add tooltips for iconbar buttons when title is too long to fit

This commit is contained in:
Matteo Galiazzo 2008-05-05 05:05:52 -07:00 committed by Mark Tiefenbruck
parent ba604ac821
commit 4a3be045b2
13 changed files with 241 additions and 10 deletions

View file

@ -1,5 +1,8 @@
(Format: Year/Month/Day)
Changes for 1.0.1:
*08/05/05:
* Add tooltips for iconbar buttons (thanks Matteo Galiazzo)
TooltipWindow.cc/hh
*08/05/02:
* Minor changes for fluxbox-generate_menu (thanks skiidoo)
util/fluxbox-generate_menu.in

View file

@ -30,7 +30,8 @@ namespace FbTk {
Button::Button(int screen_num, int x, int y,
unsigned int width, unsigned int height):
FbWindow(screen_num, x, y, width, height,
ExposureMask | ButtonPressMask | ButtonReleaseMask),
ExposureMask | ButtonPressMask | EnterWindowMask |
LeaveWindowMask | ButtonReleaseMask),
m_background_pm(0),
m_pressed_pm(0),
m_pressed_color(),
@ -45,7 +46,8 @@ Button::Button(int screen_num, int x, int y,
Button::Button(const FbWindow &parent, int x, int y,
unsigned int width, unsigned int height):
FbWindow(parent, x, y, width, height,
ExposureMask | ButtonPressMask | ButtonReleaseMask),
ExposureMask | ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask),
m_background_pm(0),
m_pressed_pm(0),
m_pressed_color(),
@ -90,6 +92,14 @@ void Button::setBackgroundPixmap(Pixmap pm) {
FbTk::FbWindow::setBackgroundPixmap(pm);
}
void Button::enterNotifyEvent(XCrossingEvent &ce){
}
void Button::leaveNotifyEvent(XCrossingEvent &ce){
}
void Button::buttonPressEvent(XButtonEvent &event) {
bool update = false;
if (m_pressed_pm != 0) {

View file

@ -61,6 +61,8 @@ public:
//@{
virtual void buttonPressEvent(XButtonEvent &event);
virtual void buttonReleaseEvent(XButtonEvent &event);
virtual void enterNotifyEvent(XCrossingEvent &ce);
virtual void leaveNotifyEvent(XCrossingEvent &ce);
virtual void exposeEvent(XExposeEvent &event);
//@}

View file

@ -158,11 +158,9 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
translateSize(m_orientation, textw, texth);
int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
bevel(),
justify(),
font(),
bevel(), justify(), font(),
text().data(), text().size(),
textlen); // return new text lne
textlen); // return new text len
// center text by default
int center_pos = texth/2 + font().ascent()/2 - 1;
@ -183,6 +181,23 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
textx, texty, m_orientation); // position
}
bool TextButton::textExceeds(int x_offset) {
unsigned int textlen = text().size();
// do text alignment
unsigned int textw = width(), texth = height();
translateSize(m_orientation, textw, texth);
FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
bevel(), justify(), font(), text().data(), text().size(),
textlen); // return new text len
return text().size()>textlen;
}
void TextButton::exposeEvent(XExposeEvent &event) {
clearArea(event.x, event.y, event.width, event.height, false);
}

View file

@ -80,6 +80,8 @@ public:
protected:
virtual void drawText(int x_offset, int y_offset, FbDrawable *drawable_override);
// return true if the text will be truncated
bool textExceeds(int x_offset);
private:
FbTk::Font *m_font;

View file

@ -52,7 +52,8 @@ IconButton::IconButton(const FbTk::FbWindow &parent,
FbTk::TextButton(parent, focused_theme->text().font(), win.title()),
m_win(win),
m_icon_window(*this, 1, 1, 1, 1,
ExposureMask | ButtonPressMask | ButtonReleaseMask),
ExposureMask |EnterWindowMask | LeaveWindowMask |
ButtonPressMask | ButtonReleaseMask),
m_use_pixmap(true),
m_theme(win, focused_theme, unfocused_theme),
m_pm(win.screen().imageControl()) {
@ -79,6 +80,20 @@ void IconButton::exposeEvent(XExposeEvent &event) {
FbTk::TextButton::exposeEvent(event);
}
void IconButton::enterNotifyEvent(XCrossingEvent &ev) {
int xoffset = 1;
if (m_icon_pixmap.drawable() != 0)
xoffset = m_icon_window.x() + m_icon_window.width() + 1;
if (FbTk::TextButton::textExceeds(xoffset))
m_win.screen().showTooltip(m_win.title());
}
void IconButton::leaveNotifyEvent(XCrossingEvent &ev) {
m_win.screen().hideTooltip();
}
void IconButton::moveResize(int x, int y,
unsigned int width, unsigned int height) {

View file

@ -45,6 +45,8 @@ public:
virtual ~IconButton();
void exposeEvent(XExposeEvent &event);
void enterNotifyEvent(XCrossingEvent &ce);
void leaveNotifyEvent(XCrossingEvent &ce);
void clear();
void clearArea(int x, int y,
unsigned int width, unsigned int height,

View file

@ -106,6 +106,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
RootTheme.hh RootTheme.cc \
FbRootWindow.hh FbRootWindow.cc \
OSDWindow.hh OSDWindow.cc \
TooltipWindow.hh TooltipWindow.cc \
Screen.cc Screen.hh ScreenResources.cc \
Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \
WinButton.hh WinButton.cc \

View file

@ -47,7 +47,7 @@ public:
bool isVisible() const { return m_visible; }
private:
protected:
void show();
BScreen &m_screen;

View file

@ -290,6 +290,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"),
tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"),
menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"),
gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"),
@ -343,6 +344,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
m_root_window(scrn),
m_geom_window(m_root_window, *this, *m_focused_windowtheme),
m_pos_window(m_root_window, *this, *m_focused_windowtheme),
m_tooltip_window(m_root_window, *this, *m_focused_windowtheme),
m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent,
InputOnly),
resource(rm, screenname, altscreenname),
@ -484,6 +486,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
renderGeomWindow();
renderPosWindow();
m_tooltip_window.setDelay(*resource.tooltip_delay);
// setup workspaces and workspace menu
int nr_ws = *resource.workspaces;
@ -1849,6 +1852,17 @@ void BScreen::showGeometry(int gx, int gy) {
}
void BScreen::showTooltip(const std::string &text) {
if (*resource.tooltip_delay >= 0)
m_tooltip_window.showText(text);
}
void BScreen::hideTooltip() {
if (*resource.tooltip_delay >= 0)
m_tooltip_window.hide();
}
void BScreen::hideGeometry() {
m_geom_window.hide();
}

View file

@ -30,7 +30,7 @@
#include "RootTheme.hh"
#include "WinButtonTheme.hh"
#include "FbWinFrameTheme.hh"
#include "OSDWindow.hh"
#include "TooltipWindow.hh"
#include "FbTk/MenuTheme.hh"
#include "FbTk/EventHandler.hh"
@ -389,6 +389,9 @@ public:
/// show geomentry with "width x height"-text, not size of window
void showGeometry(int width, int height);
void hideGeometry();
void showTooltip(const std::string &text);
void hideTooltip();
void setLayer(FbTk::XLayerItem &item, int layernum);
// remove? no, items are never removed from their layer until they die
@ -536,6 +539,7 @@ private:
FbRootWindow m_root_window;
OSDWindow m_geom_window, m_pos_window;
TooltipWindow m_tooltip_window;
FbTk::FbWindow m_dummy_window;
struct ScreenResource {
@ -554,7 +558,8 @@ private:
FbTk::Resource<FollowModel> follow_model, user_follow_model;
bool ordered_dither;
FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
unfocused_alpha, menu_alpha, menu_delay, menu_delay_close, tab_width;
unfocused_alpha, menu_alpha, menu_delay, menu_delay_close,
tab_width, tooltip_delay;
FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
FbTk::Resource<int> gc_line_width;

109
src/TooltipWindow.cc Normal file
View file

@ -0,0 +1,109 @@
// TooltipWindow.hh
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "TooltipWindow.hh"
#include "Screen.hh"
#include "FbWinFrameTheme.hh"
TooltipWindow::TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
FbTk::ThemeProxy<FbWinFrameTheme> &theme):
OSDWindow(parent, screen, theme),
delay(-1) {
FbTk::RefCount<FbTk::Command<void> > raisecmd(new FbTk::SimpleCommand<TooltipWindow>(*this, &TooltipWindow::raiseTooltip));
timer.setCommand(raisecmd);
timer.fireOnce(true);
}
void TooltipWindow::showText(const std::string &text) {
lastText = text.c_str();
if (delay == 0)
raiseTooltip();
else
timer.start();
}
void TooltipWindow::raiseTooltip() {
if (lastText.size() == 0)
return;
resize(lastText);
reconfigTheme();
int h = m_theme->font().height() + m_theme->bevelWidth() * 2;
int w = m_theme->font().textWidth(lastText, lastText.size()) + m_theme->bevelWidth() * 2;
Window root_ret; // not used
Window window_ret; // not used
int rx = 0, ry = 0;
int wx, wy; // not used
unsigned int mask; // not used
XQueryPointer(display(), m_screen.rootWindow().window(),
&root_ret, &window_ret, &rx, &ry, &wx, &wy, &mask);
// mouse position
int mx = rx;
int my = ry;
// center the mouse horizontally
rx -= w/2;
int yoffset = 10;
if (ry >= yoffset + h)
ry -= yoffset + h;
else
ry += yoffset;
// check that we are not out of screen
int outOfBound = rx + w - m_screen.width();
if (outOfBound > 0)
rx -= outOfBound;
if (rx < 0)
rx = 0;
moveResize(rx,ry,w, h);
show();
clear();
m_theme->font().drawText(*this, m_screen.screenNumber(),
m_theme->iconbarTheme().text().textGC(), lastText,
lastText.size(), m_theme->bevelWidth(),
m_theme->bevelWidth() + m_theme->font().ascent());
}
void TooltipWindow::show() {
if (m_visible)
return;
m_visible = true;
raise();
FbTk::FbWindow::show();
}
void TooltipWindow::hide() {
timer.stop();
OSDWindow::hide();
}

53
src/TooltipWindow.hh Normal file
View file

@ -0,0 +1,53 @@
// TooltipWindow.hh
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.#ifndef TOOLTIPWINDOW_HH_
#ifndef TOOLTIPWINDOW_HH_
#define TOOLTIPWINDOW_HH_
#include "OSDWindow.hh"
#include "FbTk/Command.hh"
#include "FbTk/RefCount.hh"
#include "FbTk/Timer.hh"
#include "FbTk/SimpleCommand.hh"
class TooltipWindow : public OSDWindow {
public:
TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
FbTk::ThemeProxy<FbWinFrameTheme> &theme);
void showText(const std::string &text);
void setDelay(int iDelay) {
delay = iDelay;
timer.setTimeout(delay);
}
void hide() ;
private:
void raiseTooltip();
void show();
int delay;
std::string lastText;
FbTk::Timer timer;
};
#endif /*TOOLTIPWINDOW_HH_*/