1 /********************************************************************************
2 *                                                                               *
3 *                        M e n u B u t t o n   W i d g e t                      *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1998,2021 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify          *
9 * it under the terms of the GNU Lesser General Public License as published by   *
10 * the Free Software Foundation; either version 3 of the License, or             *
11 * (at your option) any later version.                                           *
12 *                                                                               *
13 * This library is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
16 * GNU Lesser General Public License for more details.                           *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public License      *
19 * along with this program.  If not, see <http://www.gnu.org/licenses/>          *
20 ********************************************************************************/
21 #ifndef FXMENUBUTTON_H
22 #define FXMENUBUTTON_H
23 
24 #ifndef FXLABEL_H
25 #include "FXLabel.h"
26 #endif
27 
28 namespace FX {
29 
30 
31 class FXPopup;
32 
33 
34 // Menu button options
35 enum {
36   MENUBUTTON_AUTOGRAY      = 0x00800000,                                      /// Automatically gray out when no target
37   MENUBUTTON_AUTOHIDE      = 0x01000000,                                      /// Automatically hide when no target
38   MENUBUTTON_TOOLBAR       = 0x02000000,                                      /// Toolbar style
39   MENUBUTTON_DOWN          = 0,                                               /// Popup window appears below menu button
40   MENUBUTTON_UP            = 0x04000000,                                      /// Popup window appears above menu button
41   MENUBUTTON_LEFT          = 0x08000000,                                      /// Popup window to the left of the menu button
42   MENUBUTTON_RIGHT         = MENUBUTTON_LEFT|MENUBUTTON_UP,                   /// Popup window to the right of the menu button
43   MENUBUTTON_NOARROWS      = 0x10000000,                                      /// Do not show arrows
44   MENUBUTTON_ATTACH_LEFT   = 0,                                               /// Popup attaches to the left side of the menu button
45   MENUBUTTON_ATTACH_TOP    = MENUBUTTON_ATTACH_LEFT,                          /// Popup attaches to the top of the menu button
46   MENUBUTTON_ATTACH_RIGHT  = 0x20000000,                                      /// Popup attaches to the right side of the menu button
47   MENUBUTTON_ATTACH_BOTTOM = MENUBUTTON_ATTACH_RIGHT,                         /// Popup attaches to the bottom of the menu button
48   MENUBUTTON_ATTACH_CENTER = 0x40000000,                                      /// Popup attaches to the center of the menu button
49   MENUBUTTON_ATTACH_BOTH   = MENUBUTTON_ATTACH_CENTER|MENUBUTTON_ATTACH_RIGHT /// Popup attaches to both sides of the menu button
50   };
51 
52 
53 
54 /**
55 * A menu button posts a popup menu when clicked.
56 * There are many ways to control the placement where the popup will appear;
57 * first, the popup may be placed on either of the four sides relative to the
58 * menu button; this is controlled by the flags MENUBUTTON_DOWN, etc.
59 * Next, there are several attachment modes; the popup's left/bottom edge may
60 * attach to the menu button's left/top edge, or the popup's right/top edge may
61 * attach to the menu button's right/bottom edge, or both.
62 * Also, the popup may apear centered relative to the menu button.
63 * Finally, a small offset may be specified to displace the location of the
64 * popup by a few pixels so as to account for borders and so on.
65 * Normally, the menu button shows an arrow pointing to the direction where
66 * the popup is set to appear; this can be turned off by passing the option
67 * MENUBUTTON_NOARROWS.
68 */
69 class FXAPI FXMenuButton : public FXLabel {
70   FXDECLARE(FXMenuButton)
71 protected:
72   FXPopup *pane;                  // Pane to pop up
73   FXint    offsetx;               // Shift attachment point x
74   FXint    offsety;               // Shift attachment point y
75   FXbool   state;                 // Pane was popped
76 protected:
77   FXMenuButton();
78 private:
79   FXMenuButton(const FXMenuButton&);
80   FXMenuButton &operator=(const FXMenuButton&);
81 public:
82   long onPaint(FXObject*,FXSelector,void*);
83   long onUpdate(FXObject*,FXSelector,void*);
84   long onEnter(FXObject*,FXSelector,void*);
85   long onLeave(FXObject*,FXSelector,void*);
86   long onFocusIn(FXObject*,FXSelector,void*);
87   long onFocusOut(FXObject*,FXSelector,void*);
88   long onUngrabbed(FXObject*,FXSelector,void*);
89   long onMotion(FXObject*,FXSelector,void*);
90   long onButtonPress(FXObject*,FXSelector,void*);
91   long onButtonRelease(FXObject*,FXSelector,void*);
92   long onKeyPress(FXObject*,FXSelector,void*);
93   long onKeyRelease(FXObject*,FXSelector,void*);
94   long onHotKeyPress(FXObject*,FXSelector,void*);
95   long onHotKeyRelease(FXObject*,FXSelector,void*);
96   long onCmdPost(FXObject*,FXSelector,void*);
97   long onCmdUnpost(FXObject*,FXSelector,void*);
98 public:
99 
100   /// Constructor
101   FXMenuButton(FXComposite* p,const FXString& text,FXIcon* ic=NULL,FXPopup* pup=NULL,FXuint opts=JUSTIFY_NORMAL|ICON_BEFORE_TEXT|MENUBUTTON_DOWN,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=DEFAULT_PAD,FXint pr=DEFAULT_PAD,FXint pt=DEFAULT_PAD,FXint pb=DEFAULT_PAD);
102 
103   /// Create server-side resources
104   virtual void create();
105 
106   /// Detach server-side resources
107   virtual void detach();
108 
109   /// Return default width
110   virtual FXint getDefaultWidth();
111 
112   /// Return default height
113   virtual FXint getDefaultHeight();
114 
115   /// Returns true because a menu button can receive focus
116   virtual FXbool canFocus() const;
117 
118   /// Remove the focus from this window
119   virtual void killFocus();
120 
121   /// Return true if window logically contains the given point
122   virtual FXbool contains(FXint parentx,FXint parenty) const;
123 
124   /// Change the popup menu
125   void setMenu(FXPopup *pup);
126 
127   /// Return current popup menu
getMenu()128   FXPopup* getMenu() const { return pane; }
129 
130   /// Show or hide menu
131   void showMenu(FXbool shw);
132 
133   /// Is the pane shown
134   FXbool isMenuShown() const;
135 
136   /// Set X offset where menu pops up relative to button
setXOffset(FXint offx)137   void setXOffset(FXint offx){ offsetx=offx; }
138 
139   /// Return current X offset
getXOffset()140   FXint getXOffset() const { return offsetx; }
141 
142   /// Set Y offset where menu pops up relative to button
setYOffset(FXint offy)143   void setYOffset(FXint offy){ offsety=offy; }
144 
145   /// Return current Y offset
getYOffset()146   FXint getYOffset() const { return offsety; }
147 
148   /// Change menu button style
149   void setButtonStyle(FXuint style);
150 
151   /// Get menu button style
152   FXuint getButtonStyle() const;
153 
154   /// Change popup style
155   void setPopupStyle(FXuint style);
156 
157   /// Get popup style
158   FXuint getPopupStyle() const;
159 
160   /// Change attachment
161   void setAttachment(FXuint att);
162 
163   /// Get attachment
164   FXuint getAttachment() const;
165 
166   /// Save menu button to a stream
167   virtual void save(FXStream& store) const;
168 
169   /// Load menu button from a stream
170   virtual void load(FXStream& store);
171 
172   /// Destructor
173   virtual ~FXMenuButton();
174   };
175 
176 }
177 
178 #endif
179