1 #pragma once
2
3 #ifndef TNZ_POPUPMENU_INCLUDED
4 #define TNZ_POPUPMENU_INCLUDED
5
6 #include "tw/action.h"
7 #include "tw/popup.h"
8 #include "tw/button.h"
9
10 #undef DVAPI
11 #undef DVVAR
12 #ifdef TWIN_EXPORTS
13 #define DVAPI DV_EXPORT_API
14 #define DVVAR DV_EXPORT_VAR
15 #else
16 #define DVAPI DV_IMPORT_API
17 #define DVVAR DV_IMPORT_VAR
18 #endif
19
20 //-------------------------------------------------------------
21
22 class TPopupMenu;
23 class TPopupMenuItem;
24
25 //-------------------------------------------------------------
26
27 class DVAPI TPopupMenuListener {
28 public:
TPopupMenuListener()29 TPopupMenuListener() {}
~TPopupMenuListener()30 virtual ~TPopupMenuListener() {}
31
32 virtual void onMenuSelect(TPopupMenuItem *item) = 0;
33 };
34
35 //-------------------------------------------------------------
36
37 class DVAPI TPopupMenuItem : public TButton {
38 wstring m_title;
39 bool m_selected;
40
41 public:
42 TPopupMenuItem(TPopupMenu *parent, string name);
43 void repaint();
44
45 void enter(const TPoint &);
46 void leave(const TPoint &);
47
48 void leftButtonDown(const TMouseEvent &e);
49 void leftButtonUp(const TMouseEvent &e);
50
51 void setTitle(wstring title);
52
53 TPopupMenu *getPopup();
54
55 void select(bool on);
isSelected()56 bool isSelected() const { return m_selected; }
57
58 virtual int getWidth();
59 };
60
61 //-------------------------------------------------------------
62
63 class DVAPI TPopupMenuSeparator : public TWidget {
64 public:
65 TPopupMenuSeparator(TPopupMenu *parent);
66 void repaint();
67 };
68
69 //-------------------------------------------------------------
70
71 //
72 // Note: to implement right-mouse-bottom menu use
73 // the class TContextMenu (see below)
74 //
75
76 class DVAPI TPopupMenu : public TPopup {
77 TPopupMenuItem *m_currentItem;
78 TPopupMenuListener *m_listener;
79 int m_firstVisibleItem;
80 int m_visibleItemCount;
81 bool m_leftAlignment;
82
83 public:
84 TPopupMenu(TWidget *parent, string name = "popupMenu");
85 void draw();
86 void configureNotify(const TDimension &);
87
88 void leftButtonDrag(const TPoint &, UCHAR);
89 void leftButtonUp(const TPoint &);
90
91 void popup(const TPoint &pos, int width = 120);
92 void close();
93
getCurrentItem()94 TPopupMenuItem *getCurrentItem() { return m_currentItem; }
95 void setListener(TPopupMenuListener *);
96
97 static TPopupMenu *getCurrentMenu();
98
setLeftAlignment(bool a)99 void setLeftAlignment(bool a) { m_leftAlignment = a; }
100
101 private:
102 void updateItemsVisibility();
103 void updateSize();
104 void computeSize(TPoint &pos, int maxY);
105
106 friend class TPopupMenuArrow;
107 };
108
109 //-------------------------------------------------------------
110
111 //
112 // TContextMenu :
113 // a class specifically dedicated to
114 // right-mouse-button popup menu (aka Context Menu)
115 //
116 // Note: DON'T use the method popup() (inherited from TPopupMenu)
117 //
118 // Note: the context menu will be automatically destroyed
119 // DON'T keep a reference to the context menu
120 //
121 // see examples below
122 //
123
124 /*---- Example 1 (position indipendent) ----
125
126 void Pluto::rightButtonUp(const TMouseEvent &e) {
127 TContextMenu *menu = new TContextMenu(this);
128 menu->addCommand("MI_Cut");
129 menu->addCommand("MI_Copy");
130 menu->addCommand("MI_Paste");
131 menu->addCommand("MI_Clear");
132 TContextMenu::open(menu, e.m_pos);
133 }
134
135
136 ---- Example 2 (position dependent) ----
137
138
139 class MyContextMenu : public TContextMenu {
140 int m_myValue;
141 public:
142 MyContextMenu(TWidget*parent, int myValue)
143 : TContextMenu(parent), m_myValue(myValue), m_col(col) {
144 tconnect(this, "foo", this, &CellContextMenu::onFoo);
145 tconnect(this, "bar", this, &CellContextMenu::onBar);
146 }
147 void onFoo() { ... }
148 void onBar() { ... }
149 };
150
151 void Pluto::rightButtonUp(const TMouseEvent &e) {
152 int row = ....
153 int col = ....
154 TContextMenu::open(new CellContextMenu(this, row, col), e.m_pos);
155 }
156
157 -----------------------------------------*/
158
159 class DVAPI TContextMenu : public TPopupMenu {
160 public:
161 class CommandFilter {
162 public:
163 virtual bool check(string cmdName) const = 0;
~CommandFilter()164 virtual ~CommandFilter() {}
165 };
166
167 TContextMenu(TWidget *parent);
168
169 void add(string name, TGenericCommandAction *action);
170 void addCommand(string cmdName);
171 void addCommand(string cmdName, TGenericCommandAction *action);
172
addSeparator()173 void addSeparator() { new TPopupMenuSeparator(this); }
174
175 /*
176 template <class T>
177 inline void addCommand(string cmdName, T*target, void (T::*method)()) {
178 //addCommand(cmdName, new TCommandAction<T>(target, method));
179 }
180 */
181 static void open(TContextMenu *menu, const TPoint &pos);
182
183 static void setCommandFilter(CommandFilter *filter);
184
185 void onTimer(int);
186 };
187
188 template <class T>
tconnect(TContextMenu * menu,string cmdName,T * target,void (T::* method)())189 inline void tconnect(TContextMenu *menu, string cmdName, T *target,
190 void (T::*method)()) {
191 menu->addCommand(cmdName, new TCommandAction<T>(target, method));
192 }
193
194 template <class T, class Arg>
tconnect(TContextMenu * menu,string cmdName,T * target,void (T::* method)(Arg),Arg arg)195 inline void tconnect(TContextMenu *menu, string cmdName, T *target,
196 void (T::*method)(Arg), Arg arg) {
197 menu->addCommand(cmdName, new TCommandAction1<T, Arg>(target, method, arg));
198 }
199
200 #endif
201