aboutsummaryrefslogtreecommitdiff
path: root/src/tipwin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tipwin.cc')
-rw-r--r--src/tipwin.cc181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/tipwin.cc b/src/tipwin.cc
new file mode 100644
index 00000000..cec3dbaa
--- /dev/null
+++ b/src/tipwin.cc
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <FL/fl_draw.H>
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Menu_Window.H>
+#include <FL/Fl_Tooltip.H>
+#include <FL/Fl_Button.H>
+
+#include "tipwin.hh"
+
+/*
+ * Forward declarations
+ */
+static void show_timeout(void*);
+static void recent_timeout(void*);
+
+/*
+ * Custom tooltip window
+ */
+TipWin::TipWin() : Fl_Menu_Window(1, 1) // will autosize
+{
+ bgcolor = fl_color_cube(FL_NUM_RED - 1, FL_NUM_GREEN - 1, FL_NUM_BLUE - 2);
+ recent = 0;
+ strcpy(tip, "");
+ cur_widget = NULL;
+ set_override(); // no border
+ end();
+}
+
+void TipWin::draw()
+{
+ draw_box(FL_BORDER_BOX, 0, 0, w(), h(), bgcolor);
+ fl_color(FL_BLACK);
+ fl_font(labelfont(), labelsize());
+ fl_draw(tip, 3, 3, w() - 6, h() - 6,
+ //Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_WRAP));
+ Fl_Align(FL_ALIGN_LEFT));
+}
+
+void TipWin::value(const char *s) {
+ // Recalc size of window
+ snprintf(tip, sizeof(tip) - 1, "%s", s);
+ fl_font(labelfont(), labelsize());
+ int W = w(), H = h();
+ W = 0;
+ fl_measure(tip, W, H, 0);
+ W += 8; H += 8;
+ size(W, H);
+ redraw();
+}
+
+void TipWin::do_show(void *wid) {
+ cur_widget = wid; // Keep track of requesting widget
+ Fl::add_timeout(recent ? 0.2f : 0.8f, show_timeout);
+}
+
+void TipWin::do_hide() {
+ Fl::remove_timeout(show_timeout);
+ if (shown()) {
+ hide();
+ recent = 1;
+ Fl::add_timeout(0.8f, recent_timeout);
+ }
+}
+
+void TipWin::recent_tooltip(int val) {
+ recent = val;
+}
+
+//--------------------------------------------------------------------------
+
+TipWin *my_tipwin(void)
+{
+ static TipWin *tw = NULL;
+
+ if (!tw) {
+ Fl_Group *save = Fl_Group::current(); // save current widget..
+ tw = new TipWin(); // ..because this trashes it
+ tw->hide(); // start hidden
+ Fl_Group::current(save); // ..then back to previous.
+ }
+ return tw;
+}
+
+static void show_timeout(void*) {
+ // if offscreen, move tip ABOVE mouse instead
+ int scr_x, scr_y, scr_w, scr_h;
+ Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+ int ty = Fl::event_y_root() + 20;
+ if (ty + my_tipwin()->h() > scr_h)
+ ty = Fl::event_y_root() - 20 - my_tipwin()->h();
+ if (ty < 0) ty = 0;
+
+ my_tipwin()->position(Fl::event_x_root(), ty);
+ my_tipwin()->show();
+ my_tipwin()->recent_tooltip(0);
+}
+
+static void recent_timeout(void*) {
+ my_tipwin()->recent_tooltip(0);
+}
+
+
+//---------------------------------------------------------------------------
+
+/*
+ * A Button sharing a custom tooltip window
+ */
+TipWinButton::TipWinButton(int x, int y, int w, int h, const char *l) :
+ Fl_Button(x, y, w, h, l)
+{
+ tipwin = my_tipwin();
+ mytooltip = strdup("empty");
+}
+
+TipWinButton::~TipWinButton(void)
+{
+ tipwin->cancel(this); // cancel tooltip if shown
+ free(mytooltip);
+}
+
+int TipWinButton::handle(int e)
+{
+ switch (e) {
+ case FL_ENTER:
+ tipwin->value(mytooltip);
+ tipwin->do_show(this);
+ break;
+ case FL_PUSH: // push mouse
+ case FL_RELEASE: // release mouse
+ case FL_HIDE: // widget goes away
+ case FL_LEAVE: // leave focus
+ tipwin->do_hide();
+ break;
+ }
+ return (Fl_Button::handle(e));
+}
+
+void TipWinButton::set_tooltip(const char *s)
+{
+ free(mytooltip);
+ mytooltip = strdup(s);
+}
+
+
+//---------------------------------------------------------------------------
+
+/*
+ * A Light Button sharing a custom tooltip window
+ */
+CustButton::CustButton(int x, int y, int w, int h, const char *l) :
+ TipWinButton(x,y,w,h,l)
+{
+ norm_color = color();
+ light_color = 17; // {17,26,51}
+}
+
+int CustButton::handle(int e)
+{
+ if (active()) {
+ if (e == FL_ENTER) {
+ color(light_color);
+ redraw();
+ } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) {
+ color(norm_color);
+ redraw();
+ }
+ } else if (e == FL_DEACTIVATE && color() != norm_color) {
+ color(norm_color);
+ redraw();
+ }
+ return TipWinButton::handle(e);
+}
+
+void CustButton::hl_color(Fl_Color col)
+{
+ light_color = col;
+}
+