1 /********************************************************************************
2 * *
3 * T o o l B a r G r i p W i d g e t *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2000,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 #include "xincs.h"
22 #include "fxver.h"
23 #include "fxdefs.h"
24 #include "fxkeys.h"
25 #include "fxmath.h"
26 #include "FXArray.h"
27 #include "FXHash.h"
28 #include "FXMutex.h"
29 #include "FXStream.h"
30 #include "FXString.h"
31 #include "FXSize.h"
32 #include "FXPoint.h"
33 #include "FXRectangle.h"
34 #include "FXStringDictionary.h"
35 #include "FXSettings.h"
36 #include "FXRegistry.h"
37 #include "FXEvent.h"
38 #include "FXWindow.h"
39 #include "FXDCWindow.h"
40 #include "FXApp.h"
41 #include "FXToolBar.h"
42 #include "FXToolBarGrip.h"
43
44
45 /*
46 Notes:
47 - Tool bar grip is a small grabber contained in the toolbar which lets
48 a user move the toolbar around, dock and undock it, and so on.
49 - The convention is to let single-rebar tool bar grips rearrange the
50 bars in a dock site, and double-rebar grips dock and undock.
51 This convention is recommended but not enforced.
52 */
53
54
55 // Size
56 #define GRIP_SINGLE 3 // Single grip for arrangable toolbars
57 #define GRIP_DOUBLE 7 // Double grip for dockable toolbars
58
59 #define JUSTIFY_MASK (JUSTIFY_HZ_APART|JUSTIFY_VT_APART)
60
61
62 using namespace FX;
63
64 /*******************************************************************************/
65
66 namespace FX {
67
68 // Map
69 FXDEFMAP(FXToolBarGrip) FXToolBarGripMap[]={
70 FXMAPFUNC(SEL_PAINT,0,FXToolBarGrip::onPaint),
71 FXMAPFUNC(SEL_ENTER,0,FXToolBarGrip::onEnter),
72 FXMAPFUNC(SEL_LEAVE,0,FXToolBarGrip::onLeave),
73 FXMAPFUNC(SEL_MOTION,0,FXToolBarGrip::onMotion),
74 FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,FXToolBarGrip::onLeftBtnPress),
75 FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,FXToolBarGrip::onLeftBtnRelease),
76 FXMAPFUNC(SEL_KEYPRESS,0,FXToolBarGrip::onKeyPress),
77 FXMAPFUNC(SEL_KEYRELEASE,0,FXToolBarGrip::onKeyRelease),
78 FXMAPFUNC(SEL_COMMAND,FXToolBarGrip::ID_SETHELPSTRING,FXToolBarGrip::onCmdSetHelp),
79 FXMAPFUNC(SEL_COMMAND,FXToolBarGrip::ID_GETHELPSTRING,FXToolBarGrip::onCmdGetHelp),
80 FXMAPFUNC(SEL_COMMAND,FXToolBarGrip::ID_SETTIPSTRING,FXToolBarGrip::onCmdSetTip),
81 FXMAPFUNC(SEL_COMMAND,FXToolBarGrip::ID_GETTIPSTRING,FXToolBarGrip::onCmdGetTip),
82 };
83
84
85 // Object implementation
FXIMPLEMENT(FXToolBarGrip,FXDockHandler,FXToolBarGripMap,ARRAYNUMBER (FXToolBarGripMap))86 FXIMPLEMENT(FXToolBarGrip,FXDockHandler,FXToolBarGripMap,ARRAYNUMBER(FXToolBarGripMap))
87
88
89 // Deserialization
90 FXToolBarGrip::FXToolBarGrip(){
91 activeColor=0;
92 }
93
94
95 // Construct and init
FXToolBarGrip(FXComposite * p,FXObject * tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb)96 FXToolBarGrip::FXToolBarGrip(FXComposite* p,FXObject* tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb):FXDockHandler(p,tgt,sel,opts,x,y,w,h,pl,pr,pt,pb){
97 activeColor=FXRGB(0,0,255);
98 }
99
100
101
102 // Get default width
getDefaultWidth()103 FXint FXToolBarGrip::getDefaultWidth(){
104 return padleft+padright+(border<<1)+((options&TOOLBARGRIP_DOUBLE)?GRIP_DOUBLE:GRIP_SINGLE);
105 }
106
107
108 // Get default height
getDefaultHeight()109 FXint FXToolBarGrip::getDefaultHeight(){
110 return padtop+padbottom+(border<<1)+((options&TOOLBARGRIP_DOUBLE)?GRIP_DOUBLE:GRIP_SINGLE);
111 }
112
113
114 // Can have focus
canFocus() const115 FXbool FXToolBarGrip::canFocus() const { return false; }
116
117
118 // Change toolbar orientation
setDoubleBar(FXbool dbl)119 void FXToolBarGrip::setDoubleBar(FXbool dbl){
120 FXuint opts=dbl?(options|TOOLBARGRIP_DOUBLE):(options&~TOOLBARGRIP_DOUBLE);
121 if(opts!=options){
122 options=opts;
123 recalc();
124 }
125 }
126
127
128 // Return true if toolbar grip is displayed as a double bar
isDoubleBar() const129 FXbool FXToolBarGrip::isDoubleBar() const {
130 return (options&TOOLBARGRIP_DOUBLE)!=0;
131 }
132
133
134 // Handle repaint
onPaint(FXObject *,FXSelector,void * ptr)135 long FXToolBarGrip::onPaint(FXObject*,FXSelector,void* ptr){
136 FXEvent* event=static_cast<FXEvent*>(ptr);
137 FXDCWindow dc(this,event);
138 FXint xx,yy,ww,hh;
139 dc.setForeground(backColor);
140 dc.fillRectangle(border,border,width-(border<<1),height-(border<<1));
141 ww=width-padleft-padright-(border<<1);
142 hh=height-padtop-padbottom-(border<<1);
143 if(width>height){
144 xx=border+padleft;
145 if(options&TOOLBARGRIP_DOUBLE){ // =
146 yy=border+padtop+(hh-GRIP_DOUBLE)/2;
147 dc.setForeground(hiliteColor);
148 dc.fillRectangle(xx,yy,1,2);
149 dc.fillRectangle(xx,yy+4,1,2);
150 dc.fillRectangle(xx,yy,ww-1,1);
151 dc.fillRectangle(xx,yy+4,ww-1,1);
152 dc.setForeground(shadowColor);
153 dc.fillRectangle(xx+ww-1,yy,1,3);
154 dc.fillRectangle(xx+ww-1,yy+4,1,3);
155 dc.fillRectangle(xx,yy+2,ww-1,1);
156 dc.fillRectangle(xx,yy+6,ww-1,1);
157 if(flags&(FLAG_ACTIVE|FLAG_TRYDRAG|FLAG_DODRAG)){
158 dc.setForeground(activeColor);
159 dc.fillRectangle(xx+1,yy+1,ww-2,1);
160 dc.fillRectangle(xx+1,yy+5,ww-2,1);
161 }
162 }
163 else{ // -
164 yy=border+padtop+(hh-GRIP_SINGLE)/2;
165 dc.setForeground(hiliteColor);
166 dc.fillRectangle(xx,yy,1,2);
167 dc.fillRectangle(xx,yy,ww-1,1);
168 dc.setForeground(shadowColor);
169 dc.fillRectangle(xx+ww-1,yy,1,3);
170 dc.fillRectangle(xx,yy+2,ww-1,1);
171 if(flags&(FLAG_ACTIVE|FLAG_TRYDRAG|FLAG_DODRAG)){
172 dc.setForeground(activeColor);
173 dc.fillRectangle(xx+1,yy+1,ww-2,1);
174 }
175 }
176 }
177 else{
178 yy=border+padtop;
179 if(options&TOOLBARGRIP_DOUBLE){ // ||
180 xx=border+padleft+(ww-GRIP_DOUBLE)/2;
181 dc.setForeground(hiliteColor);
182 dc.fillRectangle(xx,yy,2,1);
183 dc.fillRectangle(xx+4,yy,2,1);
184 dc.fillRectangle(xx,yy,1,hh-1);
185 dc.fillRectangle(xx+4,yy,1,hh-1);
186 dc.setForeground(shadowColor);
187 dc.fillRectangle(xx,yy+hh-1,3,1);
188 dc.fillRectangle(xx+4,yy+hh-1,3,1);
189 dc.fillRectangle(xx+2,yy,1,hh-1);
190 dc.fillRectangle(xx+6,yy,1,hh-1);
191 if(flags&(FLAG_ACTIVE|FLAG_TRYDRAG|FLAG_DODRAG)){
192 dc.setForeground(activeColor);
193 dc.fillRectangle(xx+1,yy+1,1,hh-2);
194 dc.fillRectangle(xx+5,yy+1,1,hh-2);
195 }
196 }
197 else{ // |
198 xx=border+padleft+(ww-GRIP_SINGLE)/2;
199 dc.setForeground(hiliteColor);
200 dc.fillRectangle(xx,yy,2,1);
201 dc.fillRectangle(xx,yy,1,hh-1);
202 dc.setForeground(shadowColor);
203 dc.fillRectangle(xx,yy+hh-1,3,1);
204 dc.fillRectangle(xx+2,yy,1,hh-1);
205 if(flags&(FLAG_ACTIVE|FLAG_TRYDRAG|FLAG_DODRAG)){
206 dc.setForeground(activeColor);
207 dc.fillRectangle(xx+1,yy+1,1,hh-2);
208 }
209 }
210 }
211 drawFrame(dc,0,0,width,height);
212 return 1;
213 }
214
215
216 // Entered button
onEnter(FXObject * sender,FXSelector sel,void * ptr)217 long FXToolBarGrip::onEnter(FXObject* sender,FXSelector sel,void* ptr){
218 FXDockHandler::onEnter(sender,sel,ptr);
219 if(isEnabled()){ flags|=FLAG_ACTIVE; update(); }
220 return 1;
221 }
222
223
224 // Leave button
onLeave(FXObject * sender,FXSelector sel,void * ptr)225 long FXToolBarGrip::onLeave(FXObject* sender,FXSelector sel,void* ptr){
226 FXDockHandler::onLeave(sender,sel,ptr);
227 if(isEnabled()){ flags&=~FLAG_ACTIVE; update(); }
228 return 1;
229 }
230
231
232
233 // Set active color
setActiveColor(FXColor clr)234 void FXToolBarGrip::setActiveColor(FXColor clr){
235 if(clr!=activeColor){
236 activeColor=clr;
237 update();
238 }
239 }
240
241
242 // Save data
save(FXStream & store) const243 void FXToolBarGrip::save(FXStream& store) const {
244 FXDockHandler::save(store);
245 store << activeColor;
246 }
247
248
249 // Load data
load(FXStream & store)250 void FXToolBarGrip::load(FXStream& store){
251 FXDockHandler::load(store);
252 store >> activeColor;
253 }
254
255
256 }
257