📄 fl_browser_.cxx
字号:
dont_repeat = 1;
// see if changes to full_height caused by calls to slow_height
// caused scrollbar state to change, in which case we have to redraw:
full_height_ = full_height();
full_width_ = full_width();
if ((has_scrollbar_ & VERTICAL) &&
((has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) {
if (!scrollbar.visible()) goto J1;
} else {
if (scrollbar.visible()) goto J1;
}
if ((has_scrollbar_ & HORIZONTAL) &&
((has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) {
if (!hscrollbar.visible()) goto J1;
} else {
if (hscrollbar.visible()) goto J1;
}
}
// update the scrollbars and redraw them:
int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10;
if (scrollbar.visible()) {
scrollbar.damage_resize(
scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W,
Y, scrollbar_width_, H);
scrollbar.value(position_, H, 0, full_height_);
scrollbar.linesize(dy);
if (drawsquare) draw_child(scrollbar);
else update_child(scrollbar);
}
if (hscrollbar.visible()) {
hscrollbar.damage_resize(
X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H,
W, scrollbar_width_);
hscrollbar.value(hposition_, W, 0, full_width_);
hscrollbar.linesize(dy);
if (drawsquare) draw_child(hscrollbar);
else update_child(hscrollbar);
}
// draw that little square between the scrollbars:
if (drawsquare && scrollbar.visible() && hscrollbar.visible()) {
fl_color(parent()->color());
fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar_width_,scrollbar_width_);
}
real_hposition_ = hposition_;
}
// Quick way to delete and reset everything:
void Fl_Browser_::new_list() {
top_ = 0;
position_ = real_position_ = 0;
hposition_ = real_hposition_ = 0;
selection_ = 0;
offset_ = 0;
max_width = 0;
max_width_item = 0;
redraw_lines();
}
// Tell it that this item is going away, and that this must remove
// all pointers to it:
void Fl_Browser_::deleting(void* l) {
if (displayed(l)) {
redraw_lines();
if (l == top_) {
real_position_ -= offset_;
offset_ = 0;
top_ = item_next(l);
if (!top_) top_ = item_prev(l);
}
} else {
// we don't know where this item is, recalculate top...
real_position_ = 0;
top_ = 0;
}
if (l == selection_) selection_ = 0;
if (l == max_width_item) {max_width_item = 0; max_width = 0;}
}
void Fl_Browser_::replacing(void* a, void* b) {
redraw_line(a);
if (a == selection_) selection_ = b;
if (a == top_) top_ = b;
if (a == max_width_item) {max_width_item = 0; max_width = 0;}
}
void Fl_Browser_::inserting(void* a, void* b) {
if (displayed(a)) redraw_lines();
if (a == top_) top_ = b;
}
void* Fl_Browser_::find_item(int my) {
update_top();
int X, Y, W, H; bbox(X, Y, W, H);
void* l;
int yy = Y-offset_;
for (l = top_; l; l = item_next(l)) {
int hh = item_height(l); if (hh <= 0) continue;
yy += hh;
if (my <= yy || yy>=(Y+H)) return l;
}
return 0;
}
int Fl_Browser_::select(void* l, int i, int docallbacks) {
if (type() == FL_MULTI_BROWSER) {
if (selection_ != l) {
if (selection_) redraw_line(selection_);
selection_ = l;
redraw_line(l);
}
if ((!i)==(!item_selected(l))) return 0;
item_select(l, i);
redraw_line(l);
} else {
if (i && selection_ == l) return 0;
if (!i && selection_ != l) return 0;
if (selection_) {
item_select(selection_, 0);
redraw_line(selection_);
selection_ = 0;
}
if (i) {
item_select(l, 1);
selection_ = l;
redraw_line(l);
display(l);
}
}
if (docallbacks) do_callback();
return 1;
}
int Fl_Browser_::deselect(int docallbacks) {
if (type() == FL_MULTI_BROWSER) {
int change = 0;
for (void* p = item_first(); p; p = item_next(p))
change |= select(p, 0, docallbacks);
return change;
} else {
if (!selection_) return 0;
item_select(selection_, 0);
redraw_line(selection_);
selection_ = 0;
return 1;
}
}
int Fl_Browser_::select_only(void* l, int docallbacks) {
if (!l) return deselect(docallbacks);
int change = 0;
if (type() == FL_MULTI_BROWSER) {
for (void* p = item_first(); p; p = item_next(p))
if (p != l) change |= select(p, 0, docallbacks);
}
change |= select(l, 1, docallbacks);
display(l);
return change;
}
int Fl_Browser_::handle(int event) {
// must do shortcuts first or the scrollbar will get them...
if (event == FL_ENTER || event == FL_LEAVE) return 1;
if (event == FL_KEYBOARD && type() >= FL_HOLD_BROWSER) {
void* l1 = selection_;
void* l = l1; if (!l) l = top_; if (!l) l = item_first();
if (l) {
if (type()==FL_HOLD_BROWSER) switch (Fl::event_key()) {
case FL_Down:
while ((l = item_next(l)))
if (item_height(l)>0) {select_only(l, 1); break;}
return 1;
case FL_Up:
while ((l = item_prev(l))) if (item_height(l)>0) {
select_only(l, 1); break;}
return 1;
} else switch (Fl::event_key()) {
case FL_Enter:
select_only(l, 1);
return 1;
case ' ':
selection_ = l;
select(l, !item_selected(l), 1);
return 1;
case FL_Down:
while ((l = item_next(l))) {
if (Fl::event_state(FL_SHIFT|FL_CTRL))
select(l, l1 ? item_selected(l1) : 1, 1);
if (item_height(l)>0) goto J1;
}
return 1;
case FL_Up:
while ((l = item_prev(l))) {
if (Fl::event_state(FL_SHIFT|FL_CTRL))
select(l, l1 ? item_selected(l1) : 1, 1);
if (item_height(l)>0) goto J1;
}
return 1;
J1:
if (selection_) redraw_line(selection_);
selection_ = l; redraw_line(l);
display(l);
return 1;
}
}
}
if (Fl_Group::handle(event)) return 1;
int X, Y, W, H; bbox(X, Y, W, H);
int my;
static char change;
static char whichway;
static int py;
switch (event) {
case FL_PUSH:
if (!Fl::event_inside(X, Y, W, H)) return 0;
if (Fl::visible_focus()) Fl::focus(this);
my = py = Fl::event_y();
change = 0;
if (type() == FL_NORMAL_BROWSER || !top_)
;
else if (type() != FL_MULTI_BROWSER) {
change = select_only(find_item(my), when() & FL_WHEN_CHANGED);
} else {
void* l = find_item(my);
whichway = 1;
if (Fl::event_state(FL_CTRL)) { // toggle selection:
TOGGLE:
if (l) {
whichway = !item_selected(l);
change = select(l, whichway, when() & FL_WHEN_CHANGED);
}
} else if (Fl::event_state(FL_SHIFT)) { // extend selection:
if (l == selection_) goto TOGGLE;
// state of previous selection determines new value:
whichway = l ? !item_selected(l) : 1;
// see which of the new item or previous selection is earlier,
// by searching from the previous forward for this one:
int down;
if (!l) down = 1;
else {for (void* m = selection_; ; m = item_next(m)) {
if (m == l) {down = 1; break;}
if (!m) {down = 0; break;}
}}
if (down) {
for (void* m = selection_; m != l; m = item_next(m))
select(m, whichway, when() & FL_WHEN_CHANGED);
} else {
void* e = selection_;
for (void* m = item_next(l); m; m = item_next(m)) {
select(m, whichway, when() & FL_WHEN_CHANGED);
if (m == e) break;
}
}
// do the clicked item last so the select box is around it:
if (l) select(l, whichway, when() & FL_WHEN_CHANGED);
change = 1;
} else { // select only this item
change = select_only(l, when() & FL_WHEN_CHANGED);
}
}
return 1;
case FL_DRAG:
// do the scrolling first:
my = Fl::event_y();
if (my < Y && my < py) {
int p = real_position_+my-Y;
if (p<0) p = 0;
position(p);
} else if (my > (Y+H) && my > py) {
int p = real_position_+my-(Y+H);
int hh = full_height()-H; if (p > hh) p = hh;
if (p<0) p = 0;
position(p);
}
if (type() == FL_NORMAL_BROWSER || !top_)
;
else if (type() == FL_MULTI_BROWSER) {
void* l = find_item(my);
void* t; void* b; // this will be the range to change
if (my > py) { // go down
t = selection_ ? item_next(selection_) : 0;
b = l ? item_next(l) : 0;
} else { // go up
t = l;
b = selection_;
}
for (; t && t != b; t = item_next(t))
change |= select(t, whichway, when() & FL_WHEN_CHANGED);
if (l) selection_ = l;
} else {
void* l1 = selection_;
void* l =
(Fl::event_x()<x() || Fl::event_x()>x()+w()) ? selection_ :
find_item(my);
select_only(l, when() & FL_WHEN_CHANGED);
change = (l != l1);
}
py = my;
return 1;
case FL_RELEASE:
if (type() == FL_SELECT_BROWSER) {
void* t = selection_; deselect(); selection_ = t;
}
if (change) {
if (when() & FL_WHEN_RELEASE) do_callback();
else if (!(when()&FL_WHEN_CHANGED)) set_changed();
} else {
if (when() & FL_WHEN_NOT_CHANGED) do_callback();
}
return 1;
case FL_FOCUS:
case FL_UNFOCUS:
if (type() >= FL_HOLD_BROWSER && Fl::visible_focus()) {
redraw();
return 1;
} else return 0;
}
return 0;
}
Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* l)
: Fl_Group(X, Y, W, H, l),
scrollbar(0, 0, 0, 0, 0), // they will be resized by draw()
hscrollbar(0, 0, 0, 0, 0)
{
box(FL_NO_BOX);
align(FL_ALIGN_BOTTOM);
position_ = real_position_ = 0;
hposition_ = real_hposition_ = 0;
offset_ = 0;
top_ = 0;
when(FL_WHEN_RELEASE_ALWAYS);
selection_ = 0;
color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
scrollbar.callback(scrollbar_callback);
//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatability?
hscrollbar.callback(hscrollbar_callback);
hscrollbar.type(FL_HORIZONTAL);
textfont_ = FL_HELVETICA;
textsize_ = (uchar)FL_NORMAL_SIZE;
textcolor_ = FL_FOREGROUND_COLOR;
has_scrollbar_ = BOTH;
max_width = 0;
max_width_item = 0;
redraw1 = redraw2 = 0;
end();
}
// Default versions of some of the virtual functions:
int Fl_Browser_::item_quick_height(void* l) const {
return item_height(l);
}
int Fl_Browser_::incr_height() const {
return item_quick_height(item_first());
}
int Fl_Browser_::full_height() const {
int t = 0;
for (void* p = item_first(); p; p = item_next(p))
t += item_quick_height(p);
return t;
}
int Fl_Browser_::full_width() const {
return max_width;
}
void Fl_Browser_::item_select(void*, int) {}
int Fl_Browser_::item_selected(void* l) const {return l==selection_;}
//
// End of "$Id: Fl_Browser_.cxx,v 1.1.1.1 2003/06/03 22:25:41 agno Exp $".
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -