summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2019-05-09 20:52:43 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2019-05-09 20:52:47 +0200
commit15faa626f7df7a3024dda5d11001347ed4573568 (patch)
treeaad5c44d8906caef72e76f767b6895c0a4682a46
parent751f01eea8c40f70d412e691e6677d3daae54c7a (diff)
Add tooltip buttons to frames.
-rw-r--r--plugin/Makefile.mingw32.in3
-rw-r--r--plugingui/Makefile.am3
-rw-r--r--plugingui/eventhandler.cc23
-rw-r--r--plugingui/frame.cc20
-rw-r--r--plugingui/frame.h7
-rw-r--r--plugingui/guievent.h24
-rw-r--r--plugingui/helpbutton.cc75
-rw-r--r--plugingui/helpbutton.h58
-rw-r--r--plugingui/maintab.cc1
-rw-r--r--plugingui/maintab.h2
-rw-r--r--plugingui/nativewindow_win32.cc35
-rw-r--r--plugingui/nativewindow_win32.h2
-rw-r--r--plugingui/nativewindow_x11.cc22
-rw-r--r--plugingui/resources/help_button.pngbin0 -> 2196 bytes
-rw-r--r--plugingui/tooltip.cc184
-rw-r--r--plugingui/tooltip.h77
-rw-r--r--plugingui/widget.h5
17 files changed, 529 insertions, 12 deletions
diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in
index 3619fcb..eaf2e64 100644
--- a/plugin/Makefile.mingw32.in
+++ b/plugin/Makefile.mingw32.in
@@ -61,6 +61,7 @@ GUI_SRC = \
@top_srcdir@/plugingui/filebrowser.cc \
@top_srcdir@/plugingui/font.cc \
@top_srcdir@/plugingui/frame.cc \
+ @top_srcdir@/plugingui/helpbutton.cc \
@top_srcdir@/plugingui/humanizerframecontent.cc \
@top_srcdir@/plugingui/humaniservisualiser.cc \
@top_srcdir@/plugingui/image.cc \
@@ -94,6 +95,7 @@ GUI_SRC = \
@top_srcdir@/plugingui/texturedbox.cc \
@top_srcdir@/plugingui/timingframecontent.cc \
@top_srcdir@/plugingui/toggle.cc \
+ @top_srcdir@/plugingui/tooltip.cc \
@top_srcdir@/plugingui/utf8.cc \
@top_srcdir@/plugingui/verticalline.cc \
@top_srcdir@/plugingui/visualizerframecontent.cc \
@@ -135,6 +137,7 @@ RES = \
resources/bypass_button.png \
resources/font.png \
resources/fontemboss.png \
+ resources/help_button.png \
resources/knob.png \
resources/logo.png \
resources/png_error \
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index 8ae991a..09e5474 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -7,6 +7,7 @@ RES = \
resources/bypass_button.png \
resources/font.png \
resources/fontemboss.png \
+ resources/help_button.png \
resources/knob.png \
resources/logo.png \
resources/png_error \
@@ -71,6 +72,7 @@ nodist_libdggui_la_SOURCES = \
filebrowser.cc \
font.cc \
frame.cc \
+ helpbutton.cc \
humanizerframecontent.cc \
humaniservisualiser.cc \
image.cc \
@@ -104,6 +106,7 @@ nodist_libdggui_la_SOURCES = \
texturedbox.cc \
timingframecontent.cc \
toggle.cc \
+ tooltip.cc \
utf8.cc \
verticalline.cc \
visualizerframecontent.cc \
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index 696b242..fd333b8 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -254,10 +254,31 @@ void EventHandler::processEvents()
closeNotifier();
break;
+
+ case EventType::mouseEnter:
+ {
+ auto enterEvent = static_cast<MouseEnterEvent*>(event.get());
+ auto widget = window.find(enterEvent->x, enterEvent->y);
+ if(widget)
+ {
+ widget->mouseEnterEvent();
+ }
+ }
+ break;
+
+ case EventType::mouseLeave:
+ {
+ auto widget = window.mouseFocus();
+ if(widget)
+ {
+ widget->mouseLeaveEvent();
+ }
+ }
+ break;
}
}
- // Probe window and children to readrw as needed.
+ // Probe window and children to redraw as needed.
// NOTE: This method will invoke native->redraw() if a redraw is needed.
window.updateBuffer();
}
diff --git a/plugingui/frame.cc b/plugingui/frame.cc
index d552ff1..d375b6d 100644
--- a/plugingui/frame.cc
+++ b/plugingui/frame.cc
@@ -31,7 +31,7 @@
namespace GUI
{
-FrameWidget::FrameWidget(Widget* parent, bool has_switch)
+FrameWidget::FrameWidget(Widget* parent, bool has_switch, bool has_help_text)
: Widget(parent)
, is_switched_on(!has_switch)
, bar_height(24)
@@ -44,10 +44,19 @@ FrameWidget::FrameWidget(Widget* parent, bool has_switch)
power_button.setChecked(is_switched_on);
CONNECT(&power_button, stateChangedNotifier, this,
- &FrameWidget::powerButtonStateChanged);
+ &FrameWidget::powerButtonStateChanged);
}
power_button.setVisible(has_switch);
+ if(has_help_text)
+ {
+ // We only have to set this once as nothing happens on a resize
+ help_button.resize(16, 16);
+ help_button.move(width() - 4 - 16, 4);
+ help_button.setText("?");
+ }
+ help_button.setVisible(has_help_text);
+
CONNECT(this, sizeChangeNotifier, this, &FrameWidget::sizeChanged);
}
@@ -93,6 +102,11 @@ void FrameWidget::setTitle(std::string const& title)
label_width = font.textWidth(title.c_str()) / 2 + 1;
}
+void FrameWidget::setHelpText(const std::string& help_text)
+{
+ help_button.setHelpText(help_text);
+}
+
void FrameWidget::setContent(Widget* content)
{
this->content = content;
@@ -125,6 +139,8 @@ void FrameWidget::sizeChanged(int width, int height)
content->move(content_start_x, content_start_y);
content->resize(content_width, content_height);
}
+
+ help_button.move(width - 4 - 16, help_button.y());
}
} // GUI::
diff --git a/plugingui/frame.h b/plugingui/frame.h
index e29bd3d..db26ea9 100644
--- a/plugingui/frame.h
+++ b/plugingui/frame.h
@@ -30,6 +30,7 @@
#include "font.h"
#include "powerbutton.h"
+#include "helpbutton.h"
#include "widget.h"
namespace GUI
@@ -39,7 +40,7 @@ class FrameWidget
: public Widget
{
public:
- FrameWidget(Widget* parent, bool has_switch = false);
+ FrameWidget(Widget* parent, bool has_switch = false, bool has_help_text = false);
virtual ~FrameWidget() = default;
// From Widget:
@@ -48,7 +49,8 @@ public:
bool isSwitchedOn() { return is_switched_on; }
- void setTitle(std::string const& title);
+ void setTitle(const std::string& title);
+ void setHelpText(const std::string& help_text);
void setContent(Widget* content);
void setOnSwitch(bool on);
@@ -81,6 +83,7 @@ private:
// switch
bool is_switched_on;
PowerButton power_button{this};
+ HelpButton help_button{this};
void powerButtonStateChanged(bool clicked);
diff --git a/plugingui/guievent.h b/plugingui/guievent.h
index 11a7b9b..fe51826 100644
--- a/plugingui/guievent.h
+++ b/plugingui/guievent.h
@@ -42,7 +42,9 @@ enum class EventType
key,
close,
resize,
- move
+ move,
+ mouseEnter,
+ mouseLeave,
};
class Event
@@ -172,6 +174,26 @@ public:
int y;
};
+class MouseEnterEvent
+ : public Event
+{
+public:
+ EventType type() { return EventType::mouseEnter; }
+
+ int x;
+ int y;
+};
+
+class MouseLeaveEvent
+ : public Event
+{
+public:
+ EventType type() { return EventType::mouseLeave; }
+
+ int x;
+ int y;
+};
+
using EventQueue = std::list<std::shared_ptr<Event>>;
struct Rect
diff --git a/plugingui/helpbutton.cc b/plugingui/helpbutton.cc
new file mode 100644
index 0000000..fa061a6
--- /dev/null
+++ b/plugingui/helpbutton.cc
@@ -0,0 +1,75 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ * helpbutton.cc
+ *
+ * Wed May 8 17:10:08 CEST 2019
+ * Copyright 2019 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * 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 "helpbutton.h"
+
+#include "painter.h"
+
+#include <iostream>
+
+namespace GUI
+{
+
+HelpButton::HelpButton(Widget* parent)
+ : ButtonBase(parent)
+ , tip(this)
+{
+ CONNECT(this, clickNotifier, this, &HelpButton::showHelpText);
+ tip.hide();
+}
+
+void HelpButton::setHelpText(const std::string& help_text)
+{
+ tip.setText(help_text);
+}
+
+void HelpButton::repaintEvent(RepaintEvent* repaintEvent)
+{
+ Painter p(*this);
+
+ bool state = true;
+
+ // enabled and on
+ if(state)
+ {
+ if(button_state == ButtonBase::State::Down)
+ {
+ p.drawImage(0, 0, pushed);
+ }
+ else
+ {
+ p.drawImage(0, 0, normal);
+ }
+ return;
+ }
+}
+
+void HelpButton::showHelpText()
+{
+ tip.show();
+}
+
+} // GUI::
diff --git a/plugingui/helpbutton.h b/plugingui/helpbutton.h
new file mode 100644
index 0000000..6e97eca
--- /dev/null
+++ b/plugingui/helpbutton.h
@@ -0,0 +1,58 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ * helpbutton.h
+ *
+ * Wed May 8 17:10:08 CEST 2019
+ * Copyright 2019 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * 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 "texture.h"
+#include "button_base.h"
+#include "tooltip.h"
+
+namespace GUI
+{
+
+class HelpButton
+ : public ButtonBase
+{
+public:
+ HelpButton(Widget* parent);
+ virtual ~HelpButton() = default;
+
+ void setHelpText(const std::string& help_text);
+
+protected:
+ // From Widget:
+ virtual void repaintEvent(RepaintEvent* repaintEvent) override;
+
+private:
+ void showHelpText();
+
+ Texture normal{getImageCache(), ":resources/help_button.png", 0, 0, 16, 16};
+ Texture pushed{getImageCache(), ":resources/help_button.png", 16, 0, 16, 16};
+
+ Tooltip tip;
+};
+
+} // GUI::
diff --git a/plugingui/maintab.cc b/plugingui/maintab.cc
index d98c6ea..1cf445a 100644
--- a/plugingui/maintab.cc
+++ b/plugingui/maintab.cc
@@ -53,6 +53,7 @@ MainTab::MainTab(Widget* parent,
add("Resampling", resampling_frame, resamplingframe_content, 10, 0);
add("Velocity Humanizer", humanizer_frame, humanizerframe_content, 10, 1);
+ humanizer_frame.setHelpText("Hello World\nThis is a nice World\n... I think");
add("Timing Humanizer", timing_frame, timingframe_content, 10, 1);
add("Visualizer", visualizer_frame, visualizerframe_content, 10, 1);
add("Bleed Control", bleedcontrol_frame, bleedcontrolframe_content, 9, 1);
diff --git a/plugingui/maintab.h b/plugingui/maintab.h
index efd83e9..7daa669 100644
--- a/plugingui/maintab.h
+++ b/plugingui/maintab.h
@@ -69,7 +69,7 @@ private:
FrameWidget drumkit_frame{this, false};
FrameWidget status_frame{this, false};
- FrameWidget humanizer_frame{this, true};
+ FrameWidget humanizer_frame{this, true, true};
FrameWidget diskstreaming_frame{this, false};
FrameWidget bleedcontrol_frame{this, true};
FrameWidget resampling_frame{this, true};
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index 5cfb179..0dc30de 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -35,6 +35,16 @@
namespace GUI
{
+static BOOL trackMouse(HWND hwnd)
+{
+ TRACKMOUSEEVENT ev{};
+ ev.cbSize = sizeof(ev);
+ ev.dwFlags = TME_HOVER | TME_LEAVE;
+ ev.hwndTrack = hwnd;
+ ev.dwHoverTime = 1;
+ return TrackMouseEvent(&ev);
+}
+
LRESULT CALLBACK NativeWindowWin32::dialogProc(HWND hwnd, UINT msg,
WPARAM wp, LPARAM lp)
{
@@ -89,9 +99,20 @@ LRESULT CALLBACK NativeWindowWin32::dialogProc(HWND hwnd, UINT msg,
// return 0;
case WM_MOUSEMOVE:
{
+ trackMouse(native->m_hwnd);
auto mouseMoveEvent = std::make_shared<MouseMoveEvent>();
mouseMoveEvent->x = (short)LOWORD(lp);
mouseMoveEvent->y = (short)HIWORD(lp);
+ native->last_mouse_position = { mouseMoveEvent->x, mouseMoveEvent->y };
+
+ if(!native->mouse_in_window)
+ {
+ auto enterEvent = std::make_shared<MouseEnterEvent>();
+ enterEvent->x = native->last_mouse_position.first;
+ enterEvent->y = native->last_mouse_position.second;
+ native->event_queue.push_back(enterEvent);
+ native->mouse_in_window = true;
+ }
native->event_queue.push_back(mouseMoveEvent);
}
break;
@@ -295,8 +316,17 @@ LRESULT CALLBACK NativeWindowWin32::dialogProc(HWND hwnd, UINT msg,
DeleteObject(ourbitmap);
}
}
+ break;
- return DefWindowProc(hwnd, msg, wp, lp);
+ case WM_MOUSELEAVE:
+ {
+ auto leaveEvent = std::make_shared<MouseLeaveEvent>();
+ leaveEvent->x = native->last_mouse_position.first;
+ leaveEvent->y = native->last_mouse_position.second;
+ native->event_queue.push_back(leaveEvent);
+ native->mouse_in_window = false;
+ }
+ break;
}
return DefWindowProc(hwnd, msg, wp, lp);
@@ -391,6 +421,9 @@ NativeWindowWin32::NativeWindowWin32(void* native_window, Window& window)
GetModuleHandle(nullptr), nullptr);
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);
+
+ // Set up initial tracking of the mouse leave events
+ trackMouse(m_hwnd);
}
NativeWindowWin32::~NativeWindowWin32()
diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h
index 2945be6..d547dc0 100644
--- a/plugingui/nativewindow_win32.h
+++ b/plugingui/nativewindow_win32.h
@@ -66,6 +66,8 @@ private:
HWND parent_window;
Window& window;
WNDID m_hwnd = 0;
+ bool mouse_in_window{false};
+ std::pair<int, int> last_mouse_position{0, 0};
char* m_className = nullptr;
EventQueue event_queue;
};
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index f77a772..e96f26a 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -92,7 +92,9 @@ NativeWindowX11::NativeWindowX11(void* native_window, Window& window)
KeyReleaseMask|
ExposureMask |
StructureNotifyMask |
- SubstructureNotifyMask);
+ SubstructureNotifyMask |
+ EnterWindowMask |
+ LeaveWindowMask);
XSelectInput(display, xwindow, mask);
// Register the delete window message:
@@ -467,7 +469,25 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)
break;
case EnterNotify:
+ //DEBUG(x11, "EnterNotify");
+ {
+ auto enterEvent = std::make_shared<MouseEnterEvent>();
+ enterEvent->x = xevent.xcrossing.x;
+ enterEvent->y = xevent.xcrossing.y;
+ event_queue.push_back(enterEvent);
+ }
+ break;
+
case LeaveNotify:
+ //DEBUG(x11, "LeaveNotify");
+ {
+ auto leaveEvent = std::make_shared<MouseLeaveEvent>();
+ leaveEvent->x = xevent.xcrossing.x;
+ leaveEvent->y = xevent.xcrossing.y;
+ event_queue.push_back(leaveEvent);
+ }
+ break;
+
case MapNotify:
case MappingNotify:
//DEBUG(x11, "EnterNotify");
diff --git a/plugingui/resources/help_button.png b/plugingui/resources/help_button.png
new file mode 100644
index 0000000..95790f5
--- /dev/null
+++ b/plugingui/resources/help_button.png
Binary files differ
diff --git a/plugingui/tooltip.cc b/plugingui/tooltip.cc
new file mode 100644
index 0000000..4b1998a
--- /dev/null
+++ b/plugingui/tooltip.cc
@@ -0,0 +1,184 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ * tooltip.cc
+ *
+ * Wed May 8 17:31:42 CEST 2019
+ * Copyright 2019 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * 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 "tooltip.h"
+
+#include "painter.h"
+#include "font.h"
+#include "window.h"
+#include <iostream>
+
+namespace GUI
+{
+
+Tooltip::Tooltip(Widget *parent)
+ : Widget(parent->window())
+ , activating_widget(parent)
+{
+ resize(32, 32);
+}
+
+Tooltip::~Tooltip()
+{
+}
+
+void Tooltip::setText(const std::string& text)
+{
+ this->text = text;
+ needs_preprocessing = true;
+ redraw();
+}
+
+void Tooltip::resize(std::size_t width, std::size_t height)
+{
+ Widget::resize(width, height);
+}
+
+void Tooltip::repaintEvent(RepaintEvent* repaintEvent)
+{
+ if(needs_preprocessing)
+ {
+ preprocessText();
+ }
+
+ Painter p(*this);
+
+ if((width() == 0) || (height() == 0))
+ {
+ return;
+ }
+
+ box.setSize(width(), height());
+ p.drawImage(0, 0, box);
+ p.setColour(Colour(183.0f/255.0f, 219.0f/255.0f, 255.0f/255.0f, 1.0f));
+
+ int ypos = font.textHeight() + y_border;
+
+ for(std::size_t i = 0; i < preprocessed_text.size(); ++i)
+ {
+ if(i * font.textHeight() >= (height() - y_border - font.textHeight()))
+ {
+ break;
+ }
+
+ auto const& line = preprocessed_text[i];
+ p.drawText(x_border, ypos, font, line);
+ ypos += font.textHeight();
+ }
+}
+
+void Tooltip::preprocessText()
+{
+ std::vector<std::string> lines;
+
+ preprocessed_text.clear();
+ std::string text = this->text;
+
+ // Handle tab characters
+ for(std::size_t i = 0; i < text.length(); ++i)
+ {
+ char ch = text.at(i);
+ if(ch == '\t')
+ {
+ text.erase(i, 1);
+ text.insert(i, 4, ' ');
+ }
+ }
+
+ // Handle "\r"
+ for(std::size_t i = 0; i < text.length(); ++i)
+ {
+ char ch = text.at(i);
+ if(ch == '\r')
+ {
+ text.erase(i, 1);
+ }
+ }
+
+ // Handle new line characters
+ std::size_t pos = 0;
+ do
+ {
+ pos = text.find("\n");
+ lines.push_back(text.substr(0, pos));
+ text = text.substr(pos + 1);
+ } while(pos != std::string::npos);
+
+ max_text_width = 0;
+ total_text_height = 0;
+ for(auto const& line: lines)
+ {
+ std::string valid;
+ std::string current;
+ for(auto c: line)
+ {
+ current += c;
+ if(c == ' ')
+ {
+ valid.append(current.substr(valid.size()));
+ }
+ }
+ preprocessed_text.push_back(current);
+
+ max_text_width = std::max(max_text_width, font.textWidth(line));
+ total_text_height += font.textHeight(line);
+ }
+}
+
+void Tooltip::mouseLeaveEvent()
+{
+ hide();
+}
+
+void Tooltip::show()
+{
+ if(needs_preprocessing)
+ {
+ preprocessText();
+ }
+
+ resize(max_text_width + 2*x_border, total_text_height + 2*y_border);
+
+ int x = activating_widget->translateToWindowX();
+ int y = activating_widget->translateToWindowY();
+
+ if(x + width() > window()->width())
+ {
+ x -= width();
+ x += activating_widget->width();
+ }
+
+ if(y + height() > window()->height())
+ {
+ y -= height();
+ y += activating_widget->height();
+ }
+
+ move(x, y);
+ Widget::show();
+}
+
+} // GUI::
diff --git a/plugingui/tooltip.h b/plugingui/tooltip.h
new file mode 100644
index 0000000..b449512
--- /dev/null
+++ b/plugingui/tooltip.h
@@ -0,0 +1,77 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ * tooltip.h
+ *
+ * Wed May 8 17:31:42 CEST 2019
+ * Copyright 2019 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * 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.h>
+#include <vector>
+
+#include <notifier.h>
+
+#include "widget.h"
+#include "painter.h"
+#include "texturedbox.h"
+#include "font.h"
+
+namespace GUI
+{
+
+class Tooltip
+ : public Widget
+{
+public:
+ Tooltip(Widget *parent);
+ virtual ~Tooltip();
+
+ void setText(const std::string& text);
+
+ // From Widget:
+ virtual void repaintEvent(RepaintEvent* repaint_event) override;
+ virtual void resize(std::size_t height, std::size_t width) override;
+ virtual void mouseLeaveEvent() override;
+ virtual void show() override;
+
+private:
+ void preprocessText();
+
+ TexturedBox box{getImageCache(), ":resources/thinlistbox.png",
+ 0, 0, // atlas offset (x, y)
+ 1, 1, 1, // dx1, dx2, dx3
+ 1, 1, 1}; // dy1, dy2, dy3
+ Font font;
+
+ static constexpr int x_border{10};
+ static constexpr int y_border{8};
+
+ bool needs_preprocessing{false};
+ std::string text;
+ std::vector<std::string> preprocessed_text;
+ std::size_t max_text_width{0};
+ std::size_t total_text_height{0};
+ Widget* activating_widget;
+};
+
+} // GUI::
diff --git a/plugingui/widget.h b/plugingui/widget.h
index 3b17f1f..8595ef7 100644
--- a/plugingui/widget.h
+++ b/plugingui/widget.h
@@ -97,15 +97,14 @@ public:
Notifier<std::size_t, std::size_t> sizeChangeNotifier; // (width, height)
Notifier<int, int> positionChangeNotifier; // (x, y)
-protected:
- friend class EventHandler;
-
//! Translate x-coordinate from parent-space to window-space.
virtual std::size_t translateToWindowX();
//! Translate y-coordinate from parent-space to window-space.
virtual std::size_t translateToWindowY();
+protected:
+ friend class EventHandler;
PixelBufferAlpha pixbuf{0,0};
std::vector<Widget*> children;