aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatteo Galiazzo <matteo@maltesenarrazioni.it>2008-05-05 12:05:52 (GMT)
committerMark Tiefenbruck <mark@fluxbox.org>2008-05-05 12:05:52 (GMT)
commit4a3be045b28edac4953be9f195640654f8b5a1a1 (patch)
tree4b2e6466b54a5fb4bb6406ff9cf38c420be032df /src
parentba604ac821b7c1c89d10b0e8c9f85fde948856ef (diff)
downloadfluxbox_pavel-4a3be045b28edac4953be9f195640654f8b5a1a1.zip
fluxbox_pavel-4a3be045b28edac4953be9f195640654f8b5a1a1.tar.bz2
add tooltips for iconbar buttons when title is too long to fit
Diffstat (limited to 'src')
-rw-r--r--src/FbTk/Button.cc14
-rw-r--r--src/FbTk/Button.hh2
-rw-r--r--src/FbTk/TextButton.cc23
-rw-r--r--src/FbTk/TextButton.hh2
-rw-r--r--src/IconButton.cc17
-rw-r--r--src/IconButton.hh2
-rw-r--r--src/Makefile.am1
-rw-r--r--src/OSDWindow.hh2
-rw-r--r--src/Screen.cc14
-rw-r--r--src/Screen.hh9
-rw-r--r--src/TooltipWindow.cc109
-rw-r--r--src/TooltipWindow.hh53
12 files changed, 238 insertions, 10 deletions
diff --git a/src/FbTk/Button.cc b/src/FbTk/Button.cc
index 0284fea..9edbe5c 100644
--- a/src/FbTk/Button.cc
+++ b/src/FbTk/Button.cc
@@ -30,7 +30,8 @@ namespace FbTk {
30Button::Button(int screen_num, int x, int y, 30Button::Button(int screen_num, int x, int y,
31 unsigned int width, unsigned int height): 31 unsigned int width, unsigned int height):
32 FbWindow(screen_num, x, y, width, height, 32 FbWindow(screen_num, x, y, width, height,
33 ExposureMask | ButtonPressMask | ButtonReleaseMask), 33 ExposureMask | ButtonPressMask | EnterWindowMask |
34 LeaveWindowMask | ButtonReleaseMask),
34 m_background_pm(0), 35 m_background_pm(0),
35 m_pressed_pm(0), 36 m_pressed_pm(0),
36 m_pressed_color(), 37 m_pressed_color(),
@@ -45,7 +46,8 @@ Button::Button(int screen_num, int x, int y,
45Button::Button(const FbWindow &parent, int x, int y, 46Button::Button(const FbWindow &parent, int x, int y,
46 unsigned int width, unsigned int height): 47 unsigned int width, unsigned int height):
47 FbWindow(parent, x, y, width, height, 48 FbWindow(parent, x, y, width, height,
48 ExposureMask | ButtonPressMask | ButtonReleaseMask), 49 ExposureMask | ButtonPressMask | ButtonReleaseMask |
50 EnterWindowMask | LeaveWindowMask),
49 m_background_pm(0), 51 m_background_pm(0),
50 m_pressed_pm(0), 52 m_pressed_pm(0),
51 m_pressed_color(), 53 m_pressed_color(),
@@ -90,6 +92,14 @@ void Button::setBackgroundPixmap(Pixmap pm) {
90 FbTk::FbWindow::setBackgroundPixmap(pm); 92 FbTk::FbWindow::setBackgroundPixmap(pm);
91} 93}
92 94
95
96void Button::enterNotifyEvent(XCrossingEvent &ce){
97
98}
99void Button::leaveNotifyEvent(XCrossingEvent &ce){
100
101}
102
93void Button::buttonPressEvent(XButtonEvent &event) { 103void Button::buttonPressEvent(XButtonEvent &event) {
94 bool update = false; 104 bool update = false;
95 if (m_pressed_pm != 0) { 105 if (m_pressed_pm != 0) {
diff --git a/src/FbTk/Button.hh b/src/FbTk/Button.hh
index 99d8ee9..1f65799 100644
--- a/src/FbTk/Button.hh
+++ b/src/FbTk/Button.hh
@@ -61,6 +61,8 @@ public:
61 //@{ 61 //@{
62 virtual void buttonPressEvent(XButtonEvent &event); 62 virtual void buttonPressEvent(XButtonEvent &event);
63 virtual void buttonReleaseEvent(XButtonEvent &event); 63 virtual void buttonReleaseEvent(XButtonEvent &event);
64 virtual void enterNotifyEvent(XCrossingEvent &ce);
65 virtual void leaveNotifyEvent(XCrossingEvent &ce);
64 virtual void exposeEvent(XExposeEvent &event); 66 virtual void exposeEvent(XExposeEvent &event);
65 //@} 67 //@}
66 68
diff --git a/src/FbTk/TextButton.cc b/src/FbTk/TextButton.cc
index 561fe21..f259d89 100644
--- a/src/FbTk/TextButton.cc
+++ b/src/FbTk/TextButton.cc
@@ -158,11 +158,9 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
158 translateSize(m_orientation, textw, texth); 158 translateSize(m_orientation, textw, texth);
159 159
160 int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, 160 int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
161 bevel(), 161 bevel(), justify(), font(),
162 justify(),
163 font(),
164 text().data(), text().size(), 162 text().data(), text().size(),
165 textlen); // return new text lne 163 textlen); // return new text len
166 164
167 // center text by default 165 // center text by default
168 int center_pos = texth/2 + font().ascent()/2 - 1; 166 int center_pos = texth/2 + font().ascent()/2 - 1;
@@ -183,6 +181,23 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
183 textx, texty, m_orientation); // position 181 textx, texty, m_orientation); // position
184} 182}
185 183
184
185bool TextButton::textExceeds(int x_offset) {
186
187 unsigned int textlen = text().size();
188 // do text alignment
189
190 unsigned int textw = width(), texth = height();
191 translateSize(m_orientation, textw, texth);
192
193 FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
194 bevel(), justify(), font(), text().data(), text().size(),
195 textlen); // return new text len
196
197 return text().size()>textlen;
198
199}
200
186void TextButton::exposeEvent(XExposeEvent &event) { 201void TextButton::exposeEvent(XExposeEvent &event) {
187 clearArea(event.x, event.y, event.width, event.height, false); 202 clearArea(event.x, event.y, event.width, event.height, false);
188} 203}
diff --git a/src/FbTk/TextButton.hh b/src/FbTk/TextButton.hh
index eb48e61..22cda82 100644
--- a/src/FbTk/TextButton.hh
+++ b/src/FbTk/TextButton.hh
@@ -80,6 +80,8 @@ public:
80 80
81protected: 81protected:
82 virtual void drawText(int x_offset, int y_offset, FbDrawable *drawable_override); 82 virtual void drawText(int x_offset, int y_offset, FbDrawable *drawable_override);
83 // return true if the text will be truncated
84 bool textExceeds(int x_offset);
83 85
84private: 86private:
85 FbTk::Font *m_font; 87 FbTk::Font *m_font;
diff --git a/src/IconButton.cc b/src/IconButton.cc
index 09791c8..6b8118e 100644
--- a/src/IconButton.cc
+++ b/src/IconButton.cc
@@ -52,7 +52,8 @@ IconButton::IconButton(const FbTk::FbWindow &parent,
52 FbTk::TextButton(parent, focused_theme->text().font(), win.title()), 52 FbTk::TextButton(parent, focused_theme->text().font(), win.title()),
53 m_win(win), 53 m_win(win),
54 m_icon_window(*this, 1, 1, 1, 1, 54 m_icon_window(*this, 1, 1, 1, 1,
55 ExposureMask | ButtonPressMask | ButtonReleaseMask), 55 ExposureMask |EnterWindowMask | LeaveWindowMask |
56 ButtonPressMask | ButtonReleaseMask),
56 m_use_pixmap(true), 57 m_use_pixmap(true),
57 m_theme(win, focused_theme, unfocused_theme), 58 m_theme(win, focused_theme, unfocused_theme),
58 m_pm(win.screen().imageControl()) { 59 m_pm(win.screen().imageControl()) {
@@ -79,6 +80,20 @@ void IconButton::exposeEvent(XExposeEvent &event) {
79 FbTk::TextButton::exposeEvent(event); 80 FbTk::TextButton::exposeEvent(event);
80} 81}
81 82
83void IconButton::enterNotifyEvent(XCrossingEvent &ev) {
84
85 int xoffset = 1;
86 if (m_icon_pixmap.drawable() != 0)
87 xoffset = m_icon_window.x() + m_icon_window.width() + 1;
88
89 if (FbTk::TextButton::textExceeds(xoffset))
90 m_win.screen().showTooltip(m_win.title());
91}
92
93void IconButton::leaveNotifyEvent(XCrossingEvent &ev) {
94 m_win.screen().hideTooltip();
95}
96
82void IconButton::moveResize(int x, int y, 97void IconButton::moveResize(int x, int y,
83 unsigned int width, unsigned int height) { 98 unsigned int width, unsigned int height) {
84 99
diff --git a/src/IconButton.hh b/src/IconButton.hh
index b80a29b..bb41b8b 100644
--- a/src/IconButton.hh
+++ b/src/IconButton.hh
@@ -45,6 +45,8 @@ public:
45 virtual ~IconButton(); 45 virtual ~IconButton();
46 46
47 void exposeEvent(XExposeEvent &event); 47 void exposeEvent(XExposeEvent &event);
48 void enterNotifyEvent(XCrossingEvent &ce);
49 void leaveNotifyEvent(XCrossingEvent &ce);
48 void clear(); 50 void clear();
49 void clearArea(int x, int y, 51 void clearArea(int x, int y,
50 unsigned int width, unsigned int height, 52 unsigned int width, unsigned int height,
diff --git a/src/Makefile.am b/src/Makefile.am
index 0fc5a7a..337b99c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -106,6 +106,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
106 RootTheme.hh RootTheme.cc \ 106 RootTheme.hh RootTheme.cc \
107 FbRootWindow.hh FbRootWindow.cc \ 107 FbRootWindow.hh FbRootWindow.cc \
108 OSDWindow.hh OSDWindow.cc \ 108 OSDWindow.hh OSDWindow.cc \
109 TooltipWindow.hh TooltipWindow.cc \
109 Screen.cc Screen.hh ScreenResources.cc \ 110 Screen.cc Screen.hh ScreenResources.cc \
110 Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \ 111 Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \
111 WinButton.hh WinButton.cc \ 112 WinButton.hh WinButton.cc \
diff --git a/src/OSDWindow.hh b/src/OSDWindow.hh
index 3fd5c42..e11a531 100644
--- a/src/OSDWindow.hh
+++ b/src/OSDWindow.hh
@@ -47,7 +47,7 @@ public:
47 47
48 bool isVisible() const { return m_visible; } 48 bool isVisible() const { return m_visible; }
49 49
50private: 50protected:
51 void show(); 51 void show();
52 52
53 BScreen &m_screen; 53 BScreen &m_screen;
diff --git a/src/Screen.cc b/src/Screen.cc
index 7950b83..f817e6b 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -290,6 +290,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
290 menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"), 290 menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
291 menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"), 291 menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
292 tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"), 292 tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"),
293 tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"),
293 menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"), 294 menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"),
294 295
295 gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"), 296 gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"),
@@ -343,6 +344,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
343 m_root_window(scrn), 344 m_root_window(scrn),
344 m_geom_window(m_root_window, *this, *m_focused_windowtheme), 345 m_geom_window(m_root_window, *this, *m_focused_windowtheme),
345 m_pos_window(m_root_window, *this, *m_focused_windowtheme), 346 m_pos_window(m_root_window, *this, *m_focused_windowtheme),
347 m_tooltip_window(m_root_window, *this, *m_focused_windowtheme),
346 m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent, 348 m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent,
347 InputOnly), 349 InputOnly),
348 resource(rm, screenname, altscreenname), 350 resource(rm, screenname, altscreenname),
@@ -484,6 +486,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
484 486
485 renderGeomWindow(); 487 renderGeomWindow();
486 renderPosWindow(); 488 renderPosWindow();
489 m_tooltip_window.setDelay(*resource.tooltip_delay);
487 490
488 // setup workspaces and workspace menu 491 // setup workspaces and workspace menu
489 int nr_ws = *resource.workspaces; 492 int nr_ws = *resource.workspaces;
@@ -1849,6 +1852,17 @@ void BScreen::showGeometry(int gx, int gy) {
1849} 1852}
1850 1853
1851 1854
1855void BScreen::showTooltip(const std::string &text) {
1856 if (*resource.tooltip_delay >= 0)
1857 m_tooltip_window.showText(text);
1858}
1859
1860void BScreen::hideTooltip() {
1861 if (*resource.tooltip_delay >= 0)
1862 m_tooltip_window.hide();
1863}
1864
1865
1852void BScreen::hideGeometry() { 1866void BScreen::hideGeometry() {
1853 m_geom_window.hide(); 1867 m_geom_window.hide();
1854} 1868}
diff --git a/src/Screen.hh b/src/Screen.hh
index d42fea0..cf8bf1f 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -30,7 +30,7 @@
30#include "RootTheme.hh" 30#include "RootTheme.hh"
31#include "WinButtonTheme.hh" 31#include "WinButtonTheme.hh"
32#include "FbWinFrameTheme.hh" 32#include "FbWinFrameTheme.hh"
33#include "OSDWindow.hh" 33#include "TooltipWindow.hh"
34 34
35#include "FbTk/MenuTheme.hh" 35#include "FbTk/MenuTheme.hh"
36#include "FbTk/EventHandler.hh" 36#include "FbTk/EventHandler.hh"
@@ -389,6 +389,9 @@ public:
389 /// show geomentry with "width x height"-text, not size of window 389 /// show geomentry with "width x height"-text, not size of window
390 void showGeometry(int width, int height); 390 void showGeometry(int width, int height);
391 void hideGeometry(); 391 void hideGeometry();
392
393 void showTooltip(const std::string &text);
394 void hideTooltip();
392 395
393 void setLayer(FbTk::XLayerItem &item, int layernum); 396 void setLayer(FbTk::XLayerItem &item, int layernum);
394 // remove? no, items are never removed from their layer until they die 397 // remove? no, items are never removed from their layer until they die
@@ -536,6 +539,7 @@ private:
536 539
537 FbRootWindow m_root_window; 540 FbRootWindow m_root_window;
538 OSDWindow m_geom_window, m_pos_window; 541 OSDWindow m_geom_window, m_pos_window;
542 TooltipWindow m_tooltip_window;
539 FbTk::FbWindow m_dummy_window; 543 FbTk::FbWindow m_dummy_window;
540 544
541 struct ScreenResource { 545 struct ScreenResource {
@@ -554,7 +558,8 @@ private:
554 FbTk::Resource<FollowModel> follow_model, user_follow_model; 558 FbTk::Resource<FollowModel> follow_model, user_follow_model;
555 bool ordered_dither; 559 bool ordered_dither;
556 FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha, 560 FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
557 unfocused_alpha, menu_alpha, menu_delay, menu_delay_close, tab_width; 561 unfocused_alpha, menu_alpha, menu_delay, menu_delay_close,
562 tab_width, tooltip_delay;
558 FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode; 563 FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
559 564
560 FbTk::Resource<int> gc_line_width; 565 FbTk::Resource<int> gc_line_width;
diff --git a/src/TooltipWindow.cc b/src/TooltipWindow.cc
new file mode 100644
index 0000000..025cc68
--- /dev/null
+++ b/src/TooltipWindow.cc
@@ -0,0 +1,109 @@
1// TooltipWindow.hh
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22
23#include "TooltipWindow.hh"
24#include "Screen.hh"
25#include "FbWinFrameTheme.hh"
26
27
28TooltipWindow::TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
29 FbTk::ThemeProxy<FbWinFrameTheme> &theme):
30 OSDWindow(parent, screen, theme),
31 delay(-1) {
32
33 FbTk::RefCount<FbTk::Command<void> > raisecmd(new FbTk::SimpleCommand<TooltipWindow>(*this, &TooltipWindow::raiseTooltip));
34 timer.setCommand(raisecmd);
35 timer.fireOnce(true);
36
37}
38
39void TooltipWindow::showText(const std::string &text) {
40
41 lastText = text.c_str();
42 if (delay == 0)
43 raiseTooltip();
44 else
45 timer.start();
46
47}
48
49void TooltipWindow::raiseTooltip() {
50
51 if (lastText.size() == 0)
52 return;
53
54 resize(lastText);
55 reconfigTheme();
56 int h = m_theme->font().height() + m_theme->bevelWidth() * 2;
57 int w = m_theme->font().textWidth(lastText, lastText.size()) + m_theme->bevelWidth() * 2;
58
59 Window root_ret; // not used
60 Window window_ret; // not used
61 int rx = 0, ry = 0;
62 int wx, wy; // not used
63 unsigned int mask; // not used
64
65 XQueryPointer(display(), m_screen.rootWindow().window(),
66 &root_ret, &window_ret, &rx, &ry, &wx, &wy, &mask);
67
68 // mouse position
69 int mx = rx;
70 int my = ry;
71
72 // center the mouse horizontally
73 rx -= w/2;
74 int yoffset = 10;
75 if (ry >= yoffset + h)
76 ry -= yoffset + h;
77 else
78 ry += yoffset;
79
80 // check that we are not out of screen
81 int outOfBound = rx + w - m_screen.width();
82 if (outOfBound > 0)
83 rx -= outOfBound;
84 if (rx < 0)
85 rx = 0;
86
87 moveResize(rx,ry,w, h);
88
89 show();
90 clear();
91 m_theme->font().drawText(*this, m_screen.screenNumber(),
92 m_theme->iconbarTheme().text().textGC(), lastText,
93 lastText.size(), m_theme->bevelWidth(),
94 m_theme->bevelWidth() + m_theme->font().ascent());
95}
96
97
98void TooltipWindow::show() {
99 if (m_visible)
100 return;
101 m_visible = true;
102 raise();
103 FbTk::FbWindow::show();
104}
105
106void TooltipWindow::hide() {
107 timer.stop();
108 OSDWindow::hide();
109}
diff --git a/src/TooltipWindow.hh b/src/TooltipWindow.hh
new file mode 100644
index 0000000..03abc1d
--- /dev/null
+++ b/src/TooltipWindow.hh
@@ -0,0 +1,53 @@
1// TooltipWindow.hh
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.#ifndef TOOLTIPWINDOW_HH_
21#ifndef TOOLTIPWINDOW_HH_
22#define TOOLTIPWINDOW_HH_
23
24#include "OSDWindow.hh"
25#include "FbTk/Command.hh"
26#include "FbTk/RefCount.hh"
27#include "FbTk/Timer.hh"
28#include "FbTk/SimpleCommand.hh"
29
30
31class TooltipWindow : public OSDWindow {
32public:
33 TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
34 FbTk::ThemeProxy<FbWinFrameTheme> &theme);
35
36 void showText(const std::string &text);
37 void setDelay(int iDelay) {
38 delay = iDelay;
39 timer.setTimeout(delay);
40 }
41 void hide() ;
42
43private:
44 void raiseTooltip();
45 void show();
46 int delay;
47 std::string lastText;
48 FbTk::Timer timer;
49};
50
51
52
53#endif /*TOOLTIPWINDOW_HH_*/