diff --git a/libs/canvas/button.cc b/libs/canvas/button.cc new file mode 100644 index 0000000000..45a745474a --- /dev/null +++ b/libs/canvas/button.cc @@ -0,0 +1,192 @@ +/* + Copyright (C) 2017 Paul Davis + Author: Carl Hetherington + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include + +#include "canvas/button.h" +#include "canvas/canvas.h" +#include "canvas/debug.h" +#include "canvas/button.h" +#include "canvas/text.h" + +#include "gtkmm2ext/utils.h" + +using namespace std; +using namespace ArdourCanvas; +using namespace Gtkmm2ext; +using namespace Cairo; + +Button::Button (Canvas* canvas, double w, double h, Pango::FontDescription const & font_description) + : Rectangle (canvas) + , width (w) + , height (h) + , _label (new Text (canvas)) + , prelight (false) + , highlight (false) + , clicking (false) +{ + _label->set_font_description (font_description); + init (); +} + +Button::Button (Item* parent, double w, double h, Pango::FontDescription const & font_description) + : Rectangle (parent) + , _label (new Text (this)) + , prelight (false) + , highlight (false) + , clicking (false) +{ + _label->set_font_description (font_description); + init (); +} + + +Button::Button (Canvas* canvas, std::string const & str, Pango::FontDescription const & font_description) + : Rectangle (canvas) + , _label (new Text (canvas)) + , prelight (false) + , highlight (false) + , clicking (false) +{ + _label->set_font_description (font_description); + _label->set (str); + init (); +} + +Button::Button (Item* parent, std::string const & str, Pango::FontDescription const & font_description) + : Rectangle (parent) + , _label (new Text (this)) + , prelight (false) + , highlight (false) + , clicking (false) +{ + _label->set_font_description (font_description); + _label->set (str); + init (); +} + +void +Button::init () +{ + add (_label); + + Event.connect (sigc::mem_fun (*this, &Button::event_handler)); + _label->Event.connect (sigc::mem_fun (*this, &Button::event_handler)); + + Rect r = _label->bounding_box (); + _label->set_position (Duple ((width - r.width())/2.0, (height - r.height())/2.0)); +} + +void +Button::compute_bounding_box () const +{ + _bounding_box = Rect (0, 0, width, height); + + /* Item::bounding_box() will add children */ + + set_bbox_clean (); +} + +#define CORNER_RADIUS 5 + +void +Button::set_size (double w, double h) +{ + width = w; + height = h; + + set_bbox_dirty (); + redraw (); +} + +void +Button::set_label (std::string const & str) +{ + _label->set (str); + /* move to recenter */ + Rect r = _label->bounding_box (); + _label->set_position (Duple ((width - r.width())/2.0, (height - r.height())/2.0)); + redraw (); +} + +void +Button::render (Rect const & area, Cairo::RefPtr context) const +{ + Rect self = item_to_window (_bounding_box, false); + Rect draw = self.intersection (area); + + if (!draw) { + return; + } + + double cr, g, b, a; + + context->save (); + context->set_operator (OPERATOR_OVER); + + /* basic (rounded) rectangle, with pattern to fill */ + rounded_rectangle (context, self.x0 + 2.5, self.y0 + 2.5, width - 4, height - 4, CORNER_RADIUS); + + if (highlight) { + context->set_operator (Cairo::OPERATOR_OVER); + context->set_source_rgba (1.0, 0.0, 0.0, .2); + rounded_rectangle (context, self.x0 + 2.5, self.y0 + 2.5, width - 4, height - 4, CORNER_RADIUS); + context->fill(); + } + + if (prelight) { + context->set_operator (Cairo::OPERATOR_OVER); + color_to_rgba (contrasting_text_color (color.color()), cr, g, b, a); + context->set_source_rgba (cr, g, b, 0.1); + rounded_rectangle (context, self.x0 + 2.5, self.y0 + 2.5, width - 4, height - 4, CORNER_RADIUS); + context->fill(); + } + + context->restore (); + + Item::render_children (area, context); +} + +void +Button::set_highlight (bool yn) +{ + if (highlight != yn) { + highlight = yn; + redraw (); + } +} + +bool +Button::event_handler (GdkEvent *ev) +{ + if (ev->type == GDK_ENTER_NOTIFY) { + prelight = true; + redraw (); + } else if (ev->type == GDK_LEAVE_NOTIFY) { + prelight = false; + redraw (); + } + return false; +} + +std::string +Button::label() const +{ + return _label->text(); +} diff --git a/libs/canvas/canvas/button.h b/libs/canvas/canvas/button.h new file mode 100644 index 0000000000..4f645413a0 --- /dev/null +++ b/libs/canvas/canvas/button.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2011-2013 Paul Davis + Author: Carl Hetherington + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#pragma once + +#include + +#include "canvas/visibility.h" +#include "canvas/rectangle.h" +#include "canvas/types.h" + +namespace Pango { + class FontDescription; +} + +namespace ArdourCanvas +{ +class Text; + +class LIBCANVAS_API Button : public Rectangle +{ +public: + Button (Canvas*, double width, double height, Pango::FontDescription const &); + Button (Item*, double width, double height, Pango::FontDescription const &); + + Button (Canvas*, std::string const &, Pango::FontDescription const &); + Button (Item*, std::string const &, Pango::FontDescription const &); + + void render (Rect const &, Cairo::RefPtr) const; + void compute_bounding_box () const; + + void set_label (std::string const &); + std::string label() const; + Text* text() const { return _label; } + + void set_size (double w, double h); + void set_highlight (bool); + + private: + double width; + double height; + Text* _label; + bool prelight; + bool highlight; + bool clicking; + Gtkmm2ext::HSV color; + + bool event_handler (GdkEvent*); + void init (); +}; + +} + diff --git a/libs/canvas/wscript b/libs/canvas/wscript index 9716882c66..b69020e52a 100644 --- a/libs/canvas/wscript +++ b/libs/canvas/wscript @@ -20,6 +20,7 @@ canvas_sources = [ 'arc.cc', 'arrow.cc', 'box.cc', + 'button.cc', 'canvas.cc', 'circle.cc', 'container.cc',