From 43fe6ee02720782ce9da715b57c8d0037e6ef641 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Thu, 20 Jul 2023 13:48:43 +0200 Subject: [PATCH] FLUID improves positioning and sizing new widgets Better default sizes for text based widgets and menu managers Better Menu refresh on custom text heights Smarter positioning of menu bars and groups inside tabs Fixes wrong include guard --- fluid/Fl_Button_Type.h | 6 +-- fluid/Fl_Group_Type.cxx | 14 ++++++- fluid/Fl_Group_Type.h | 5 ++- fluid/Fl_Menu_Type.h | 44 +++++----------------- fluid/Fl_Widget_Type.cxx | 11 ++---- fluid/Fl_Window_Type.cxx | 6 +-- fluid/factory.cxx | 80 +++++++++++++++++++++++++++++----------- fluid/function_panel.cxx | 2 +- fluid/function_panel.fl | 2 +- 9 files changed, 94 insertions(+), 76 deletions(-) diff --git a/fluid/Fl_Button_Type.h b/fluid/Fl_Button_Type.h index ea7ed7cd3..743c1fdd5 100644 --- a/fluid/Fl_Button_Type.h +++ b/fluid/Fl_Button_Type.h @@ -14,8 +14,8 @@ // https://www.fltk.org/bugs.php // -#ifndef _FLUID_FACTORY_H -#define _FLUID_FACTORY_H +#ifndef _FL_BUTTON_TYPE_H +#define _FL_BUTTON_TYPE_H #include "Fl_Widget_Type.h" @@ -40,4 +40,4 @@ public: extern Fl_Button_Type Fl_Button_type; -#endif // _FLUID_FACTORY_H +#endif // _FL_BUTTON_TYPE_H diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx index 06d5e8013..c0e7526e3 100644 --- a/fluid/Fl_Group_Type.cxx +++ b/fluid/Fl_Group_Type.cxx @@ -5,7 +5,7 @@ // the Fl_Tabs widget, with special stuff to select tab items and // insure that only one is visible. // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2023 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -136,6 +136,18 @@ void ungroup_cb(Fl_Widget *, void *) { set_modflag(1); } +void Fl_Group_Type::ideal_size(int &w, int &h) { + if (parent && parent->is_true_widget()) { + Fl_Widget *p = ((Fl_Widget_Type*)parent)->o; + w = p->w() / 2; + h = p->h() / 2; + } else { + w = 140; + h = 140; + } + Fd_Snap_Action::better_size(w, h); +} + void Fl_Group_Type::write_code1(Fd_Code_Writer& f) { Fl_Widget_Type::write_code1(f); } diff --git a/fluid/Fl_Group_Type.h b/fluid/Fl_Group_Type.h index 9b6b83404..6f104fb80 100644 --- a/fluid/Fl_Group_Type.h +++ b/fluid/Fl_Group_Type.h @@ -1,7 +1,7 @@ // -// Widget type header file for the Fast Light Tool Kit (FLTK). +// Group type header file for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2023 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -40,6 +40,7 @@ class Fl_Group_Type : public Fl_Widget_Type { typedef Fl_Widget_Type super; public: + void ideal_size(int &w, int &h) FL_OVERRIDE; const char *type_name() FL_OVERRIDE {return "Fl_Group";} const char *alt_type_name() FL_OVERRIDE {return "fltk::Group";} Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE { diff --git a/fluid/Fl_Menu_Type.h b/fluid/Fl_Menu_Type.h index a18e4edef..3824270a6 100644 --- a/fluid/Fl_Menu_Type.h +++ b/fluid/Fl_Menu_Type.h @@ -1,5 +1,5 @@ // -// Widget type header file for the Fast Light Tool Kit (FLTK). +// Menu type header file for the Fast Light Tool Kit (FLTK). // // Type for creating all subclasses of Fl_Widget // This should have the widget pointer in it, but it is still in the @@ -23,6 +23,8 @@ #include "Fl_Button_Type.h" +#include "Fd_Snap_Action.h" + #include #include #include @@ -125,6 +127,11 @@ class Fl_Menu_Manager_Type : public Fl_Widget_Type { typedef Fl_Widget_Type super; public: + void ideal_size(int &w, int &h) FL_OVERRIDE { + h = layout->textsize_not_null() + 8; + w = layout->textsize_not_null() * 6 + 8; + Fd_Snap_Action::better_size(w, h); + } int is_parent() const FL_OVERRIDE {return 1;} int menusize; virtual void build_menu() = 0; @@ -160,16 +167,6 @@ class Fl_Input_Choice_Type : public Fl_Menu_Manager_Type return 1; } public: - void ideal_size(int &w, int &h) FL_OVERRIDE { - Fl_Input_Choice *myo = (Fl_Input_Choice *)o; - fl_font(myo->textfont(), myo->textsize()); - h = fl_height() + myo->textsize() - 6; - w = o->w() - 20 - Fl::box_dw(o->box()); - int ww = (int)fl_width('m'); - w = ((w + ww - 1) / ww) * ww + 20 + Fl::box_dw(o->box()); - if (h < 15) h = 15; - if (w < (15 + h)) w = 15 + h; - } ~Fl_Input_Choice_Type() { if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Input_Choice*)o)->menu()); } @@ -221,20 +218,13 @@ public: extern Fl_Menu_Item button_type_menu[]; /** - \brief Makae Menu Button widgets. + \brief Make Menu Button widgets. */ class Fl_Menu_Button_Type : public Fl_Menu_Base_Type { typedef Fl_Menu_Base_Type super; Fl_Menu_Item *subtypes() FL_OVERRIDE {return button_type_menu;} public: - void ideal_size(int &w, int &h) FL_OVERRIDE { - Fl_Widget_Type::ideal_size(w, h); - w += 2 * ((o->labelsize() - 3) & ~1) + o->labelsize() - 4; - h = (h / 5) * 5; - if (h < 15) h = 15; - if (w < (15 + h)) w = 15 + h; - } const char *type_name() FL_OVERRIDE {return "Fl_Menu_Button";} const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuButton";} Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE { @@ -252,17 +242,6 @@ class Fl_Choice_Type : public Fl_Menu_Base_Type { typedef Fl_Menu_Base_Type super; public: - void ideal_size(int &w, int &h) FL_OVERRIDE { - Fl_Widget_Type::ideal_size(w, h); - int w1 = o->h() - Fl::box_dh(o->box()); - if (w1 > 20) w1 = 20; - w1 = (w1 - 4) / 3; - if (w1 < 1) w1 = 1; - w += 2 * w1 + o->labelsize() - 4; - h = (h / 5) * 5; - if (h < 15) h = 15; - if (w < (15 + h)) w = 15 + h; - } const char *type_name() FL_OVERRIDE {return "Fl_Choice";} const char *alt_type_name() FL_OVERRIDE {return "fltk::Choice";} Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE { @@ -283,11 +262,6 @@ class Fl_Menu_Bar_Type : public Fl_Menu_Base_Type { typedef Fl_Menu_Base_Type super; public: - void ideal_size(int &w, int &h) FL_OVERRIDE { - w = o->window()->w(); - h = ((o->labelsize() + Fl::box_dh(o->box()) + 4) / 5) * 5; - if (h < 15) h = 15; - } const char *type_name() FL_OVERRIDE {return "Fl_Menu_Bar";} const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuBar";} Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {return new Fl_Menu_Bar(X,Y,W,H);} diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx index 674949df5..8556de03b 100644 --- a/fluid/Fl_Widget_Type.cxx +++ b/fluid/Fl_Widget_Type.cxx @@ -70,14 +70,9 @@ const char* subclassname(Fl_Type* l) { // Return the ideal widget size... void Fl_Widget_Type::ideal_size(int &w, int &h) { - h = o->labelsize(); - o->measure_label(w, h); - - w += Fl::box_dw(o->box()); - h += Fl::box_dh(o->box()); - - if (w < 15) w = 15; - if (h < 15) h = 15; + w = 120; + h = 100; + Fd_Snap_Action::better_size(w, h); } /** diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 236a736a8..f74e0eae1 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -207,7 +207,7 @@ int Overlay_Window::handle(int e) { */ Fl_Type *Fl_Window_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; - while (p && !p->is_code_block()) p = p->parent; + while (p && (!p->is_code_block() || p->is_a(ID_Widget_Class))) p = p->parent; if (!p) { fl_message("Please select a function"); return 0; @@ -307,8 +307,8 @@ void Fl_Window_Type::ideal_size(int &w, int &h) { int screen = Fl::screen_num(win->x(), win->y()); Fl::screen_work_area(sx, sy, sw, sh, screen); w = fd_min(w, sw*3/4); h = fd_min(h, sh*3/4); - Fd_Snap_Action::better_size(w, h); } + Fd_Snap_Action::better_size(w, h); } @@ -966,7 +966,7 @@ int Fl_Window_Type::handle(int event) { { Fl_Type *cc = Fl_Type::current; Fl_Type::current = Fl_Type::current_dnd; - add_new_widget_from_user(prototype, kAddAfterCurrent); + add_new_widget_from_user(prototype, kAddAsLastChild); Fl_Type::current = cc; } else { add_new_widget_from_user(prototype, kAddAsLastChild); diff --git a/fluid/factory.cxx b/fluid/factory.cxx index 7ed855cd5..2eb0bbca3 100644 --- a/fluid/factory.cxx +++ b/fluid/factory.cxx @@ -2,7 +2,7 @@ // Widget factory code for the Fast Light Tool Kit (FLTK). // // Type classes for most of the fltk widgets. Most of the work -// is done by code in Fl_Widget_Type.C. Also a factory instance +// is done by code in Fl_Widget_Type.cxx. Also a factory instance // of each of these type classes. // // This file also contains the "new" menu, which has a pointer @@ -26,6 +26,7 @@ #include "fluid.h" #include "Fl_Group_Type.h" +#include "Fl_Menu_Type.h" #include "Fd_Snap_Action.h" #include "pixmaps.h" #include "undo.h" @@ -351,7 +352,7 @@ class Fl_Counter_Type : public Fl_Valuator_Type public: void ideal_size(int &w, int &h) FL_OVERRIDE { h = layout->textsize_not_null() + 8; - w = layout->labelsize * 4 + 4 * h; // make room for the arrows + w = layout->textsize_not_null() * 4 + 4 * h; // make room for the arrows Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_Counter"; } @@ -583,8 +584,8 @@ class Fl_Value_Input_Type : public Fl_Valuator_Type } public: void ideal_size(int &w, int &h) FL_OVERRIDE { - h = layout->labelsize + 8; - w = layout->labelsize * 4 + 8; + h = layout->textsize_not_null() + 8; + w = layout->textsize_not_null() * 4 + 8; Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_Value_Input"; } @@ -622,8 +623,8 @@ class Fl_Value_Output_Type : public Fl_Valuator_Type } public: void ideal_size(int &w, int &h) FL_OVERRIDE { - h = layout->labelsize + 8; - w = layout->labelsize * 4 + 8; + h = layout->textsize_not_null() + 8; + w = layout->textsize_not_null() * 4 + 8; Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_Value_Output"; } @@ -677,8 +678,8 @@ class Fl_Input_Type : public Fl_Widget_Type } public: void ideal_size(int &w, int &h) FL_OVERRIDE { - h = layout->labelsize + 8; - w = layout->labelsize * 6 + 8; + h = layout->textsize_not_null() + 8; + w = layout->textsize_not_null() * 6 + 8; Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_Input"; } @@ -714,8 +715,8 @@ class Fl_File_Input_Type : public Fl_Input_Type Fl_Menu_Item *subtypes() FL_OVERRIDE { return NULL; } // Don't inherit. public: void ideal_size(int &w, int &h) FL_OVERRIDE { - h = layout->labelsize + 8 + 10; // Directoy bar is additional 10 pixels high - w = layout->labelsize * 10 + 8; + h = layout->textsize_not_null() + 8 + 10; // Directoy bar is additional 10 pixels high + w = layout->textsize_not_null() * 10 + 8; Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_File_Input"; } @@ -991,8 +992,8 @@ class Fl_Spinner_Type : public Fl_Widget_Type } public: void ideal_size(int &w, int &h) FL_OVERRIDE { - h = layout->labelsize + 8; - w = layout->labelsize * 4 + 8; + h = layout->textsize_not_null() + 8; + w = layout->textsize_not_null() * 4 + 8; Fd_Snap_Action::better_size(w, h); } const char *type_name() FL_OVERRIDE { return "Fl_Spinner"; } @@ -1149,32 +1150,67 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { undo_suspend(); Fl_Type *t = ((Fl_Type*)inPrototype)->make(strategy); if (t) { - if (t->is_widget() && !t->is_a(Fl_Type::ID_Window)) - { + if (t->is_widget() && !t->is_a(Fl_Type::ID_Window)) { Fl_Widget_Type *wt = (Fl_Widget_Type *)t; + bool changed = false; // Set font sizes... + changed |= (wt->o->labelsize() != layout->labelsize); wt->o->labelsize(layout->labelsize); - if (layout->labelfont >= 0) + if (layout->labelfont >= 0) { + changed |= (wt->o->labelfont() != layout->labelfont); wt->o->labelfont(layout->labelfont); + } - Fl_Font f = layout->textfont; - int s = layout->textsize; - Fl_Color c; + Fl_Font fc, f = layout->textfont; + int sc, s = layout->textsize; + Fl_Color cc, c; + wt->textstuff(0, fc, sc, cc); - if (layout->textfont >= 0) + if ((f >= 0) && (fc != f)) { + changed = true; wt->textstuff(1, f, s, c); - if (layout->textsize > 0) + } + if ((s > 0) && (sc != s)) { + changed = true; wt->textstuff(2, f, s, c); + } + if (changed && t->is_a(Fl_Type::ID_Menu_Item)) { + Fl_Type * tt = t->parent; + while (tt && !tt->is_a(Fl_Type::ID_Menu_Manager_)) tt = tt->parent; + ((Fl_Menu_Manager_Type*)tt)->build_menu(); + } + } + if (t->is_true_widget() && !t->is_a(Fl_Type::ID_Window)) { // Resize and/or reposition new widget... + Fl_Widget_Type *wt = (Fl_Widget_Type *)t; + + // The parent field is already set at this point, so we can use that + // inside ideal_size(). int w = 0, h = 0; wt->ideal_size(w, h); if ((t->parent && t->parent->is_a(Fl_Type::ID_Flex))) { // Do not resize or layout the widget. Flex will need the widget size. - } else if (wt->is_a(Fl_Type::ID_Menu_Bar)) { - // Move and resize the menubar across the top of the window... + } else if ( wt->is_a(Fl_Type::ID_Group) + && wt->parent + && wt->parent->is_a(Fl_Type::ID_Tabs) + //&& (Fl_Window_Type::popupx == 0x7FFFFFFF) + && (layout->top_tabs_margin > 0)) { + // If the widget is a group and the parent is tabs and the top tabs + // margin is set (and the user is not requesting a specific position) + // then prefit the group correctly to the Tabs container. + Fl_Widget *po = ((Fl_Tabs_Type*)wt->parent)->o; + wt->o->resize(po->x(), po->y() + layout->top_tabs_margin, + po->w(), po->h() - layout->top_tabs_margin); + } else if ( wt->is_a(Fl_Type::ID_Menu_Bar) + && wt->parent + && wt->parent->is_a(Fl_Type::ID_Window) + && (wt->prev == wt->parent)) { + // If this is the first child of a window, make the menu bar as wide as + // the window and drop it at 0, 0. Otherwise just use the suggested size. + w = wt->o->window()->w(); wt->o->resize(0, 0, w, h); } else { if (Fl_Window_Type::popupx != 0x7FFFFFFF) { diff --git a/fluid/function_panel.cxx b/fluid/function_panel.cxx index 2c5919a99..04c1a4785 100644 --- a/fluid/function_panel.cxx +++ b/fluid/function_panel.cxx @@ -702,7 +702,7 @@ Fl_Double_Window* make_comment_panel() { void type_make_cb(Fl_Widget*,void*d) { const char *type_name = (const char*)d; - if (Fl_Type::current && Fl_Type::current->is_group()) + if (Fl_Type::current && Fl_Type::current->is_parent()) add_new_widget_from_user(type_name, kAddAsLastChild); else add_new_widget_from_user(type_name, kAddAfterCurrent); diff --git a/fluid/function_panel.fl b/fluid/function_panel.fl index b597ac34e..8977fecdf 100644 --- a/fluid/function_panel.fl +++ b/fluid/function_panel.fl @@ -537,7 +537,7 @@ Function {make_comment_panel()} {open Function {type_make_cb(Fl_Widget*,void*d)} {return_type void } { code {const char *type_name = (const char*)d; -if (Fl_Type::current && Fl_Type::current->is_group()) +if (Fl_Type::current && Fl_Type::current->is_parent()) add_new_widget_from_user(type_name, kAddAsLastChild); else add_new_widget_from_user(type_name, kAddAfterCurrent);} {}