summaryrefslogtreecommitdiff
path: root/third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx
diff options
context:
space:
mode:
authorYuval Adam <yuv.adm@gmail.com>2014-08-08 14:42:07 +0300
committerYuval Adam <yuv.adm@gmail.com>2014-08-08 14:42:07 +0300
commita6163888f3c56123b1db313743c6147ba498732c (patch)
treeff7d15d991d1d09ba6cbc0cec80924f57445bfdd /third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx
parentc3e4c9a25c2910d2d66d52215b3406b13d5b23d5 (diff)
Add third_party libs
Diffstat (limited to 'third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx')
-rw-r--r--third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx403
1 files changed, 403 insertions, 0 deletions
diff --git a/third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx b/third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx
new file mode 100644
index 0000000..fd83a58
--- /dev/null
+++ b/third_party/windows/fltk-1.1.10/src/Fl_Tabs.cxx
@@ -0,0 +1,403 @@
+//
+// "$Id: Fl_Tabs.cxx 5791 2007-05-01 20:20:21Z matt $"
+//
+// Tab widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2005 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+// This is the "file card tabs" interface to allow you to put lots and lots
+// of buttons and switches in a panel, as popularized by many toolkits.
+
+// Each child widget is a card, and it's label() is printed on the card tab.
+// Clicking the tab makes that card visible.
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Tooltip.H>
+
+#define BORDER 2
+#define EXTRASPACE 10
+
+// return the left edges of each tab (plus a fake left edge for a tab
+// past the right-hand one). These position are actually of the left
+// edge of the slope. They are either seperated by the correct distance
+// or by EXTRASPACE or by zero.
+// Return value is the index of the selected item.
+
+int Fl_Tabs::tab_positions(int* p, int* wp) {
+ int selected = 0;
+ Fl_Widget*const* a = array();
+ int i;
+ char prev_draw_shortcut = fl_draw_shortcut;
+ fl_draw_shortcut = 1;
+
+ p[0] = Fl::box_dx(box());
+ for (i=0; i<children(); i++) {
+ Fl_Widget* o = *a++;
+ if (o->visible()) selected = i;
+
+ int wt = 0; int ht = 0;
+ o->measure_label(wt,ht);
+
+ wp[i] = wt+EXTRASPACE;
+ p[i+1] = p[i]+wp[i]+BORDER;
+ }
+ fl_draw_shortcut = prev_draw_shortcut;
+
+ int r = w();
+ if (p[i] <= r) return selected;
+ // uh oh, they are too big:
+ // pack them against right edge:
+ p[i] = r;
+ for (i = children(); i--;) {
+ int l = r-wp[i];
+ if (p[i+1] < l) l = p[i+1];
+ if (p[i] <= l) break;
+ p[i] = l;
+ r -= EXTRASPACE;
+ }
+ // pack them against left edge and truncate width if they still don't fit:
+ for (i = 0; i<children(); i++) {
+ if (p[i] >= i*EXTRASPACE) break;
+ p[i] = i*EXTRASPACE;
+ int W = w()-1-EXTRASPACE*(children()-i) - p[i];
+ if (wp[i] > W) wp[i] = W;
+ }
+ // adjust edges according to visiblity:
+ for (i = children(); i > selected; i--) {
+ p[i] = p[i-1]+wp[i-1];
+ }
+ return selected;
+}
+
+// return space needed for tabs. Negative to put them on the bottom:
+int Fl_Tabs::tab_height() {
+ int H = h();
+ int H2 = y();
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o->y() < y()+H) H = o->y()-y();
+ if (o->y()+o->h() > H2) H2 = o->y()+o->h();
+ }
+ H2 = y()+h()-H2;
+ if (H2 > H) return (H2 <= 0) ? 0 : -H2;
+ else return (H <= 0) ? 0 : H;
+}
+
+// this is used by fluid to pick tabs:
+Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
+ int H = tab_height();
+ if (H < 0) {
+ if (event_y > y()+h() || event_y < y()+h()+H) return 0;
+ } else {
+ if (event_y > y()+H || event_y < y()) return 0;
+ }
+ if (event_x < x()) return 0;
+ int p[128], wp[128];
+ tab_positions(p, wp);
+ for (int i=0; i<children(); i++) {
+ if (event_x < x()+p[i+1]) return child(i);
+ }
+ return 0;
+}
+
+void Fl_Tabs::redraw_tabs()
+{
+ int H = tab_height();
+ if (H >= 0) {
+ H += Fl::box_dy(box());
+ damage(FL_DAMAGE_SCROLL, x(), y(), w(), H);
+ } else {
+ H = Fl::box_dy(box()) - H;
+ damage(FL_DAMAGE_SCROLL, x(), y() + h() - H, w(), H);
+ }
+}
+
+int Fl_Tabs::handle(int event) {
+
+ Fl_Widget *o;
+ int i;
+
+ switch (event) {
+
+ case FL_PUSH: {
+ int H = tab_height();
+ if (H >= 0) {
+ if (Fl::event_y() > y()+H) return Fl_Group::handle(event);
+ } else {
+ if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event);
+ }}
+ case FL_DRAG:
+ case FL_RELEASE:
+ o = which(Fl::event_x(), Fl::event_y());
+ if (event == FL_RELEASE) {
+ push(0);
+ if (o && Fl::visible_focus() && Fl::focus()!=this) {
+ Fl::focus(this);
+ redraw_tabs();
+ }
+ if (o && value(o)) {
+ set_changed();
+ do_callback();
+ }
+ Fl_Tooltip::current(o);
+ } else {
+ push(o);
+ }
+ return 1;
+ case FL_MOVE: {
+ int ret = Fl_Group::handle(event);
+ Fl_Widget *o = Fl_Tooltip::current(), *n = o;
+ int H = tab_height();
+ if ( (H>=0) && (Fl::event_y()>y()+H) )
+ return ret;
+ else if ( (H<0) && (Fl::event_y() < y()+h()+H) )
+ return ret;
+ else {
+ n = which(Fl::event_x(), Fl::event_y());
+ if (!n) n = this;
+ }
+ if (n!=o)
+ Fl_Tooltip::enter(n);
+ return ret; }
+ case FL_FOCUS:
+ case FL_UNFOCUS:
+ if (!Fl::visible_focus()) return Fl_Group::handle(event);
+ if (Fl::event() == FL_RELEASE ||
+ Fl::event() == FL_SHORTCUT ||
+ Fl::event() == FL_KEYBOARD ||
+ Fl::event() == FL_FOCUS ||
+ Fl::event() == FL_UNFOCUS) {
+ redraw_tabs();
+ if (Fl::event() == FL_FOCUS || Fl::event() == FL_UNFOCUS) return 0;
+ else return 1;
+ } else return Fl_Group::handle(event);
+ case FL_KEYBOARD:
+ switch (Fl::event_key()) {
+ case FL_Left:
+ if (child(0)->visible()) return 0;
+ for (i = 1; i < children(); i ++)
+ if (child(i)->visible()) break;
+ value(child(i - 1));
+ set_changed();
+ do_callback();
+ return 1;
+ case FL_Right:
+ if (child(children() - 1)->visible()) return 0;
+ for (i = 0; i < children(); i ++)
+ if (child(i)->visible()) break;
+ value(child(i + 1));
+ set_changed();
+ do_callback();
+ return 1;
+ case FL_Down:
+ redraw();
+ return Fl_Group::handle(FL_FOCUS);
+ default:
+ break;
+ }
+ return Fl_Group::handle(event);
+ case FL_SHORTCUT:
+ for (i = 0; i < children(); ++i) {
+ Fl_Widget *c = child(i);
+ if (c->test_shortcut(c->label())) {
+ char sc = !c->visible();
+ value(c);
+ if (sc) set_changed();
+ do_callback();
+ return 1;
+ }
+ }
+ return Fl_Group::handle(event);
+ case FL_SHOW:
+ value(); // update visibilities and fall through
+ default:
+ return Fl_Group::handle(event);
+
+ }
+}
+
+int Fl_Tabs::push(Fl_Widget *o) {
+ if (push_ == o) return 0;
+ if (push_ && !push_->visible() || o && !o->visible())
+ redraw_tabs();
+ push_ = o;
+ return 1;
+}
+
+// The value() is the first visible child (or the last child if none
+// are visible) and this also hides any other children.
+// This allows the tabs to be deleted, moved to other groups, and
+// show()/hide() called without it screwing up.
+Fl_Widget* Fl_Tabs::value() {
+ Fl_Widget* v = 0;
+ Fl_Widget*const* a = array();
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (v) o->hide();
+ else if (o->visible()) v = o;
+ else if (!i) {o->show(); v = o;}
+ }
+ return v;
+}
+
+// Setting the value hides all other children, and makes this one
+// visible, iff it is really a child:
+int Fl_Tabs::value(Fl_Widget *newvalue) {
+ Fl_Widget*const* a = array();
+ int ret = 0;
+ for (int i=children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o == newvalue) {
+ if (!o->visible()) ret = 1;
+ o->show();
+ } else {
+ o->hide();
+ }
+ }
+ return ret;
+}
+
+enum {LEFT, RIGHT, SELECTED};
+
+void Fl_Tabs::draw() {
+ Fl_Widget *v = value();
+ int H = tab_height();
+
+ if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing:
+ Fl_Color c = v ? v->color() : color();
+
+ draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), c);
+
+ if (selection_color() != c) {
+ // Draw the top 5 lines of the tab pane in the selection color so
+ // that the user knows which tab is selected...
+ if (H >= 0) fl_push_clip(x(), y() + H, w(), 5);
+ else fl_push_clip(x(), y() + h() - H - 4, w(), 5);
+
+ draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H),
+ selection_color());
+
+ fl_pop_clip();
+ }
+ if (v) draw_child(*v);
+ } else { // redraw the child
+ if (v) update_child(*v);
+ }
+ if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) {
+ int p[128]; int wp[128];
+ int selected = tab_positions(p,wp);
+ int i;
+ Fl_Widget*const* a = array();
+ for (i=0; i<selected; i++)
+ draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], LEFT);
+ for (i=children()-1; i > selected; i--)
+ draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT);
+ if (v) {
+ i = selected;
+ draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED);
+ }
+ }
+}
+
+void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
+ int sel = (what == SELECTED);
+ int dh = Fl::box_dh(box());
+ int dy = Fl::box_dy(box());
+ char prev_draw_shortcut = fl_draw_shortcut;
+ fl_draw_shortcut = 1;
+
+ Fl_Boxtype bt = (o==push_ &&!sel) ? fl_down(box()) : box();
+
+ // compute offsets to make selected tab look bigger
+ int yofs = sel ? 0 : BORDER;
+
+ if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W;
+
+ if (H >= 0) {
+ if (sel) fl_clip(x1, y(), x2 - x1, H + dh - dy);
+ else fl_clip(x1, y(), x2 - x1, H);
+
+ H += dh;
+
+ Fl_Color c = sel ? selection_color() : o->selection_color();
+
+ draw_box(bt, x1, y() + yofs, W, H + 10 - yofs, c);
+
+ // Save the previous label color
+ Fl_Color oc = o->labelcolor();
+
+ // Draw the label using the current color...
+ o->labelcolor(sel ? labelcolor() : o->labelcolor());
+ o->draw_label(x1, y() + yofs, W, H - yofs, FL_ALIGN_CENTER);
+
+ // Restore the original label color...
+ o->labelcolor(oc);
+
+ if (Fl::focus() == this && o->visible())
+ draw_focus(box(), x1, y(), W, H);
+
+ fl_pop_clip();
+ } else {
+ H = -H;
+
+ if (sel) fl_clip(x1, y() + h() - H - dy, x2 - x1, H + dy);
+ else fl_clip(x1, y() + h() - H, x2 - x1, H);
+
+ H += dh;
+
+ Fl_Color c = sel ? selection_color() : o->selection_color();
+
+ draw_box(bt, x1, y() + h() - H - 10, W, H + 10 - yofs, c);
+
+ // Save the previous label color
+ Fl_Color oc = o->labelcolor();
+
+ // Draw the label using the current color...
+ o->labelcolor(sel ? labelcolor() : o->labelcolor());
+ o->draw_label(x1, y() + h() - H, W, H - yofs, FL_ALIGN_CENTER);
+
+ // Restore the original label color...
+ o->labelcolor(oc);
+
+ if (Fl::focus() == this && o->visible())
+ draw_focus(box(), x1, y() + h() - H, W, H);
+
+ fl_pop_clip();
+ }
+ fl_draw_shortcut = prev_draw_shortcut;
+}
+
+Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) :
+ Fl_Group(X,Y,W,H,l)
+{
+ box(FL_THIN_UP_BOX);
+ push_ = 0;
+}
+
+//
+// End of "$Id: Fl_Tabs.cxx 5791 2007-05-01 20:20:21Z matt $".
+//