1 /* B.Oops
2  * Glitch effect sequencer LV2 plugin
3  *
4  * Copyright (C) 2019 by Sven Jähnichen
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef HALOBUTTON_HPP_
22 #define HALOBUTTON_HPP_
23 
24 #include "BWidgets/ValueWidget.hpp"
25 #include "BWidgets/Focusable.hpp"
26 #include "BWidgets/Label.hpp"
27 
28 class HaloButton : public BWidgets::ValueWidget, public BWidgets::Focusable
29 {
30 public:
HaloButton()31 	HaloButton () : HaloButton (0, 0, 0, 0, "editwidget", "") {}
32 
HaloButton(const double x,const double y,const double width,const double height,const std::string & name,const std::string & focusText)33 	HaloButton (const double x, const double y, const double width, const double height, const std::string& name, const std::string& focusText) :
34 		ValueWidget (x, y, width, height, name, 0.0),
35 		Focusable (std::chrono::milliseconds (BWIDGETS_DEFAULT_FOCUS_IN_MS),
36 			   std::chrono::milliseconds (BWIDGETS_DEFAULT_FOCUS_OUT_MS)),
37 		focusLabel_ (0, 0, 40, 20, name_ + BWIDGETS_DEFAULT_FOCUS_NAME, focusText)
38    	{
39    		focusLabel_.setStacking (BWidgets::STACKING_OVERSIZE);
40    		focusLabel_.resize ();
41    		focusLabel_.hide ();
42    		add (focusLabel_);
43    	}
44 
HaloButton(const HaloButton & that)45 	HaloButton (const HaloButton& that) :
46 		ValueWidget (that), Focusable (that),
47 		focusLabel_ (that.focusLabel_)
48 	{
49 		focusLabel_.hide();
50 		add (focusLabel_);
51 	}
52 
operator =(const HaloButton & that)53 	HaloButton& operator= (const HaloButton& that)
54 	{
55 		release (&focusLabel_);
56 		focusLabel_ = that.focusLabel_;
57 		focusLabel_.hide();
58 
59 		Widget::operator= (that);
60 		Focusable::operator= (that);
61 
62 		add (focusLabel_);
63 
64 		return *this;
65 
66 	}
67 
clone() const68 	virtual BWidgets::Widget* clone () const override {return new HaloButton (*this);}
69 
applyTheme(BStyles::Theme & theme)70 	virtual void applyTheme (BStyles::Theme& theme) override {applyTheme (theme, name_);}
71 
applyTheme(BStyles::Theme & theme,const std::string & name)72 	virtual void applyTheme (BStyles::Theme& theme, const std::string& name) override
73 	{
74 		Widget::applyTheme (theme, name);
75 		focusLabel_.applyTheme (theme, name + BWIDGETS_DEFAULT_FOCUS_NAME);
76 		focusLabel_.resize();
77 	}
78 
onButtonPressed(BEvents::PointerEvent * event)79 	virtual void onButtonPressed (BEvents::PointerEvent* event) override
80 	{
81 		setValue (1.0);
82 		Widget::cbfunction_[BEvents::EventType::BUTTON_PRESS_EVENT] (event);
83 	}
84 
onButtonReleased(BEvents::PointerEvent * event)85 	virtual void onButtonReleased (BEvents::PointerEvent* event) override
86 	{
87 		setValue (0.0);
88 		Widget::cbfunction_[BEvents::EventType::BUTTON_RELEASE_EVENT] (event);
89 	}
90 
onFocusIn(BEvents::FocusEvent * event)91 	virtual void onFocusIn (BEvents::FocusEvent* event) override
92 	{
93 		if (event && event->getWidget())
94 		{
95 			BUtilities::Point pos = event->getPosition();
96 			focusLabel_.moveTo (pos.x - 0.5 * focusLabel_.getWidth(), pos.y - focusLabel_.getHeight());
97 			focusLabel_.show();
98 		}
99 		Widget::onFocusIn (event);
100 	}
101 
onFocusOut(BEvents::FocusEvent * event)102 	virtual void onFocusOut (BEvents::FocusEvent* event) override
103 	{
104 		if (event && event->getWidget()) focusLabel_.hide();
105 		Widget::onFocusOut (event);
106 	}
107 
108 protected:
109 	BWidgets::Label focusLabel_;
110 
draw(const BUtilities::RectArea & area)111 	virtual void draw (const BUtilities::RectArea& area) override
112 	{
113 		if ((!widgetSurface_) || (cairo_surface_status (widgetSurface_) != CAIRO_STATUS_SUCCESS)) return;
114 
115 		if ((getWidth () >= 1) && (getHeight () >= 1))
116 		{
117 			// Draw super class widget elements first
118 			Widget::draw (area);
119 
120 			if (value == 1.0)
121 			{
122 				cairo_t* cr = cairo_create (widgetSurface_);
123 				if (cairo_status (cr) == CAIRO_STATUS_SUCCESS)
124 				{
125 					// Limit cairo-drawing area
126 					cairo_rectangle (cr, area.getX (), area.getY (), area.getWidth (), area.getHeight ());
127 					cairo_clip (cr);
128 
129 					double x0 = getXOffset ();
130 					double y0 = getYOffset ();
131 					double w = getEffectiveWidth ();
132 					double h = getEffectiveHeight ();
133 					cairo_rectangle (cr, x0, y0, w, h);
134 					cairo_set_line_width (cr, 1.0);
135 					cairo_set_source_rgba (cr, CAIRO_RGBA (BColors::white));
136 					cairo_stroke (cr);
137 					cairo_destroy (cr);
138 				}
139 			}
140 		}
141 	}
142 };
143 
144 #endif /* HALOBUTTON_HPP_ */
145