FLUID: Improves adding widgets to Fl_Flex.

This commit is contained in:
Matthias Melcher 2023-11-01 20:17:00 +01:00
parent aaaf0a0537
commit 904d25dafe
6 changed files with 94 additions and 17 deletions

View File

@ -478,6 +478,43 @@ int Fl_Flex_Type::parent_is_flex(Fl_Type *t) {
&& t->parent->is_a(ID_Flex));
}
/**
Insert a widget in the child list so that it moves as close as possible the position.
\param[in] child any widget in the tree but this, may already be a child of
this and will be relocated if so
\param[in] x, y pixel coordinates relative to the top left of the window
*/
void Fl_Flex_Type::insert_child_at(Fl_Widget *child, int x, int y) {
Fl_Flex *flex = (Fl_Flex*)o;
// find the insertion point closest to x, y
int d = flex->w() + flex->h(), di = -1;
if (flex->horizontal()) {
int i, dx;
for (i=0; i<flex->children(); i++) {
dx = x - flex->child(i)->x();
if (dx < 0) dx = -dx;
if (dx < d) { d = dx; di = i; }
}
dx = x - (flex->x()+flex->w());
if (dx < 0) dx = -dx;
if (dx < d) { d = dx; di = i; }
} else {
int i, dy;
for (i=0; i<flex->children(); i++) {
dy = y - flex->child(i)->y();
if (dy < 0) dy = -dy;
if (dy < d) { d = dy; di = i; }
}
dy = y - (flex->y()+flex->h());
if (dy < 0) dy = -dy;
if (dy < d) { d = dy; di = i; }
}
if (di > -1) {
flex->insert(*child, di);
}
}
int Fl_Flex_Type::size(Fl_Type *t, char fixed_only) {
if (!t->is_widget()) return 0;
if (!t->parent) return 0;

View File

@ -125,6 +125,7 @@ public:
void remove_child(Fl_Type*) FL_OVERRIDE;
void layout_widget() FL_OVERRIDE;
void change_subtype_to(int n);
void insert_child_at(Fl_Widget *child, int x, int y);
static int parent_is_flex(Fl_Type*);
static int size(Fl_Type*, char fixed_only=0);
static int is_fixed(Fl_Type*);

View File

@ -826,7 +826,18 @@ extern void fix_group_size(Fl_Type *t);
extern Fl_Menu_Item Main_Menu[];
extern Fl_Menu_Item New_Menu[];
// move the selected children according to current dx,dy,drag state:
/**
Move the selected children according to current dx, dy, drag state.
This is somewhat of a do-all function that received many additions when new
widget types were added. In the default case, moving a group will simply move
all descendants with it. When resizing, children are resized to fit within
the group.
This is not ideal for widgets that are moved or resized within a group that
manages the layout of its children. We must create a more universal way to
modify move events per widget type.
*/
void Fl_Window_Type::moveallchildren()
{
undo_checkpoint();
@ -837,26 +848,39 @@ void Fl_Window_Type::moveallchildren()
int x,y,r,t,ow=myo->o->w(),oh=myo->o->h();
newposition(myo,x,y,r,t);
if (myo->is_a(ID_Flex) || myo->is_a(ID_Grid)) {
// Flex and Grid need to be able to layout their children.
allow_layout++;
myo->o->resize(x,y,r-x,t-y);
allow_layout--;
} else {
// Other groups are resized without affecting their children, however
// they move their children if the entire widget is moved.
myo->o->resize(x,y,r-x,t-y);
}
if (Fl_Flex_Type::parent_is_flex(myo)) {
// If the border of a Flex child is move, give that child a fixed size
// so that the user request is reflected.
Fl_Flex_Type* ft = (Fl_Flex_Type*)myo->parent;
Fl_Flex* f = (Fl_Flex*)ft->o;
if (f->horizontal()) {
if (myo->o->w()!=ow) {
f->fixed(myo->o, myo->o->w());
f->layout();
}
if (drag & FD_DRAG) {
ft->insert_child_at(myo->o, Fl::event_x(), Fl::event_y());
} else {
if (myo->o->h()!=oh) {
f->fixed(myo->o, myo->o->h());
f->layout();
if (f->horizontal()) {
if (myo->o->w()!=ow) {
f->fixed(myo->o, myo->o->w());
f->layout();
}
} else {
if (myo->o->h()!=oh) {
f->fixed(myo->o, myo->o->h());
f->layout();
}
}
}
// relayout the Flex parent
allow_layout++;
f->layout();
allow_layout--;
} else if (myo->parent && myo->parent->is_a(ID_Grid)) {
Fl_Grid_Type* gt = (Fl_Grid_Type*)myo->parent;
if (drag & FD_DRAG) {

View File

@ -142,7 +142,8 @@ script_panel->hide(); // otherwise hide..} open
}
code {// Enable line numbers
script_input->linenumber_width(60);
script_input->linenumber_size(script_input->Fl_Text_Display::textsize());} {}
script_input->linenumber_size(script_input->Fl_Text_Display::textsize());} {selected
}
}
Function {make_settings_window()} {open
@ -282,7 +283,7 @@ Examples:
}
Fl_Check_Button ghosted_outline_button {
label {Show Low Contrast Groups Ghosted}
callback toggle_ghosted_outline_cb selected
callback toggle_ghosted_outline_cb
tooltip {groups with no box type or flat boxtypes without contrast will be rendered with a dim outline in the editing window only} xywh {120 340 200 20} down_box DOWN_BOX labelsize 11
code0 {o->value(show_ghosted_outline);}
}

View File

@ -6,17 +6,29 @@
\tableofcontents
\section schemes Schemes
Write me... .
\section options Options
Write me... .
## Select scheme ##
## Show tooltips ##
## Show completions dialogs ##
## Open previous file on startup ##
## Remember window positions ##
## Show comments in browser ##
\section external_editor External Editor
Write me... .
When you configure the External Editor text field with a shell command and
select the "Use for Code Nodes" option, FLUID will launch an external editor
for editing the C++ code within a Code Node. After making changes and saving
the code in the external editor, it will automatically be transferred back
into the Code Node. The shell command is constructed by combining the text
field's content with the path and name of a temporary file containing the
code snippet. The file name ends in `.cxx`.
\section overlays Overlay

View File

@ -1195,6 +1195,8 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) {
wt->ideal_size(w, h);
if ((t->parent && t->parent->is_a(ID_Flex))) {
if (Fl_Window_Type::popupx != 0x7FFFFFFF)
((Fl_Flex_Type*)t->parent)->insert_child_at(((Fl_Widget_Type*)t)->o, Fl_Window_Type::popupx, Fl_Window_Type::popupy);
t->parent->layout_widget();
} else if ( wt->is_a(ID_Group)
&& wt->parent