diff options
| author | Matthias Melcher <git@matthiasm.com> | 2021-12-08 20:52:33 +0100 |
|---|---|---|
| committer | Matthias Melcher <git@matthiasm.com> | 2021-12-08 20:52:51 +0100 |
| commit | 1be158a840922aa03682d39926dc60ecb487063b (patch) | |
| tree | 283dcc8e45f8a094db2ffe22a046f29ac83f3656 /fluid | |
| parent | c1edba3137b371ea8aba60e5a111a1fa01c7b470 (diff) | |
STR 3460.b: fixed scrollbar update in widget_browser
Also fixed a bug where a Manu item was accessed by index, which
already was out of sync.
Diffstat (limited to 'fluid')
| -rw-r--r-- | fluid/Fl_Type.cxx | 94 | ||||
| -rw-r--r-- | fluid/Fl_Window_Type.cxx | 8 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 4 | ||||
| -rw-r--r-- | fluid/fluid.h | 1 | ||||
| -rw-r--r-- | fluid/widget_browser.cxx | 94 | ||||
| -rw-r--r-- | fluid/widget_browser.h | 37 |
6 files changed, 155 insertions, 83 deletions
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx index 68094850f..cda6b7601 100644 --- a/fluid/Fl_Type.cxx +++ b/fluid/Fl_Type.cxx @@ -147,6 +147,7 @@ static void delete_children(Fl_Type *p) { for (f = p; f && f->next && f->next->level > p->level; f = f->next) {/*empty*/} for (; f != p; ) { Fl_Type *g = f->prev; + widget_browser->deleting(f); delete f; f = g; } @@ -158,6 +159,7 @@ void delete_all(int selected_only) { if (f->selected || !selected_only) { delete_children(f); Fl_Type *g = f->next; + widget_browser->deleting(f); delete f; f = g; } else f = f->next; @@ -250,13 +252,24 @@ const char* Fl_Type::title() { return type_name(); } -// add a list of widgets as a new child of p: +/** + Add this list/tree of widgets as a new child of p. + + \c this is not part of the widget browser. \c p should be in the + widget_browser, so \c Fl_Type::first and \c Fl_Type::last are valid for \c p. + + This methods updates the widget_browser. + + \param[in] p insert \c this tree as a child of \c p + */ void Fl_Type::add(Fl_Type *p) { if (p && parent == p) return; undo_checkpoint(); parent = p; + // p is not in the Widget_Browser, so we must run the linked list to find the last entry Fl_Type *end = this; while (end->next) end = end->next; + // run the list again to set the future node levels Fl_Type *q; int newlevel; if (p) { @@ -268,6 +281,7 @@ void Fl_Type::add(Fl_Type *p) { } for (Fl_Type *t = this->next; t; t = t->next) t->level += (newlevel-level); level = newlevel; + // now link this tree after p if (q) { prev = q->prev; prev->next = this; @@ -283,28 +297,52 @@ void Fl_Type::add(Fl_Type *p) { last = end; prev = end->next = 0; } + // tell this that it was added, so it can update itself if (p) p->add_child(this,0); open_ = 1; fixvisible(this); set_modflag(1); + // run the p tree a last time to make sure the widget_browser updates correctly + Fl_Type *a = p; + for (Fl_Type *t = this; t && a != end; a = t, t = t->next) + widget_browser->inserting(a, t); widget_browser->redraw(); } -// add to a parent before another widget: +/** + Add this list/tree of widgets as a new sibling before p. + + \c this is not part of the widget browser. \c p should be in the + widget_browser, so \c Fl_Type::first and \c Fl_Type::last are valid for \c p. + + This methods updates the widget_browser. + + \param[in] p insert \c this tree as a child of \c p + */ void Fl_Type::insert(Fl_Type *g) { + // p is not in the Widget_Browser, so we must run the linked list to find the last entry Fl_Type *end = this; while (end->next) end = end->next; + // this wil get the sam parent as g parent = g->parent; + // run the list again to set the future node levels int newlevel = g->level; visible = g->visible; for (Fl_Type *t = this->next; t; t = t->next) t->level += newlevel-level; level = newlevel; + // insert this in the list before g prev = g->prev; if (prev) prev->next = this; else first = this; end->next = g; g->prev = end; fixvisible(this); + // tell parent that it has a new child, so it can update itself if (parent) parent->add_child(this, g); + // run this tree a last time to make sure the widget_browser updates correctly + Fl_Type *a = prev; + for (Fl_Type *t = this; t && a != end; a = t, t = t->next) + if (a) + widget_browser->inserting(a, t); widget_browser->redraw(); } @@ -326,27 +364,39 @@ int Fl_Type::msgnum() { /** Remove this node and all its children from the parent node. + + This does not delete anything. The resulting list//tree will no longer be in + the widget_browser, so \c Fl_Type::first and \c Fl_Type::last do not apply + to it. + \return the node that follows this node after the operation; can be NULL */ Fl_Type *Fl_Type::remove() { - // -- find the last child of this node + // find the last child of this node Fl_Type *end = this; for (;;) { - if (!end->next || end->next->level <= level) break; + if (!end->next || end->next->level <= level) + break; end = end->next; } - // -- unlink this node from the previous one - if (prev) prev->next = end->next; - else first = end->next; - // -- unlink the last child from their next node - if (end->next) end->next->prev = prev; - else last = prev; + // unlink this node from the previous one + if (prev) + prev->next = end->next; + else + first = end->next; + // unlink the last child from their next node + if (end->next) + end->next->prev = prev; + else + last = prev; Fl_Type *r = end->next; prev = end->next = 0; - // -- allow the parent to update changes in the UI + // allow the parent to update changes in the UI if (parent) parent->remove_child(this); parent = 0; - widget_browser->redraw_lines(); + // tell the widget_browser that we removed some nodes + for (Fl_Type *t = this; t; t = t->next) + widget_browser->deleting(t); widget_browser->redraw(); selection_changed(0); return r; @@ -388,14 +438,23 @@ void Fl_Type::open() { printf("Open of '%s' is not yet implemented\n",type_name()); } -// move f (and its children) into list before g: // returns pointer to whatever is after f & children + +/** + Move this node (and its children) into list before g. + \param[in] p move \c this tree before \c p + */ void Fl_Type::move_before(Fl_Type* g) { if (level != g->level) printf("move_before levels don't match! %d %d\n", level, g->level); + // Find the last child in the list Fl_Type* n; - for (n = next; n && n->level > level; n = n->next) {/*empty*/} + for (n = next; n && n->level > level; n = n->next) ; if (n == g) return; + // Tell the widget browser that we delete them + for (n = next; n && n->level > level; n = n->next) + widget_browser->deleting(n); + // now link this tree before g Fl_Type *l = n ? n->prev : Fl_Type::last; prev->next = n; if (n) n->prev = prev; else Fl_Type::last = prev; @@ -403,8 +462,13 @@ void Fl_Type::move_before(Fl_Type* g) { l->next = g; if (prev) prev->next = this; else Fl_Type::first = this; g->prev = l; + // tell parent that it has a new child, so it can update itself if (parent && is_widget()) parent->move_child(this,g); - widget_browser->inserting(g, this); + // run this tree a last time to make sure the widget_browser updates correctly + Fl_Type *a = prev; + for (Fl_Type *t = this; t && a != n; a = t, t = t->next) + if (a) + widget_browser->inserting(a, t); widget_browser->display(this); widget_browser->redraw(); } diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index c42d62af7..ea2e4da54 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -1089,7 +1089,7 @@ extern Fl_Menu_Item Main_Menu[]; // Calculate new bounding box of selected widgets: void Fl_Window_Type::fix_overlay() { - Main_Menu[40].label("Hide O&verlays"); + overlay_item->label("Hide O&verlays"); overlays_invisible = 0; recalc = 1; ((Overlay_Window *)(this->o))->redraw_overlay(); @@ -1120,8 +1120,10 @@ void redraw_overlays() { void toggle_overlays(Fl_Widget *,void *) { overlays_invisible = !overlays_invisible; - if (overlays_invisible) Main_Menu[40].label("Show O&verlays"); - else Main_Menu[40].label("Hide O&verlays"); + if (overlays_invisible) + overlay_item->label("Show O&verlays"); + else + overlay_item->label("Hide O&verlays"); for (Fl_Type *o=Fl_Type::first; o; o=o->next) if (o->is_window()) { diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index 0779e600d..7fe776fa9 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -127,6 +127,9 @@ Fl_Menu_Item *widgetbin_item = NULL; /// Menuitem to show or hide the source view, label will change if view is visible. Fl_Menu_Item *sourceview_item = NULL; +/// Menuitem to show or hide the editing overlay, label will change if overlay visibility changes. +Fl_Menu_Item *overlay_item = NULL; + //////////////////////////////////////////////////////////////// /// Filename of the current .fl design file @@ -1426,6 +1429,7 @@ void make_main_window() { history_item = (Fl_Menu_Item*)main_menubar->find_item(open_history_cb); widgetbin_item = (Fl_Menu_Item*)main_menubar->find_item(toggle_widgetbin_cb); sourceview_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_sourceview_cb); + overlay_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_overlays); main_menubar->global(); fill_in_New_Menu(); main_window->end(); diff --git a/fluid/fluid.h b/fluid/fluid.h index e2370359f..20045ab06 100644 --- a/fluid/fluid.h +++ b/fluid/fluid.h @@ -63,6 +63,7 @@ extern Fl_Menu_Item *save_item; extern Fl_Menu_Item *history_item; extern Fl_Menu_Item *widgetbin_item; extern Fl_Menu_Item *sourceview_item; +extern Fl_Menu_Item *overlay_item; extern int modflag; diff --git a/fluid/widget_browser.cxx b/fluid/widget_browser.cxx index 6d4d1028a..7996d905e 100644 --- a/fluid/widget_browser.cxx +++ b/fluid/widget_browser.cxx @@ -47,26 +47,26 @@ Widget_Browser *widget_browser = NULL; Shortcut to have the widget browser graphics refreshed soon. */ void redraw_browser() { - widget_browser->redraw(); + widget_browser->redraw(); } /** Shortcut to create the widget browser. */ Fl_Widget *make_widget_browser(int x,int y,int w,int h) { - return (widget_browser = new Widget_Browser(x,y,w,h)); + return (widget_browser = new Widget_Browser(x,y,w,h)); } /** Make sure thet the caller is visible in the widget browser. \param[in] caller scroll the browser in y so that caller - is visible (may be NULL) + is visible (may be NULL) */ void redraw_widget_browser(Fl_Type *caller) { - if (caller) - widget_browser->display(caller); - widget_browser->redraw(); + if (caller) + widget_browser->display(caller); + widget_browser->redraw(); } /** @@ -75,7 +75,7 @@ void redraw_widget_browser(Fl_Type *caller) \oaram[in] v the new selection state (1=select, 0=de-select) */ void select(Fl_Type *o, int v) { - widget_browser->select(o,v,1); + widget_browser->select(o,v,1); } /** @@ -83,14 +83,14 @@ void select(Fl_Type *o, int v) { \param[in] o select this node */ void select_only(Fl_Type *o) { - widget_browser->select_only(o,1); + widget_browser->select_only(o,1); } /** Deselect all nodes in the widget browser. */ void deselect() { - widget_browser->deselect(); + widget_browser->deselect(); } /** @@ -119,20 +119,20 @@ void reveal_in_browser(Fl_Type *t) { // ---- local functions /** - Copy the given string str to buffer p with no more than maxl characters. + Copy the given string str to buffer p with no more than maxl characters. - Add "..." if string was truncated. + Add "..." if string was truncated. - Quote characters are NOT counted. + Quote characters are NOT counted. - \param[out] p return the resulting string in this buffer, terminated with + \param[out] p return the resulting string in this buffer, terminated with a NUL byte - \param[in] str copy this string; utf8 aware - \param[in] maxl maximum number of letter to copy until we print + \param[in] str copy this string; utf8 aware + \param[in] maxl maximum number of letter to copy until we print the elipsis (...) - \param[in] auote if set, the resulting string is embedded in double quotes - \returns pointer to end of string (before terminating null byte). - \note the buffer p must be large enough to hold (4 * (maxl+1) + 1) bytes + \param[in] auote if set, the resulting string is embedded in double quotes + \returns pointer to end of string (before terminating null byte). + \note the buffer p must be large enough to hold (4 * (maxl+1) + 1) bytes or (4 * (maxl+1) + 3) bytes if quoted, e.g. "123..." because each UTF-8 character can consist of 4 bytes, "..." adds 3 bytes, quotes '""' add two bytes, and the terminating null byte adds another byte. @@ -177,7 +177,7 @@ static char *copy_trunc(char *p, const char *str, int maxl, int quote) */ Widget_Browser::Widget_Browser(int X,int Y,int W,int H,const char*l) : Fl_Browser_(X,Y,W,H,l), - pushedtitle(NULL) +pushedtitle(NULL) { type(FL_MULTI_BROWSER); Fl_Widget::callback(callback_stub); @@ -254,26 +254,26 @@ int Widget_Browser::incr_height() const { } /** - Draw an item in the widget browser. + Draw an item in the widget browser. - A browser line starts with a variable size space. This space directly - relates to the level of the type entry. + A browser line starts with a variable size space. This space directly + relates to the level of the type entry. - If this type has the ability to store children, a triangle follows, - pointing right (closed) or pointing down (open, children shown). + If this type has the ability to store children, a triangle follows, + pointing right (closed) or pointing down (open, children shown). - Next follows an icon that is specific to the type. This makes it easy to - spot certain types. + Next follows an icon that is specific to the type. This makes it easy to + spot certain types. - Now follows some text. For classes and widgets, this is the type itself, - followed by the name of the object. Other objects show their content as - text, possibly abbreviated with an ellipsis. + Now follows some text. For classes and widgets, this is the type itself, + followed by the name of the object. Other objects show their content as + text, possibly abbreviated with an ellipsis. - \param v v is a pointer to the actual widget type and can be cast safely - to Fl_Type - \param X,Y these give the position in window coordinates of the top left - corner of this line -*/ + \param v v is a pointer to the actual widget type and can be cast safely + to Fl_Type + \param X,Y these give the position in window coordinates of the top left + corner of this line + */ void Widget_Browser::item_draw(void *v, int X, int Y, int, int) const { // cast to a more general type Fl_Type *l = (Fl_Type *)v; @@ -427,19 +427,19 @@ void Widget_Browser::callback() { } /** - Override the event handling for this browser. - - The vertical mouse position corresponds to an entry in the type tree. - The horizontal position has the following hot zones: - - 0-3 is the widget frame and ignored - - the next hot zone starts 12*indent pixels further to the right - - the next 13 pixels refer to the arrow that indicates children for the item - - 18 pixels follow for the icon - - the remaining part is filled with text - - \param[in] e the incoming event type - \return 0 if the event is not supported, and 1 if the event was "used up" -*/ + Override the event handling for this browser. + + The vertical mouse position corresponds to an entry in the type tree. + The horizontal position has the following hot zones: + - 0-3 is the widget frame and ignored + - the next hot zone starts 12*indent pixels further to the right + - the next 13 pixels refer to the arrow that indicates children for the item + - 18 pixels follow for the icon + - the remaining part is filled with text + + \param[in] e the incoming event type + \return 0 if the event is not supported, and 1 if the event was "used up" + */ int Widget_Browser::handle(int e) { static Fl_Type *title; Fl_Type *l; diff --git a/fluid/widget_browser.h b/fluid/widget_browser.h index c00d45052..dfcd4db35 100644 --- a/fluid/widget_browser.h +++ b/fluid/widget_browser.h @@ -34,29 +34,30 @@ extern void reveal_in_browser(Fl_Type *t); class Widget_Browser : public Fl_Browser_ { - friend class Fl_Type; + friend class Fl_Type; - static void callback_stub(Fl_Widget *o, void *) { - ((Widget_Browser *)o)->callback(); - } + static void callback_stub(Fl_Widget *o, void *) { + ((Widget_Browser *)o)->callback(); + } - Fl_Type* pushedtitle; + Fl_Type* pushedtitle; - // required routines for Fl_Browser_ subclass: - void *item_first() const ; - void *item_next(void *) const ; - void *item_prev(void *) const ; - int item_selected(void *) const ; - void item_select(void *,int); - int item_width(void *) const ; - int item_height(void *) const ; - void item_draw(void *,int,int,int,int) const ; - int incr_height() const ; + // required routines for Fl_Browser_ subclass: + void *item_first() const ; + void *item_next(void *) const ; + void *item_prev(void *) const ; + int item_selected(void *) const ; + void item_select(void *,int); + int item_width(void *) const ; + int item_height(void *) const ; + void item_draw(void *,int,int,int,int) const ; + int incr_height() const ; public: - int handle(int); - void callback(); - Widget_Browser(int,int,int,int,const char * =0); + Widget_Browser(int,int,int,int,const char * =NULL); + int handle(int); + void callback(); + void deleting(Fl_Type *inType) { Fl_Browser_::deleting((void*)inType); } }; #endif // _FLUID_WIDGET_BROWSER_H |
