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.
This commit is contained in:
parent
c1edba3137
commit
1be158a840
@ -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();
|
||||
}
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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.
|
||||
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
|
||||
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"
|
||||
*/
|
||||
\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;
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user