aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/tipwin.cc181
-rw-r--r--src/tipwin.hh58
-rw-r--r--src/ui.cc65
-rw-r--r--src/ui.hh36
-rw-r--r--src/uicmd.cc6
6 files changed, 276 insertions, 72 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ceba3e01..c4c7949a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,6 +25,8 @@ dillo_SOURCES = \
dillo.cc \
paths.cc \
paths.hh \
+ tipwin.cc \
+ tipwin.hh \
ui.cc \
ui.hh \
uicmd.cc \
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;
+}
+
diff --git a/src/tipwin.hh b/src/tipwin.hh
new file mode 100644
index 00000000..77ffa60e
--- /dev/null
+++ b/src/tipwin.hh
@@ -0,0 +1,58 @@
+#ifndef __TIPWIN_HH__
+#define __TIPWIN_HH__
+
+#include <FL/Fl_Menu_Window.H>
+#include <FL/Fl_Button.H>
+
+
+/*
+ * Custom tooltip window
+ */
+class TipWin : public Fl_Menu_Window {
+ char tip[256];
+ int bgcolor, recent;
+ void *cur_widget;
+public:
+ TipWin();
+ void draw();
+ void value(const char *s);
+ void do_show(void *wid);
+ void do_hide();
+ void recent_tooltip(int val);
+
+ void cancel(void *wid) {
+ if (wid == cur_widget) { cur_widget = NULL; do_hide(); }
+ }
+};
+
+extern TipWin *my_tipwin(void);
+
+
+/*
+ * A Button sharing a custom tooltip window
+ */
+class TipWinButton : public Fl_Button {
+ char *mytooltip;
+ TipWin *tipwin;
+ public:
+ TipWinButton(int x, int y, int w, int h, const char *l = 0);
+ ~TipWinButton();
+ virtual int handle(int e);
+
+ void set_tooltip(const char *s);
+};
+
+/*
+ * A button that highlights on mouse over
+ */
+class CustButton : public TipWinButton {
+ Fl_Color norm_color, light_color;
+public:
+ CustButton(int x, int y, int w, int h, const char *l=0);
+ virtual int handle(int e);
+ void hl_color(Fl_Color col);
+};
+
+
+#endif // __TIPWIN_HH__
+
diff --git a/src/ui.cc b/src/ui.cc
index 5755cf98..6d53251b 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -19,6 +19,7 @@
#include "msg.h"
#include "timeout.hh"
#include "utf8.hh"
+#include "tipwin.hh"
#include <FL/Fl.H>
#include <FL/Fl_Pixmap.H>
@@ -158,10 +159,10 @@ int CustInput::handle(int e)
/*
* Used to handle "paste" within the toolbar's Clear button.
*/
-class CustPasteButton : public CustLightButton {
+class CustPasteButton : public CustButton {
public:
CustPasteButton(int x, int y, int w, int h, const char *l=0) :
- CustLightButton(x,y,w,h,l) {};
+ CustButton(x,y,w,h,l) {};
int handle(int e);
};
@@ -175,7 +176,7 @@ int CustPasteButton::handle(int e)
return 1;
}
}
- return CustLightButton::handle(e);
+ return CustButton::handle(e);
}
//----------------------------------------------------------------------------
@@ -379,13 +380,13 @@ static void bugmeter_cb(Fl_Widget *wid, void *data)
/*
* Make a generic navigation button
*/
-Fl_Button *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg,
- int b_n, int start)
+CustButton *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg,
+ int b_n, int start)
{
if (start)
p_xpos = 0;
- Fl_Button *b = new CustLightButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL);
+ CustButton *b = new CustButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL);
if (img)
b->image(img);
if (deimg)
@@ -413,14 +414,14 @@ void UI::make_toolbar(int tw, int th)
Bookmarks = make_button("Book", icons->ImgBook, NULL, UI_BOOK);
Tools = make_button("Tools", icons->ImgTools, NULL, UI_TOOLS);
- Back->tooltip("Previous page");
- Forw->tooltip("Next page");
- Home->tooltip("Go to the Home page");
- Reload->tooltip("Reload");
- Save->tooltip("Save this page");
- Stop->tooltip("Stop loading");
- Bookmarks->tooltip("View bookmarks");
- Tools->tooltip("Settings");
+ Back->set_tooltip("Previous page");
+ Forw->set_tooltip("Next page");
+ Home->set_tooltip("Go to the Home page");
+ Reload->set_tooltip("Reload");
+ Save->set_tooltip("Save this page");
+ Stop->set_tooltip("Stop loading");
+ Bookmarks->set_tooltip("View bookmarks");
+ Tools->set_tooltip("Settings");
}
/*
@@ -428,14 +429,14 @@ void UI::make_toolbar(int tw, int th)
*/
void UI::make_location(int ww)
{
- Fl_Button *b;
+ CustButton *b;
- Clear = b = new CustPasteButton(p_xpos,0,16,lh,0);
+ b = Clear = (CustButton*) new CustPasteButton(p_xpos,0,16,lh,0);
b->image(icons->ImgClear);
b->callback(clear_cb, this);
b->clear_visible_focus();
b->box(FL_THIN_UP_BOX);
- b->tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
+ b->set_tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
p_xpos += b->w();
Fl_Input *i = Location = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0);
@@ -445,20 +446,20 @@ void UI::make_location(int ww)
i->tooltip("Location");
p_xpos += i->w();
- Search = b = new CustLightButton(p_xpos,0,16,lh,0);
+ Search = b = new CustButton(p_xpos,0,16,lh,0);
b->image(icons->ImgSearch);
b->callback(search_cb, this);
b->clear_visible_focus();
b->box(FL_THIN_UP_BOX);
- b->tooltip("Search the Web");
+ b->set_tooltip("Search the Web");
p_xpos += b->w();
- Help = b = new CustLightButton(p_xpos,0,16,lh,0);
+ Help = b = new CustButton(p_xpos,0,16,lh,0);
b->image(icons->ImgHelp);
b->callback(help_cb, this);
b->clear_visible_focus();
b->box(FL_THIN_UP_BOX);
- b->tooltip("Help");
+ b->set_tooltip("Help");
p_xpos += b->w();
}
@@ -489,10 +490,10 @@ void UI::make_progress_bars(int wide, int thin_up)
*/
Fl_Widget *UI::make_filemenu_button()
{
- Fl_Button *btn;
+ CustButton *btn;
int w = 0, h = 0, padding;
- FileButton = btn = new Fl_Button(p_xpos,0,bw,bh,"W");
+ FileButton = btn = new CustButton(p_xpos,0,bw,bh,"W");
btn->labeltype(FL_FREE_LABELTYPE);
btn->measure_label(w, h);
padding = w;
@@ -504,7 +505,7 @@ Fl_Widget *UI::make_filemenu_button()
_MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding);
btn->box(FL_THIN_UP_BOX);
btn->callback(filemenu_cb, this);
- btn->tooltip("File menu");
+ btn->set_tooltip("File menu");
btn->clear_visible_focus();
if (!prefs.show_filemenu)
btn->hide();
@@ -610,11 +611,11 @@ void UI::make_status_bar(int ww, int wh)
StatusOutput->color(FL_GRAY_RAMP + 18);
// Bug Meter
- BugMeter = new CustLightButton(ww-bm_w,wh-sh,bm_w,sh);
+ BugMeter = new CustButton(ww-bm_w,wh-sh,bm_w,sh);
BugMeter->image(icons->ImgMeterOK);
BugMeter->box(FL_THIN_DOWN_BOX);
BugMeter->align(FL_ALIGN_INSIDE | FL_ALIGN_TEXT_NEXT_TO_IMAGE);
- BugMeter->tooltip("Show HTML bugs\n(right-click for menu)");
+ BugMeter->set_tooltip("Show HTML bugs\n(right-click for menu)");
BugMeter->callback(bugmeter_cb, this);
BugMeter->clear_visible_focus();
@@ -632,7 +633,6 @@ UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) :
LocBar = NavBar = StatusBar = NULL;
Tabs = NULL;
- TabTooltip = NULL;
TopGroup = this;
TopGroup->box(FL_NO_BOX);
clear_flag(SHORTCUT_LABEL);
@@ -691,7 +691,6 @@ UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) :
UI::~UI()
{
_MSG("UI::~UI()\n");
- dFree(TabTooltip);
}
/*
@@ -703,16 +702,6 @@ int UI::handle(int event)
int ret = 0;
if (event == FL_KEYBOARD) {
- /* WORKAROUND: remove the Panel's fltk-tooltip.
- * Although the expose event is delivered, it has an offset. This
- * extra call avoids the lingering tooltip. */
- if (!Fl::event_inside(Main) &&
- (Fl::event_inside((Fl_Widget*)tabs()) ||
- Fl::event_inside(NavBar) ||
- (LocBar && Fl::event_inside(LocBar)) ||
- (StatusBar && Fl::event_inside(StatusBar))))
- window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1);
-
return 0; // Receive as shortcut
} else if (event == FL_SHORTCUT) {
KeysCommand_t cmd = Keys::getKeyCmd();
diff --git a/src/ui.hh b/src/ui.hh
index ddc350a5..ac47b13c 100644
--- a/src/ui.hh
+++ b/src/ui.hh
@@ -11,6 +11,7 @@
#include <FL/Fl_Image.H>
#include <FL/Fl_Tabs.H>
+#include "tipwin.hh"
#include "findbar.hh"
typedef enum {
@@ -115,43 +116,16 @@ public:
}
};
-/*
- * A button that highlights on mouse over
- */
-class CustLightButton : public Fl_Button {
- Fl_Color norm_color, light_color;
-public:
- CustLightButton(int x, int y, int w, int h, const char *l=0) :
- Fl_Button(x,y,w,h,l) { norm_color = color(); light_color = 51; };
- virtual int handle(int e)
- {
- if (active()) {
- if (e == FL_ENTER) {
- color(light_color); // {17,26,51}
- 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 Fl_Button::handle(e);
- }
- void hl_color(Fl_Color col) { light_color = col; };
-};
//
// UI class definition -------------------------------------------------------
//
class UI : public CustGroupVertical {
CustTabs *Tabs;
- char *TabTooltip;
CustGroupVertical *TopGroup;
- Fl_Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools,
- *Clear, *Search, *Help, *BugMeter, *FileButton;
+ CustButton *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks,
+ *Tools, *Clear, *Search, *Help, *BugMeter, *FileButton;
CustGroupHorizontal *LocBar, *NavBar, *StatusBar;
Fl_Input *Location;
CustProgressBox *PProg, *IProg;
@@ -166,8 +140,8 @@ class UI : public CustGroupVertical {
bool PanelTemporary;
UIPanelmode Panelmode;
- Fl_Button *make_button(const char *label, Fl_Image *img,
- Fl_Image*deimg, int b_n, int start = 0);
+ CustButton *make_button(const char *label, Fl_Image *img, Fl_Image*deimg,
+ int b_n, int start = 0);
void make_toolbar(int tw, int th);
void make_location(int ww);
void make_progress_bars(int wide, int thin_up);
diff --git a/src/uicmd.cc b/src/uicmd.cc
index 40279a60..27ad7d49 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -107,7 +107,7 @@ class CustTabs : public Fl_Group {
Fl_Scroll *Scroll;
Fl_Pack *Pack;
Fl_Group *Control;
- CustLightButton *CloseBtn;
+ CustButton *CloseBtn;
int tabcolor_inactive, tabcolor_active;
void update_pack_offset(void);
@@ -151,12 +151,12 @@ public:
/* control buttons go inside a group */
Control = new Fl_Group(ww-ctl_w,0,ctl_w,ctab_h);
- CloseBtn = new CustLightButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
+ CloseBtn = new CustButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
CloseBtn->box(FL_THIN_UP_BOX);
CloseBtn->labelcolor(0x00641000);
CloseBtn->hl_color(FL_WHITE);
CloseBtn->clear_visible_focus();
- CloseBtn->tooltip(prefs.right_click_closes_tab ?
+ CloseBtn->set_tooltip(prefs.right_click_closes_tab ?
"Close current tab.\nor Right-click tab label to close." :
"Close current tab.\nor Middle-click tab label to close.");
CloseBtn->callback(close_tab_btn_cb, this);