menu delay and mode

This commit is contained in:
fluxgen 2003-12-12 18:18:49 +00:00
parent 624fd1e121
commit bf75608df0
6 changed files with 170 additions and 35 deletions

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Menu.cc,v 1.45 2003/12/10 23:33:15 fluxgen Exp $
// $Id: Menu.cc,v 1.46 2003/12/12 18:18:49 fluxgen Exp $
//use GNU extensions
#ifndef _GNU_SOURCE
@ -37,6 +37,7 @@
#include "App.hh"
#include "EventManager.hh"
#include "Transparent.hh"
#include "SimpleCommand.hh"
#include <X11/Xatom.h>
#include <X11/keysym.h>
@ -65,6 +66,17 @@ Menu::Menu(MenuTheme &tm, ImageControl &imgctrl):
m_themeobserver(*this),
m_need_update(true) {
// setup timers
RefCount<Command> show_cmd(new SimpleCommand<Menu>(*this, &Menu::openSubmenu));
m_submenu_timer.setCommand(show_cmd);
m_submenu_timer.fireOnce(true);
RefCount<Command> hide_cmd(new SimpleCommand<Menu>(*this, &Menu::closeMenu));
m_hide_timer.setCommand(hide_cmd);
m_hide_timer.fireOnce(true);
// make sure we get updated when the theme is reloaded
tm.addListener(m_themeobserver);
@ -673,7 +685,7 @@ void Menu::drawSubmenu(unsigned int index) {
if (m_alignment == ALIGNBOTTOM &&
(y + item->submenu()->height()) > ((shifted) ? menu.y_shift :
menu.y) + height()) {
menu.y) + height()) {
y = (((shifted) ? menu.y_shift : menu.y) +
height() - item->submenu()->height());
}
@ -864,23 +876,23 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
}
} else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) {
// enable clip mask
XSetClipMask(FbTk::App::instance()->display(),
gc,
m_theme.unselectedPixmap().mask().drawable());
XSetClipOrigin(FbTk::App::instance()->display(),
gc, sel_x, item_y);
// copy bullet pixmap to frame
m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(),
gc,
0, 0,
sel_x, item_y,
m_theme.unselectedPixmap().width(),
m_theme.unselectedPixmap().height());
// disable clip mask
XSetClipMask(FbTk::App::instance()->display(),
gc,
None);
// enable clip mask
XSetClipMask(FbTk::App::instance()->display(),
gc,
m_theme.unselectedPixmap().mask().drawable());
XSetClipOrigin(FbTk::App::instance()->display(),
gc, sel_x, item_y);
// copy bullet pixmap to frame
m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(),
gc,
0, 0,
sel_x, item_y,
m_theme.unselectedPixmap().width(),
m_theme.unselectedPixmap().height());
// disable clip mask
XSetClipMask(FbTk::App::instance()->display(),
gc,
None);
}
if (dotext && text) {
@ -1109,6 +1121,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
void Menu::motionNotifyEvent(XMotionEvent &me) {
m_hide_timer.stop();
if (me.window == menu.title && (me.state & Button1Mask)) {
if (movable) {
if (! moving) {
@ -1128,7 +1141,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
menu.window.move(menu.x, menu.y);
// if (which_sub >= 0)
// drawSubmenu(which_sub);
// drawSubmenu(which_sub);
}
}
} else if ((! (me.state & Button1Mask)) && me.window == menu.frame &&
@ -1139,21 +1152,28 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
if ((i != which_press || sbl != which_sbl) &&
(w < static_cast<int>(menuitems.size()) && w >= 0)) {
if (which_press != -1 && which_sbl != -1) {
int p = which_sbl * menu.persub + which_press;
MenuItem *item = menuitems[p];
// don't redraw disabled items on enter/leave
if (item->isEnabled()) {
if (item != 0 && item->isEnabled()) {
drawItem(p, false, true, true);
if (item->submenu()) {
if (item->submenu()->isVisible() &&
(! item->submenu()->isTorn())) {
item->submenu()->internal_hide();
!item->submenu()->isTorn()) {
which_sub = -1;
// setup hide timer for submenu
item->submenu()->startHide();
}
}
}
}
which_press = i;
@ -1162,11 +1182,27 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
MenuItem *itmp = menuitems[w];
if (itmp->submenu()) {
if (!itmp->submenu()->isVisible())
drawSubmenu(w);
} else
drawItem(w, true);
if (theme().menuMode() == MenuTheme::DELAY_OPEN) {
cerr<<"menuMode DELAY_OPEN"<<endl;
// setup show menu timer
stopHide();
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = theme().delayOpen();
m_submenu_timer.setTimeout(timeout);
m_submenu_timer.start();
}
} else {
m_submenu_timer.stop();
if (itmp->isEnabled())
drawItem(w, true, true, true);
}
}
}
}
@ -1347,4 +1383,39 @@ void Menu::renderTransFrame() {
menu.frame.updateTransparent();
}
void Menu::openSubmenu() {
if (!isVisible() || which_press < 0 || which_press >= menuitems.size() ||
which_sbl < 0 || which_sbl >= menuitems.size())
return;
int item = which_sbl * menu.persub + which_press;
if (item < 0 || item >= menuitems.size())
return;
stopHide();
if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible())
drawSubmenu(item);
}
void Menu::closeMenu() {
if (isVisible() &&
!isTorn()) {
internal_hide();
}
}
void Menu::startHide() {
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = theme().delayClose();
m_hide_timer.setTimeout(timeout);
m_hide_timer.start();
}
void Menu::stopHide() {
m_hide_timer.stop();
}
}; // end namespace FbTk

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Menu.hh,v 1.25 2003/12/10 23:08:06 fluxgen Exp $
// $Id: Menu.hh,v 1.26 2003/12/12 18:18:49 fluxgen Exp $
#ifndef FBTK_MENU_HH
#define FBTK_MENU_HH
@ -39,6 +39,7 @@
#include "Observer.hh"
#include "FbPixmap.hh"
#include "MenuTheme.hh"
#include "Timer.hh"
namespace FbTk {
@ -174,6 +175,11 @@ protected:
inline const Menu *parent() const { return m_parent; }
private:
void openSubmenu();
void closeMenu();
void startHide();
void stopHide();
void renderTransFrame();
typedef std::vector<MenuItem *> Menuitems;
@ -215,6 +221,8 @@ private:
static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused
FbPixmap m_frame_pm;
bool m_need_update;
Timer m_submenu_timer;
Timer m_hide_timer;
};
}; // end namespace FbTk

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: MenuTheme.cc,v 1.11 2003/09/12 23:32:02 fluxgen Exp $
// $Id: MenuTheme.cc,v 1.12 2003/12/12 18:18:49 fluxgen Exp $
#include "MenuTheme.hh"
@ -60,6 +60,9 @@ MenuTheme::MenuTheme(int screen_num):
h_text_gc(RootWindow(m_display, screen_num)),
d_text_gc(RootWindow(m_display, screen_num)),
hilite_gc(RootWindow(m_display, screen_num)),
m_menumode(DELAY_OPEN),
m_delayopen(0), // no delay as default
m_delayclose(0), // no delay as default
m_alpha(255) {
// set default values

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: MenuTheme.hh,v 1.10 2003/11/28 22:53:10 fluxgen Exp $
// $Id: MenuTheme.hh,v 1.11 2003/12/12 18:18:49 fluxgen Exp $
#ifndef FBTK_MENUTHEME_HH
#define FBTK_MENUTHEME_HH
@ -37,6 +37,11 @@ namespace FbTk {
class MenuTheme:public FbTk::Theme {
public:
//!! TODO
// this isn't actually used with a theme item
// see setMenuMode() for more info
enum MenuMode {CLICK_OPEN, DELAY_OPEN};
enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND};
MenuTheme(int screen_num);
virtual ~MenuTheme();
@ -102,7 +107,16 @@ public:
inline unsigned char alpha() const { return m_alpha; }
void setAlpha(unsigned char alpha) { m_alpha = alpha; }
// this isn't actually a theme item
// but we'll let it be here for now, until there's a better way to
// get resources into menu
void setMenuMode(MenuMode mode) { m_menumode = mode; }
MenuMode menuMode() const { return m_menumode; }
void setDelayOpen(int usec) { m_delayopen = usec; }
void setDelayClose(int usec) { m_delayclose = usec; }
int delayOpen() const { return m_delayopen; }
int delayClose() const { return m_delayclose; }
const FbTk::Color &borderColor() const { return *m_border_color; }
FbTk::Subject &themeChangeSig() { return m_theme_change_sig; }
/// attach observer
@ -126,6 +140,10 @@ private:
FbTk::Subject m_theme_change_sig;
unsigned char m_alpha;
MenuMode m_menumode;
unsigned int m_delayopen; ///< in usec
unsigned int m_delayclose; ///< in usec
};
}; // end namespace FbTk

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.cc,v 1.247 2003/12/10 23:08:03 fluxgen Exp $
// $Id: Screen.cc,v 1.248 2003/12/12 18:18:12 fluxgen Exp $
#include "Screen.hh"
@ -154,7 +154,31 @@ private:
}; // End anonymous namespace
template <>
void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setDefaultValue() {
*(*this) = FbTk::MenuTheme::DELAY_OPEN;
}
template <>
string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() {
switch (*(*this)) {
case FbTk::MenuTheme::DELAY_OPEN:
return string("Delay");
case FbTk::MenuTheme::CLICK_OPEN:
return string("Click");
}
return string("Delay");
}
template <>
void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setFromString(const char *str) {
if (strcasecmp(str, "Delay") == 0)
*(*this) = FbTk::MenuTheme::DELAY_OPEN;
else if (strcasecmp(str, "Click") == 0)
*(*this) = FbTk::MenuTheme::CLICK_OPEN;
else
setDefaultValue();
}
namespace {
@ -222,7 +246,10 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"),
workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"),
edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha") {
menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha"),
menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode") {
};
@ -307,6 +334,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
m_menutheme->setAlpha(*resource.menu_alpha);
m_menutheme->setMenuMode(*resource.menu_mode);
m_menutheme->setDelayOpen(*resource.menu_delay);
m_menutheme->setDelayClose(*resource.menu_delay_close);
imageControl().setDither(*resource.image_dither);
@ -570,6 +600,10 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) {
void BScreen::reconfigure() {
m_menutheme->setAlpha(*resource.menu_alpha);
m_menutheme->setMenuMode(*resource.menu_mode);
m_menutheme->setDelayOpen(*resource.menu_delay);
m_menutheme->setDelayClose(*resource.menu_delay_close);
Fluxbox::instance()->loadRootCommand(*this);
// setup windowtheme, toolbartheme for antialias

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.hh,v 1.126 2003/12/10 23:08:03 fluxgen Exp $
// $Id: Screen.hh,v 1.127 2003/12/12 18:18:12 fluxgen Exp $
#ifndef SCREEN_HH
#define SCREEN_HH
@ -430,7 +430,8 @@ private:
FbTk::Resource<std::string> resizemode;
FbTk::Resource<Fluxbox::FocusModel> focus_model;
bool ordered_dither;
FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha;
FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha, menu_delay, menu_delay_close;
FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
int placement_policy, row_direction, col_direction;