2002-12-25 11:46:50 +00:00
|
|
|
// Menu.hh for FbTk - Fluxbox Toolkit
|
2005-01-24 18:02:34 +00:00
|
|
|
// Copyright (c) 2001 - 2004 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
2002-12-25 11:46:50 +00:00
|
|
|
//
|
|
|
|
// Basemenu.hh for Blackbox - an X11 Window manager
|
|
|
|
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2007-12-30 15:32:53 +00:00
|
|
|
#ifndef FBTK_MENU_HH
|
|
|
|
#define FBTK_MENU_HH
|
2002-12-25 11:46:50 +00:00
|
|
|
|
|
|
|
#include <vector>
|
2003-04-20 14:20:14 +00:00
|
|
|
#include <memory>
|
2002-12-25 11:46:50 +00:00
|
|
|
|
2007-12-30 15:32:53 +00:00
|
|
|
#include "FbString.hh"
|
2002-12-25 11:46:50 +00:00
|
|
|
#include "FbWindow.hh"
|
|
|
|
#include "EventHandler.hh"
|
2003-02-15 01:48:16 +00:00
|
|
|
#include "Observer.hh"
|
2003-07-19 03:59:56 +00:00
|
|
|
#include "MenuTheme.hh"
|
2003-12-12 18:18:49 +00:00
|
|
|
#include "Timer.hh"
|
2007-03-03 19:35:34 +00:00
|
|
|
#include "TypeAhead.hh"
|
2002-12-25 11:46:50 +00:00
|
|
|
|
|
|
|
namespace FbTk {
|
|
|
|
|
2008-01-11 07:41:22 +00:00
|
|
|
class Command<class T>;
|
2002-12-25 11:46:50 +00:00
|
|
|
class MenuItem;
|
2003-01-10 00:46:54 +00:00
|
|
|
class ImageControl;
|
2007-12-30 06:44:11 +00:00
|
|
|
class RefCount<class T>;
|
2002-12-25 11:46:50 +00:00
|
|
|
|
2003-01-07 02:09:43 +00:00
|
|
|
/// Base class for menus
|
2007-10-13 21:51:37 +00:00
|
|
|
class Menu: public FbTk::EventHandler, FbTk::FbWindowRenderer,
|
|
|
|
public FbTk::Observer {
|
2002-12-25 11:46:50 +00:00
|
|
|
public:
|
|
|
|
enum Alignment{ ALIGNDONTCARE = 1, ALIGNTOP, ALIGNBOTTOM };
|
|
|
|
enum { RIGHT = 1, LEFT };
|
2007-12-29 21:38:53 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
/**
|
|
|
|
Bullet type
|
|
|
|
*/
|
|
|
|
enum { EMPTY = 0, SQUARE, TRIANGLE, DIAMOND };
|
2007-12-29 21:38:53 +00:00
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
Menu(FbTk::ThemeProxy<MenuTheme> &tm, ImageControl &imgctrl);
|
2002-12-25 11:46:50 +00:00
|
|
|
virtual ~Menu();
|
|
|
|
|
|
|
|
/**
|
|
|
|
@name manipulators
|
|
|
|
*/
|
|
|
|
//@{
|
|
|
|
/// add a menu item with a label and a command
|
2008-01-11 07:41:22 +00:00
|
|
|
int insert(const FbString &label, RefCount<Command<void> > &cmd, int pos=-1);
|
2003-01-09 16:43:54 +00:00
|
|
|
/// add empty menu item
|
2006-05-20 15:08:14 +00:00
|
|
|
int insert(const FbString &label, int pos=-1);
|
2002-12-25 11:46:50 +00:00
|
|
|
/// add submenu
|
2006-05-20 15:08:14 +00:00
|
|
|
int insert(const FbString &label, Menu *submenu, int pos= -1);
|
2003-01-12 17:02:33 +00:00
|
|
|
/// add menu item
|
|
|
|
int insert(MenuItem *item, int pos=-1);
|
2003-01-07 02:09:43 +00:00
|
|
|
/// remove an item
|
2002-12-25 11:46:50 +00:00
|
|
|
int remove(unsigned int item);
|
2003-01-07 02:09:43 +00:00
|
|
|
/// remove all items
|
|
|
|
void removeAll();
|
2007-12-29 21:38:53 +00:00
|
|
|
void setInternalMenu(bool val = true) { m_internal_menu = val; }
|
|
|
|
void setAlignment(Alignment a) { m_alignment = a; }
|
2008-08-16 12:54:07 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
/// raise this window
|
2003-02-03 13:40:52 +00:00
|
|
|
virtual void raise();
|
2002-12-25 11:46:50 +00:00
|
|
|
/// lower this window
|
2003-02-03 13:40:52 +00:00
|
|
|
virtual void lower();
|
2007-03-03 19:35:34 +00:00
|
|
|
/// cycle through menuitems
|
|
|
|
void cycleItems(bool reverse);
|
2009-08-08 17:20:45 +00:00
|
|
|
/// set and highlight new active index
|
|
|
|
void setActiveIndex(int new_index);
|
2003-07-03 12:23:28 +00:00
|
|
|
void enterSubmenu();
|
2003-02-02 16:32:41 +00:00
|
|
|
|
2003-01-07 02:09:43 +00:00
|
|
|
void disableTitle();
|
|
|
|
void enableTitle();
|
2003-04-20 13:49:26 +00:00
|
|
|
|
2004-09-11 13:45:16 +00:00
|
|
|
void setScreen(int x, int y, int w, int h);
|
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
/**
|
|
|
|
@name event handlers
|
|
|
|
*/
|
|
|
|
//@{
|
2003-07-02 05:26:45 +00:00
|
|
|
void handleEvent(XEvent &event);
|
2002-12-25 11:46:50 +00:00
|
|
|
void buttonPressEvent(XButtonEvent &bp);
|
2007-06-03 23:51:11 +00:00
|
|
|
virtual void buttonReleaseEvent(XButtonEvent &br);
|
2002-12-25 11:46:50 +00:00
|
|
|
void motionNotifyEvent(XMotionEvent &mn);
|
|
|
|
void exposeEvent(XExposeEvent &ee);
|
2003-07-02 05:26:45 +00:00
|
|
|
void keyPressEvent(XKeyEvent &ke);
|
2008-02-09 02:36:06 +00:00
|
|
|
void leaveNotifyEvent(XCrossingEvent &ce);
|
2002-12-25 11:46:50 +00:00
|
|
|
//@}
|
2003-07-02 05:26:45 +00:00
|
|
|
/// get input focus
|
|
|
|
void grabInputFocus();
|
2003-07-10 11:55:49 +00:00
|
|
|
virtual void reconfigure();
|
2002-12-25 11:46:50 +00:00
|
|
|
/// set label string
|
2006-05-20 15:08:14 +00:00
|
|
|
void setLabel(const FbString &labelstr);
|
2002-12-25 11:46:50 +00:00
|
|
|
/// move menu to x,y
|
2007-01-07 11:55:14 +00:00
|
|
|
virtual void move(int x, int y);
|
2008-09-22 05:32:02 +00:00
|
|
|
virtual void updateMenu();
|
2002-12-25 11:46:50 +00:00
|
|
|
void setItemSelected(unsigned int index, bool val);
|
|
|
|
void setItemEnabled(unsigned int index, bool val);
|
2007-12-29 21:38:53 +00:00
|
|
|
void setMinimumSublevels(int m) { menu.minsub = m; }
|
2002-12-25 11:46:50 +00:00
|
|
|
virtual void drawSubmenu(unsigned int index);
|
|
|
|
/// show menu
|
|
|
|
virtual void show();
|
|
|
|
/// hide menu
|
2007-12-18 06:52:30 +00:00
|
|
|
virtual void hide(bool force = false);
|
2003-02-23 00:59:13 +00:00
|
|
|
virtual void clearWindow();
|
2002-12-25 11:46:50 +00:00
|
|
|
/*@}*/
|
2007-12-29 21:38:53 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
/**
|
|
|
|
@name accessors
|
|
|
|
*/
|
|
|
|
//@{
|
2007-12-29 21:38:53 +00:00
|
|
|
bool isTorn() const { return m_torn; }
|
|
|
|
bool isVisible() const { return m_visible; }
|
|
|
|
bool isMoving() const { return m_moving; }
|
|
|
|
int screenNumber() const { return menu.window.screenNumber(); }
|
|
|
|
Window window() const { return menu.window.window(); }
|
|
|
|
FbWindow &fbwindow() { return menu.window; }
|
|
|
|
const FbWindow &fbwindow() const { return menu.window; }
|
|
|
|
FbWindow &titleWindow() { return menu.title; }
|
|
|
|
FbWindow &frameWindow() { return menu.frame; }
|
|
|
|
const std::string &label() const { return menu.label; }
|
|
|
|
int x() const { return menu.window.x(); }
|
|
|
|
int y() const { return menu.window.y(); }
|
|
|
|
unsigned int width() const { return menu.window.width(); }
|
|
|
|
unsigned int height() const { return menu.window.height(); }
|
|
|
|
size_t numberOfItems() const { return menuitems.size(); }
|
|
|
|
int currentSubmenu() const { return m_which_sub; }
|
2007-02-28 19:13:59 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
bool isItemSelected(unsigned int index) const;
|
|
|
|
bool isItemEnabled(unsigned int index) const;
|
2004-08-03 21:25:51 +00:00
|
|
|
bool isItemSelectable(unsigned int index) const;
|
2008-01-05 01:39:19 +00:00
|
|
|
FbTk::ThemeProxy<MenuTheme> &theme() { return m_theme; }
|
|
|
|
const FbTk::ThemeProxy<MenuTheme> &theme() const { return m_theme; }
|
|
|
|
unsigned char alpha() const { return theme()->alpha(); }
|
2007-12-29 21:38:53 +00:00
|
|
|
static Menu *shownMenu() { return shown; }
|
|
|
|
static Menu *focused() { return s_focused; }
|
2007-12-18 05:09:20 +00:00
|
|
|
static void hideShownMenu();
|
2003-05-13 00:24:00 +00:00
|
|
|
/// @return menuitem at index
|
2007-12-29 21:38:53 +00:00
|
|
|
const MenuItem *find(unsigned int index) const { return menuitems[index]; }
|
|
|
|
MenuItem *find(unsigned int index) { return menuitems[index]; }
|
2002-12-25 11:46:50 +00:00
|
|
|
//@}
|
2004-06-27 13:51:24 +00:00
|
|
|
/// @return true if index is valid
|
2007-12-29 21:38:53 +00:00
|
|
|
bool validIndex(int index) const { return (index < static_cast<int>(numberOfItems()) && index >= 0); }
|
2002-12-25 11:46:50 +00:00
|
|
|
|
2007-12-29 21:38:53 +00:00
|
|
|
Menu *parent() { return m_parent; }
|
|
|
|
const Menu *parent() const { return m_parent; }
|
2004-08-29 12:35:29 +00:00
|
|
|
|
2005-04-26 01:41:55 +00:00
|
|
|
void renderForeground(FbWindow &win, FbDrawable &drawable);
|
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
protected:
|
|
|
|
|
2007-12-29 21:38:53 +00:00
|
|
|
void setTitleVisibility(bool b) {
|
|
|
|
m_title_vis = b; m_need_update = true;
|
2004-06-14 12:23:57 +00:00
|
|
|
if (!b)
|
|
|
|
titleWindow().lower();
|
|
|
|
else
|
|
|
|
titleWindow().raise();
|
|
|
|
}
|
2003-01-12 17:02:33 +00:00
|
|
|
|
2005-04-26 01:41:55 +00:00
|
|
|
// renders item onto pm
|
|
|
|
int drawItem(FbDrawable &pm, unsigned int index,
|
|
|
|
bool highlight = false,
|
|
|
|
bool exclusive_drawable = false);
|
2007-03-03 19:35:34 +00:00
|
|
|
void clearItem(int index, bool clear = true, int search_index = -1);
|
2005-04-26 01:41:55 +00:00
|
|
|
void highlightItem(int index);
|
|
|
|
virtual void redrawTitle(FbDrawable &pm);
|
|
|
|
virtual void redrawFrame(FbDrawable &pm);
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2007-07-07 01:56:46 +00:00
|
|
|
virtual void internal_hide(bool first = true);
|
2002-12-25 11:46:50 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
virtual void update(FbTk::Subject *);
|
2005-04-10 18:18:14 +00:00
|
|
|
|
2007-12-29 21:38:53 +00:00
|
|
|
private:
|
2003-12-17 00:43:22 +00:00
|
|
|
|
2003-12-12 18:18:49 +00:00
|
|
|
void openSubmenu();
|
|
|
|
void closeMenu();
|
|
|
|
void startHide();
|
|
|
|
void stopHide();
|
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
FbTk::ThemeProxy<MenuTheme> &m_theme;
|
2002-12-25 11:46:50 +00:00
|
|
|
Menu *m_parent;
|
2003-01-10 00:46:54 +00:00
|
|
|
ImageControl &m_image_ctrl;
|
2002-12-25 11:46:50 +00:00
|
|
|
|
2007-12-28 09:14:19 +00:00
|
|
|
typedef std::vector<MenuItem *> Menuitems;
|
|
|
|
Menuitems menuitems;
|
2007-03-03 19:35:34 +00:00
|
|
|
TypeAhead<Menuitems, MenuItem *> m_type_ahead;
|
|
|
|
Menuitems m_matches;
|
|
|
|
|
|
|
|
void resetTypeAhead();
|
|
|
|
void drawTypeAheadItems();
|
|
|
|
void drawLine(int index, int size);
|
|
|
|
void fixMenuItemIndices();
|
|
|
|
|
2004-09-11 13:45:16 +00:00
|
|
|
int m_screen_x, m_screen_y;
|
2006-04-16 11:18:22 +00:00
|
|
|
unsigned int m_screen_width, m_screen_height;
|
2005-01-15 13:35:48 +00:00
|
|
|
bool m_moving; ///< if we're moving/draging or not
|
2007-07-15 16:32:54 +00:00
|
|
|
bool m_closing; ///< if we're right clicking on the menu title
|
2005-01-15 13:35:48 +00:00
|
|
|
bool m_visible; ///< menu visibility
|
|
|
|
bool m_torn; ///< torn from parent
|
|
|
|
bool m_internal_menu; ///< whether we should destroy this menu or if it's managed somewhere else
|
|
|
|
bool m_title_vis; ///< title visibility
|
2007-12-29 21:38:53 +00:00
|
|
|
|
2007-02-28 19:13:59 +00:00
|
|
|
int m_which_sub;
|
2002-12-25 11:46:50 +00:00
|
|
|
Alignment m_alignment;
|
2004-06-13 10:58:34 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
struct _menu {
|
2005-04-26 01:41:55 +00:00
|
|
|
Pixmap frame_pixmap, title_pixmap, hilite_pixmap;
|
2002-12-25 11:46:50 +00:00
|
|
|
FbTk::FbWindow window, frame, title;
|
|
|
|
|
|
|
|
std::string label;
|
2006-08-09 04:20:06 +00:00
|
|
|
int x_move, y_move, sublevels, persub, minsub, grab_x, grab_y;
|
2004-06-13 10:58:34 +00:00
|
|
|
|
|
|
|
unsigned int frame_h, item_w;
|
2002-12-25 11:46:50 +00:00
|
|
|
} menu;
|
|
|
|
|
2004-06-27 13:51:24 +00:00
|
|
|
int m_active_index; ///< current highlighted index
|
|
|
|
|
2007-12-28 09:14:19 +00:00
|
|
|
std::auto_ptr<FbTk::Shape> m_shape;
|
|
|
|
|
2003-04-20 13:49:26 +00:00
|
|
|
Drawable m_root_pm;
|
2007-01-21 18:43:22 +00:00
|
|
|
static Menu *shown; ///< used for determining if there's a menu open at all
|
2003-07-02 05:26:45 +00:00
|
|
|
static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused
|
2003-04-25 12:32:57 +00:00
|
|
|
bool m_need_update;
|
2003-12-12 18:18:49 +00:00
|
|
|
Timer m_submenu_timer;
|
|
|
|
Timer m_hide_timer;
|
2002-12-25 11:46:50 +00:00
|
|
|
};
|
|
|
|
|
2003-12-16 17:06:52 +00:00
|
|
|
} // end namespace FbTk
|
2003-01-12 17:02:33 +00:00
|
|
|
|
2002-12-25 11:46:50 +00:00
|
|
|
#endif // FBTK_MENU_HH
|