// fltkcomplexbutton.cc contains code from FLTK 1.3's src/Fl_Button.cxx // that is Copyright 1998-2010 by Bill Spitzak and others. /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "fltkcomplexbutton.hh" using namespace dw::fltk::ui; /** Sets the current value of the button. A non-zero value sets the button to 1 (ON), and zero sets it to 0 (OFF). \param[in] v button value. \see set(), clear() */ int ComplexButton::value(int v) { v = v ? 1 : 0; oldval = v; clear_changed(); if (value_ != v) { value_ = v; if (box()) redraw(); else redraw_label(); return 1; } else { return 0; } } /** Turns on this button and turns off all other radio buttons in the group (calling \c value(1) or \c set() does not do this). */ void ComplexButton::setonly() { // set this radio button on, turn others off value(1); Fl_Group* g = parent(); Fl_Widget*const* a = g->array(); for (int i = g->children(); i--;) { Fl_Widget* o = *a++; if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0); } } void ComplexButton::draw() { if (type() == FL_HIDDEN_BUTTON) return; Fl_Color col = value() ? selection_color() : color(); draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col); draw_backdrop(); if (labeltype() == FL_NORMAL_LABEL && value()) { Fl_Color c = labelcolor(); labelcolor(fl_contrast(c, col)); draw_label(); labelcolor(c); } else draw_label(); if (Fl::focus() == this) draw_focus(); // ComplexButton is a Group; draw its children for (int i = children () - 1; i >= 0; i--) draw_child (*child (i)); } int ComplexButton::handle(int event) { int newval; switch (event) { case FL_ENTER: /* FALLTHROUGH */ case FL_LEAVE: // if ((value_?selection_color():color())==FL_GRAY) redraw(); return 1; case FL_PUSH: if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); case FL_DRAG: if (Fl::event_inside(this)) { if (type() == FL_RADIO_BUTTON) newval = 1; else newval = !oldval; } else { clear_changed(); newval = oldval; } if (newval != value_) { value_ = newval; set_changed(); redraw(); if (when() & FL_WHEN_CHANGED) do_callback(); } return 1; case FL_RELEASE: if (value_ == oldval) { if (when() & FL_WHEN_NOT_CHANGED) do_callback(); return 1; } set_changed(); if (type() == FL_RADIO_BUTTON) setonly(); else if (type() == FL_TOGGLE_BUTTON) oldval = value_; else { value(oldval); set_changed(); if (when() & FL_WHEN_CHANGED) { Fl_Widget_Tracker wp(this); do_callback(); if (wp.deleted()) return 1; } } if (when() & FL_WHEN_RELEASE) do_callback(); return 1; case FL_SHORTCUT: if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut())) return 0; if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); goto triggered_by_keyboard; case FL_FOCUS : /* FALLTHROUGH */ case FL_UNFOCUS : if (Fl::visible_focus()) { if (box() == FL_NO_BOX) { // Widgets with the FL_NO_BOX boxtype need a parent to // redraw, since it is responsible for redrawing the // background... int X = x() > 0 ? x() - 1 : 0; int Y = y() > 0 ? y() - 1 : 0; if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); } else redraw(); return 1; } else return 0; case FL_KEYBOARD : if (Fl::focus() == this && Fl::event_key() == ' ' && !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { set_changed(); triggered_by_keyboard: Fl_Widget_Tracker wp(this); if (type() == FL_RADIO_BUTTON && !value_) { setonly(); if (when() & FL_WHEN_CHANGED) do_callback(); } else if (type() == FL_TOGGLE_BUTTON) { value(!value()); if (when() & FL_WHEN_CHANGED) do_callback(); } if (wp.deleted()) return 1; if (when() & FL_WHEN_RELEASE) do_callback(); return 1; } default: return 0; } } /** The constructor creates the button using the given position, size and label. \param[in] X, Y, W, H position and size of the widget \param[in] L widget label, default is no label */ ComplexButton::ComplexButton(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) { Fl_Group::current(0); box(FL_UP_BOX); down_box(FL_NO_BOX); value_ = oldval = 0; shortcut_ = 0; set_flag(SHORTCUT_LABEL); } ComplexButton::~ComplexButton() { /* * The Fl_Group destructor clear()s the children, but layout expects * the flat view to be around until it deletes if. */ remove(0); }