add tooltips for iconbar buttons when title is too long to fit
This commit is contained in:
parent
ba604ac821
commit
4a3be045b2
13 changed files with 241 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
|
||||
bool isVisible() const { return m_visible; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
void show();
|
||||
|
||||
BScreen &m_screen;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -390,6 +390,9 @@ public:
|
|||
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
109
src/TooltipWindow.cc
Normal 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
53
src/TooltipWindow.hh
Normal 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_*/
|
Loading…
Reference in a new issue