mirror of https://github.com/fltk/fltk
FLUID: Fixes grouping and ungrouping, #1056
- grouping a bunch of widgets will now create the new group in the expected place - also add grouping and ungrouping of menu items - ungrouping now also works with only a few items selected instead all items, moving the selection before the group
This commit is contained in:
parent
1da9438a1c
commit
c8b8eb4b84
|
@ -89,59 +89,95 @@ void fix_group_size(Fl_Type *tt) {
|
||||||
t->o->resize(X,Y,R-X,B-Y);
|
t->o->resize(X,Y,R-X,B-Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void group_selected_menuitems();
|
||||||
|
|
||||||
void group_cb(Fl_Widget *, void *) {
|
void group_cb(Fl_Widget *, void *) {
|
||||||
// Find the current widget:
|
if (!Fl_Type::current) {
|
||||||
Fl_Type *qq = Fl_Type::current;
|
fl_message("No widgets selected.");
|
||||||
while (qq && !qq->is_true_widget()) qq = qq->parent;
|
return;
|
||||||
if (!qq || qq->level < 1 || (qq->level == 1 && qq->is_a(ID_Widget_Class))) {
|
}
|
||||||
fl_message("Please select widgets to group");
|
if (!Fl_Type::current->is_widget()) {
|
||||||
|
fl_message("Only widgets and menu items can be grouped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Fl_Type::current->is_a(ID::ID_Menu_Item)) {
|
||||||
|
group_selected_menuitems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// The group will be created in the parent group of the current widget
|
||||||
|
Fl_Type *qq = Fl_Type::current->parent;
|
||||||
|
Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
|
||||||
|
while (qq && !qq->is_a(ID::ID_Group)) {
|
||||||
|
qq = qq->parent;
|
||||||
|
}
|
||||||
|
if (!qq) {
|
||||||
|
fl_message("Can't create a new group here.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
undo_checkpoint();
|
undo_checkpoint();
|
||||||
undo_suspend();
|
undo_suspend();
|
||||||
Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
|
Fl_Type::current = qq;
|
||||||
force_parent = 1;
|
|
||||||
Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make(kAddAsLastChild));
|
Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make(kAddAsLastChild));
|
||||||
n->move_before(q);
|
n->move_before(q);
|
||||||
n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h());
|
n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h());
|
||||||
for (Fl_Type *t = Fl_Type::first; t;) {
|
for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
|
||||||
if (t->level != n->level || t == n || !t->selected) {
|
if (t->level != n->level || t == n || !t->selected) {
|
||||||
t = t->next; continue;}
|
t = t->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Fl_Type *nxt = t->remove();
|
Fl_Type *nxt = t->remove();
|
||||||
t->add(n, kAddAsLastChild);
|
t->add(n, kAddAsLastChild);
|
||||||
t = nxt;
|
t = nxt;
|
||||||
}
|
}
|
||||||
fix_group_size(n);
|
fix_group_size(n);
|
||||||
|
Fl_Type::current = q;
|
||||||
n->layout_widget();
|
n->layout_widget();
|
||||||
widget_browser->rebuild();
|
widget_browser->rebuild();
|
||||||
undo_resume();
|
undo_resume();
|
||||||
set_modflag(1);
|
set_modflag(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void ungroup_selected_menuitems();
|
||||||
|
|
||||||
void ungroup_cb(Fl_Widget *, void *) {
|
void ungroup_cb(Fl_Widget *, void *) {
|
||||||
// Find the group:
|
if (!Fl_Type::current) {
|
||||||
Fl_Type *q = Fl_Type::current;
|
fl_message("No widgets selected.");
|
||||||
while (q && !q->is_true_widget()) q = q->parent;
|
|
||||||
if (q) q = q->parent;
|
|
||||||
if (!q || q->level < 1 || (q->level == 1 && q->is_a(ID_Widget_Class))) {
|
|
||||||
fl_message("Please select widgets in a group");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Fl_Type* n;
|
if (!Fl_Type::current->is_widget()) {
|
||||||
for (n = q->next; n && n->level > q->level; n = n->next) {
|
fl_message("Only widgets and menu items can be ungrouped.");
|
||||||
if (n->level == q->level+1 && !n->selected) {
|
return;
|
||||||
fl_message("Please select all widgets in group");
|
}
|
||||||
return;
|
if (Fl_Type::current->is_a(ID::ID_Menu_Item)) {
|
||||||
}
|
ungroup_selected_menuitems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
|
||||||
|
int q_level = q->level;
|
||||||
|
Fl_Type *qq = Fl_Type::current->parent;
|
||||||
|
while (qq && !qq->is_true_widget()) qq = qq->parent;
|
||||||
|
if (!qq || !qq->is_a(ID_Group)) {
|
||||||
|
fl_message("Only menu widgets inside a group can be ungrouped.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
undo_checkpoint();
|
undo_checkpoint();
|
||||||
undo_suspend();
|
undo_suspend();
|
||||||
for (n = q->next; n && n->level > q->level;) {
|
Fl_Type::current = qq;
|
||||||
Fl_Type *nxt = n->remove();
|
for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
|
||||||
n->insert(q);
|
if (t->level != q_level || !t->selected) {
|
||||||
n = nxt;
|
t = t->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Fl_Type *nxt = t->remove();
|
||||||
|
t->insert(qq);
|
||||||
|
t = nxt;
|
||||||
}
|
}
|
||||||
delete q;
|
if (!qq->next || (qq->next->level <= qq->level)) {
|
||||||
|
qq->remove();
|
||||||
|
delete qq; // qq has no children that need to be delete
|
||||||
|
}
|
||||||
|
Fl_Type::current = q;
|
||||||
widget_browser->rebuild();
|
widget_browser->rebuild();
|
||||||
undo_resume();
|
undo_resume();
|
||||||
set_modflag(1);
|
set_modflag(1);
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "Fluid_Image.h"
|
#include "Fluid_Image.h"
|
||||||
#include "custom_widgets.h"
|
#include "custom_widgets.h"
|
||||||
#include "mergeback.h"
|
#include "mergeback.h"
|
||||||
|
#include "undo.h"
|
||||||
|
#include "widget_browser.h"
|
||||||
|
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/fl_message.H>
|
#include <FL/fl_message.H>
|
||||||
|
@ -175,6 +177,65 @@ Fl_Type *Fl_Menu_Item_Type::make(Strategy strategy) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void group_selected_menuitems() {
|
||||||
|
// The group will be created in the parent group of the current menuitem
|
||||||
|
Fl_Type *qq = Fl_Type::current->parent;
|
||||||
|
Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
|
||||||
|
if (!qq || !(qq->is_a(ID_Menu_Manager_) || qq->is_a(ID_Submenu))) {
|
||||||
|
fl_message("Can't create a new group here.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
undo_checkpoint();
|
||||||
|
undo_suspend();
|
||||||
|
submenuflag = 1;
|
||||||
|
Fl_Widget_Type *n = (Fl_Widget_Type*)(q->make(kAddAfterCurrent));
|
||||||
|
submenuflag = 0;
|
||||||
|
for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
|
||||||
|
if (t->level != n->level || t == n || !t->selected) {
|
||||||
|
t = t->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Fl_Type *nxt = t->remove();
|
||||||
|
t->add(n, kAddAsLastChild);
|
||||||
|
t = nxt;
|
||||||
|
}
|
||||||
|
widget_browser->rebuild();
|
||||||
|
undo_resume();
|
||||||
|
set_modflag(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ungroup_selected_menuitems() {
|
||||||
|
// Find the submenu
|
||||||
|
Fl_Type *qq = Fl_Type::current->parent;
|
||||||
|
Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
|
||||||
|
int q_level = q->level;
|
||||||
|
if (!qq || !qq->is_a(ID_Submenu)) {
|
||||||
|
fl_message("Only menu items inside a submenu can be ungrouped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
undo_checkpoint();
|
||||||
|
undo_suspend();
|
||||||
|
Fl_Type::current = qq;
|
||||||
|
for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
|
||||||
|
if (t->level != q_level || !t->selected) {
|
||||||
|
t = t->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Fl_Type *nxt = t->remove();
|
||||||
|
t->insert(qq);
|
||||||
|
t = nxt;
|
||||||
|
}
|
||||||
|
if (!qq->next || (qq->next->level <= qq->level)) {
|
||||||
|
qq->remove();
|
||||||
|
delete qq; // qq has no children that need to be delete
|
||||||
|
}
|
||||||
|
Fl_Type::current = q;
|
||||||
|
widget_browser->rebuild();
|
||||||
|
undo_resume();
|
||||||
|
set_modflag(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create and add a new Checkbox Menu Item node.
|
Create and add a new Checkbox Menu Item node.
|
||||||
\param[in] strategy add after current or as last child
|
\param[in] strategy add after current or as last child
|
||||||
|
|
|
@ -257,10 +257,11 @@ __Edit > Later (F3)__: Move all of the selected widgets one later in order
|
||||||
among the children of their parent (if possible).
|
among the children of their parent (if possible).
|
||||||
|
|
||||||
__Edit > Group (F7)__: Create a new Fl_Group and make all the currently
|
__Edit > Group (F7)__: Create a new Fl_Group and make all the currently
|
||||||
selected widgets children of it.
|
selected widgets children of that group.
|
||||||
|
|
||||||
__Edit > Ungroup (F8)__: Delete the parent group if all the children of a
|
__Edit > Ungroup (F8)__: Move the selected children of a group out of the
|
||||||
group are selected.
|
group and up one level in the hierarchy. If all children of a group are
|
||||||
|
selected and moved, the remaining empty group is deleted.
|
||||||
|
|
||||||
__Edit > Show or Hide Overlays (Ctrl+Shift+O)__: Toggle the display of the
|
__Edit > Show or Hide Overlays (Ctrl+Shift+O)__: Toggle the display of the
|
||||||
red overlays off, without changing the selection. This makes it easier to see
|
red overlays off, without changing the selection. This makes it easier to see
|
||||||
|
|
Loading…
Reference in New Issue