From 19b9cddf7d5ef3daac5cda481db492f28574d28d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Nusser?= <andre.nusser@googlemail.com>
Date: Sun, 16 Apr 2017 12:54:16 +0200
Subject: Move button functionality to BaseButton. Create TabButton.

---
 plugingui/Makefile.am    |  1 +
 plugingui/button.cc      | 84 ++++++++---------------------------------
 plugingui/button.h       | 37 ++----------------
 plugingui/button_base.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
 plugingui/button_base.h  | 74 ++++++++++++++++++++++++++++++++++++
 plugingui/tabbutton.cc   | 84 ++++++++++++++++++++++++++++++++++++++---
 plugingui/tabbutton.h    | 34 ++++++++++++++---
 7 files changed, 297 insertions(+), 114 deletions(-)
 create mode 100644 plugingui/button_base.cc
 create mode 100644 plugingui/button_base.h

(limited to 'plugingui')

diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index 1dcff20..133c71f 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -29,6 +29,7 @@ nodist_libdggui_la_SOURCES = \
 	widget.cc \
 	colour.cc \
 	painter.cc \
+	button_base.cc \
 	button.cc \
 	pixelbuffer.cc \
 	lineedit.cc \
diff --git a/plugingui/button.cc b/plugingui/button.cc
index fb25390..0da79a0 100644
--- a/plugingui/button.cc
+++ b/plugingui/button.cc
@@ -28,49 +28,19 @@
 
 #include "painter.h"
 
-#include <stdio.h>
 #include <hugin.hpp>
+#include <stdio.h>
 
-namespace GUI {
-
-Button::Button(Widget *parent)
-	: Widget(parent)
-	, draw_state(up)
-	, button_state(up)
+namespace GUI
 {
-}
 
-Button::~Button()
+Button::Button(Widget* parent)
+	: ButtonBase(parent)
 {
 }
 
-void Button::buttonEvent(ButtonEvent* buttonEvent)
+Button::~Button()
 {
-	// Ignore everything except left clicks.
-	if(buttonEvent->button != MouseButton::left)
-	{
-		return;
-	}
-
-	if(buttonEvent->direction == Direction::down)
-	{
-		draw_state = down;
-		button_state = down;
-		in_button = true;
-		redraw();
-	}
-
-	if(buttonEvent->direction == Direction::up)
-	{
-		draw_state = up;
-		button_state = up;
-		redraw();
-		if(in_button)
-		{
-			clicked();
-			clickNotifier();
-		}
-	}
 }
 
 void Button::repaintEvent(RepaintEvent* repaintEvent)
@@ -89,48 +59,24 @@ void Button::repaintEvent(RepaintEvent* repaintEvent)
 		return;
 	}
 
-	switch(draw_state) {
-	case up:
+	switch(draw_state)
+	{
+	case State::Up:
 		box_up.setSize(w - padLeft, h - padTop);
 		p.drawImage(padLeft, padTop, box_up);
-
 		break;
-	case down:
+
+	case State::Down:
 		box_down.setSize(w - padLeft, h - padTop);
 		p.drawImage(padLeft, padTop, box_down);
 		break;
 	}
 
 	p.setColour(Colour(0.1));
-	p.drawText(width()/2-(text.length()*3)+(draw_state==up?0:1) + (padLeft / 2),
-	           height()/2+5+1+(draw_state==up?0:1) + (padTop / 2), font, text,
-	           true);
-}
-
-void Button::setText(const std::string& text)
-{
-	this->text = text;
-	redraw();
-}
-
-void Button::mouseLeaveEvent()
-{
-	in_button = false;
-	if(button_state == down)
-	{
-		draw_state = up;
-		redraw();
-	}
-}
-
-void Button::mouseEnterEvent()
-{
-	in_button = true;
-	if(button_state == down)
-	{
-		draw_state = down;
-		redraw();
-	}
+	auto x = (w / 2) - (3 * text.length()) + (draw_state == State::Up ? 0 : 1) +
+	         (padLeft / 2);
+	auto y = (h / 2) + 5 + 1 + (draw_state == State::Up ? 0 : 1) + (padTop / 2);
+	p.drawText(x, y, font, text, true);
 }
 
-} //GUI::
+} // GUI::
diff --git a/plugingui/button.h b/plugingui/button.h
index 04656ba..fde0459 100644
--- a/plugingui/button.h
+++ b/plugingui/button.h
@@ -26,42 +26,23 @@
  */
 #pragma once
 
-#include <string>
-
-#include <notifier.h>
-
-#include "widget.h"
-#include "painter.h"
+#include "button_base.h"
 #include "font.h"
 #include "texturedbox.h"
 
 namespace GUI {
 
-class Button : public Widget {
+class Button
+	: public ButtonBase {
 public:
-	Button(Widget *parent);
+	Button(Widget* parent);
 	virtual ~Button();
 
-	// From Widget:
-	bool isFocusable() override { return true; }
-	bool catchMouse() override { return true; }
-
-	void setText(const std::string& text);
-
-	Notifier<> clickNotifier;
-
 protected:
-	virtual void clicked() {}
-
 	// From Widget:
 	virtual void repaintEvent(RepaintEvent* e) override;
-	virtual void buttonEvent(ButtonEvent* e) override;
-	virtual void mouseLeaveEvent() override;
-	virtual void mouseEnterEvent() override;
 
 private:
-	bool in_button{false};
-
 	TexturedBox box_up{getImageCache(), ":pushbutton.png",
 			0, 0, // atlas offset (x, y)
 			11, 1, 11, // dx1, dx2, dx3
@@ -72,17 +53,7 @@ private:
 			11, 1, 11, // dx1, dx2, dx3
 			10, 72, 12}; // dy1, dy2, dy3
 
-	typedef enum {
-		up,
-		down
-	} state_t;
-
-	std::string text;
-
 	Font font{":fontemboss.png"};
-
-	state_t draw_state{up};
-	state_t button_state{up};
 };
 
 } // GUI::
diff --git a/plugingui/button_base.cc b/plugingui/button_base.cc
new file mode 100644
index 0000000..1030bbc
--- /dev/null
+++ b/plugingui/button_base.cc
@@ -0,0 +1,97 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ *            button_base.cc
+ *
+ *  Sat Apr 15 21:45:30 CEST 2017
+ *  Copyright 2017 André Nusser
+ *  andre.nusser@googlemail.com
+ ****************************************************************************/
+
+/*
+ *  This file is part of DrumGizmo.
+ *
+ *  DrumGizmo is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  DrumGizmo 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with DrumGizmo; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#include "button_base.h"
+
+namespace GUI {
+
+ButtonBase::ButtonBase(Widget *parent)
+	: Widget(parent)
+	, draw_state(State::Up)
+	, button_state(State::Up)
+{
+}
+
+ButtonBase::~ButtonBase()
+{
+}
+
+void ButtonBase::buttonEvent(ButtonEvent* buttonEvent)
+{
+	// Ignore everything except left clicks.
+	if(buttonEvent->button != MouseButton::left)
+	{
+		return;
+	}
+
+	if(buttonEvent->direction == Direction::down)
+	{
+		draw_state = State::Down;
+		button_state = State::Down;
+		in_button = true;
+		redraw();
+	}
+
+	if(buttonEvent->direction == Direction::up)
+	{
+		draw_state = State::Up;
+		button_state = State::Up;
+		redraw();
+		if(in_button)
+		{
+			clicked();
+			clickNotifier();
+		}
+	}
+}
+
+void ButtonBase::setText(const std::string& text)
+{
+	this->text = text;
+	redraw();
+}
+
+void ButtonBase::mouseLeaveEvent()
+{
+	in_button = false;
+	if(button_state == State::Down)
+	{
+		draw_state = State::Up;
+		redraw();
+	}
+}
+
+void ButtonBase::mouseEnterEvent()
+{
+	in_button = true;
+	if(button_state == State::Down)
+	{
+		draw_state = State::Down;
+		redraw();
+	}
+}
+
+} // GUI::
diff --git a/plugingui/button_base.h b/plugingui/button_base.h
new file mode 100644
index 0000000..a21a084
--- /dev/null
+++ b/plugingui/button_base.h
@@ -0,0 +1,74 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ *            button_base.h
+ *
+ *  Sat Apr 15 21:45:30 CEST 2017
+ *  Copyright 2017 André Nusser
+ *  andre.nusser@googlemail.com
+ ****************************************************************************/
+
+/*
+ *  This file is part of DrumGizmo.
+ *
+ *  DrumGizmo is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  DrumGizmo 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with DrumGizmo; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#pragma once
+
+#include <string>
+
+#include <notifier.h>
+
+#include "widget.h"
+
+namespace GUI {
+
+class ButtonBase
+	: public Widget
+{
+public:
+	ButtonBase(Widget* parent);
+	virtual ~ButtonBase();
+
+	// From Widget:
+	bool isFocusable() override { return true; }
+	bool catchMouse() override { return true; }
+
+	void setText(const std::string& text);
+
+	Notifier<> clickNotifier;
+
+protected:
+	virtual void clicked() {}
+
+	// From Widget:
+	virtual void repaintEvent(RepaintEvent* e) override {};
+	virtual void buttonEvent(ButtonEvent* e) override;
+	virtual void mouseLeaveEvent() override;
+	virtual void mouseEnterEvent() override;
+
+	bool in_button{false};
+
+	enum class State {
+		Up,
+		Down
+	};
+
+	std::string text;
+
+	State draw_state{State::Up};
+	State button_state{State::Up};
+};
+
+} // GUI::
diff --git a/plugingui/tabbutton.cc b/plugingui/tabbutton.cc
index 2a55572..1fc4619 100644
--- a/plugingui/tabbutton.cc
+++ b/plugingui/tabbutton.cc
@@ -26,24 +26,96 @@
  */
 #include "tabbutton.h"
 
+#include "painter.h"
+
 namespace GUI
 {
 
-TabButton::TabButton(Widget* parent, Widget* tabWidget)
-	: Button(parent)
-	, tabWidget(tabWidget)
+TabButton::TabButton(Widget* parent, Widget* tab_widget)
+	: ButtonBase(parent)
+	, tab_widget(tab_widget)
 {
 	CONNECT(this, clickNotifier, this, &TabButton::clickHandler);
 }
 
-Widget *TabButton::getTabWidget()
+TabButton::~TabButton()
+{
+}
+
+Widget* TabButton::getTabWidget()
+{
+	return tab_widget;
+}
+
+std::size_t TabButton::getMinimalWidth() const
 {
-	return tabWidget;
+	std::size_t padding = 15;
+	auto font_width = font.textWidth(text);
+
+	return font_width + padding;
+}
+
+std::size_t TabButton::getMinimalHeight() const
+{
+	std::size_t padding = 10;
+	auto font_height= font.textHeight(text);
+
+	return font_height + padding;
+}
+
+void TabButton::setActive(bool active)
+{
+	if (active) {
+		draw_state = State::Down;
+	}
+	else {
+		draw_state = State::Up;
+	}
+
+	redraw();
+}
+
+void TabButton::repaintEvent(RepaintEvent* e)
+{
+	Painter p(*this);
+
+	p.clear();
+
+	int padTop = 3;
+	int padLeft = 0;
+
+	int w = width();
+	int h = height();
+	if(w == 0 || h == 0)
+	{
+		return;
+	}
+
+	switch(draw_state)
+	{
+	case State::Up:
+		tab_passive.setSize(w - padLeft, h - padTop);
+		p.drawImage(padLeft, padTop, tab_passive);
+		break;
+
+	case State::Down:
+		tab_active.setSize(w - padLeft, h - padTop);
+		p.drawImage(padLeft, padTop, tab_active);
+		break;
+	}
+
+	p.setColour(Colour(0.1));
+	// FIXME: fix all the magic values here
+	auto x = (width() / 2) - (3 * text.length()) +
+	         (draw_state == State::Up ? 0 : 1) + (padLeft / 2);
+	auto y = (height() / 2) + 5 + 1 + (draw_state == State::Up ? 0 : 1) +
+	         (padTop / 2);
+	p.drawText(x, y + 4, font, text, true);
 }
 
 void TabButton::clickHandler()
 {
-	switchTabNotifier(tabWidget);
+	switchTabNotifier(tab_widget);
 }
 
 } // GUI::
diff --git a/plugingui/tabbutton.h b/plugingui/tabbutton.h
index 2f5e287..2f0dc10 100644
--- a/plugingui/tabbutton.h
+++ b/plugingui/tabbutton.h
@@ -28,26 +28,48 @@
 
 #include <notifier.h>
 
-#include "widget.h"
-#include "button.h"
+#include "button_base.h"
+#include "font.h"
+#include "texturedbox.h"
 
 namespace GUI
 {
 
 class TabButton
-	: public Button
+	: public ButtonBase
 {
 public:
-	TabButton(Widget* parent, Widget* tabWidget);
+	TabButton(Widget* parent, Widget* tab_widget);
+	virtual ~TabButton();
 
-	Widget *getTabWidget();
+	Widget* getTabWidget();
+	std::size_t getMinimalWidth() const;
+	std::size_t getMinimalHeight() const;
+	void setActive(bool active);
 
 	Notifier<Widget*> switchTabNotifier;
 
+protected:
+	// From Widget:
+	virtual void repaintEvent(RepaintEvent* e) override;
+
 private:
 	void clickHandler();
 
-	Widget* tabWidget;
+	Widget* tab_widget;
+	bool active;
+
+	TexturedBox tab_active{getImageCache(), ":tab.png",
+			0, 0, // atlas offset (x, y)
+			5, 1, 5, // dx1, dx2, dx3
+			5, 13, 1}; // dy1, dy2, dy3
+
+	TexturedBox tab_passive{getImageCache(), ":tab.png",
+			11, 0, // atlas offset (x, y)
+			5, 1, 5, // dx1, dx2, dx3
+			5, 13, 1}; // dy1, dy2, dy3
+
+	Font font{":fontemboss.png"};
 };
 
 } // GUI::
-- 
cgit v1.2.3