1 /********************************************************************************
2 *                                                                               *
3 *                      S w i t c h   P a n e l   C l a s s                      *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1997,2006 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or                 *
9 * modify it under the terms of the GNU Lesser General Public                    *
10 * License as published by the Free Software Foundation; either                  *
11 * version 2.1 of the License, or (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 GNU             *
16 * Lesser General Public License for more details.                               *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public              *
19 * License along with this library; if not, write to the Free Software           *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
21 *********************************************************************************
22 * $Id: FXSwitcher.cpp,v 1.35 2006/01/22 17:58:43 fox Exp $                      *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "FXHash.h"
28 #include "FXThread.h"
29 #include "FXStream.h"
30 #include "FXString.h"
31 #include "FXSize.h"
32 #include "FXPoint.h"
33 #include "FXRectangle.h"
34 #include "FXRegistry.h"
35 #include "FXApp.h"
36 #include "FXDCWindow.h"
37 #include "FXSwitcher.h"
38 
39 
40 /*
41   Notes:
42   - We do not look at LAYOUT_FIX_WIDTH and LAYOUT_FIX_HEIGHT because
43     FXSwitcher resizes its children anyway and doing this would cause
44     the size to grow instead of shrinkwrap to the biggest child.
45   - Thanks to Charles Warren for the suggestion for the collapse
46     modes.
47 */
48 
49 
50 // Switcher styles
51 #define SWITCHER_MASK (SWITCHER_HCOLLAPSE|SWITCHER_VCOLLAPSE)
52 
53 using namespace FX;
54 
55 /*******************************************************************************/
56 
57 namespace FX {
58 
59 // Map
60 FXDEFMAP(FXSwitcher) FXSwitcherMap[]={
61   FXMAPFUNC(SEL_PAINT,0,FXSwitcher::onPaint),
62   FXMAPFUNCS(SEL_UPDATE,FXSwitcher::ID_OPEN_FIRST,FXSwitcher::ID_OPEN_LAST,FXSwitcher::onUpdOpen),
63   FXMAPFUNC(SEL_COMMAND,FXSwitcher::ID_SETVALUE,FXSwitcher::onCmdSetValue),
64   FXMAPFUNC(SEL_COMMAND,FXSwitcher::ID_SETINTVALUE,FXSwitcher::onCmdSetIntValue),
65   FXMAPFUNC(SEL_COMMAND,FXSwitcher::ID_GETINTVALUE,FXSwitcher::onCmdGetIntValue),
66   FXMAPFUNCS(SEL_COMMAND,FXSwitcher::ID_OPEN_FIRST,FXSwitcher::ID_OPEN_LAST,FXSwitcher::onCmdOpen),
67   };
68 
69 
70 // Object implementation
FXIMPLEMENT(FXSwitcher,FXPacker,FXSwitcherMap,ARRAYNUMBER (FXSwitcherMap))71 FXIMPLEMENT(FXSwitcher,FXPacker,FXSwitcherMap,ARRAYNUMBER(FXSwitcherMap))
72 
73 
74 
75 // Make a switcher window
76 FXSwitcher::FXSwitcher(FXComposite *p,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb):
77   FXPacker(p,opts,x,y,w,h,pl,pr,pt,pb,0,0){
78   current=0;
79   }
80 
81 
82 // Handle repaint
onPaint(FXObject *,FXSelector,void * ptr)83 long FXSwitcher::onPaint(FXObject*,FXSelector,void* ptr){
84   FXEvent *ev=(FXEvent*)ptr;
85   FXDCWindow dc(this,ev);
86   dc.setForeground(backColor);
87   dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h);
88   drawFrame(dc,0,0,width,height);
89   return 1;
90   }
91 
92 
93 // Update value from a message
onCmdSetValue(FXObject *,FXSelector,void * ptr)94 long FXSwitcher::onCmdSetValue(FXObject*,FXSelector,void* ptr){
95   setCurrent((FXint)(FXuval)ptr);
96   return 1;
97   }
98 
99 
100 // Update value from a message
onCmdSetIntValue(FXObject *,FXSelector,void * ptr)101 long FXSwitcher::onCmdSetIntValue(FXObject*,FXSelector,void* ptr){
102   setCurrent(*((FXint*)ptr));
103   return 1;
104   }
105 
106 
107 // Obtain value from text field
onCmdGetIntValue(FXObject *,FXSelector,void * ptr)108 long FXSwitcher::onCmdGetIntValue(FXObject*,FXSelector,void* ptr){
109   *((FXint*)ptr)=getCurrent();
110   return 1;
111   }
112 
113 
114 // Bring nth to the top
onCmdOpen(FXObject *,FXSelector sel,void *)115 long FXSwitcher::onCmdOpen(FXObject*,FXSelector sel,void*){
116   setCurrent(FXSELID(sel)-ID_OPEN_FIRST,TRUE);
117   return 1;
118   }
119 
120 
121 // Update the nth button
onUpdOpen(FXObject * sender,FXSelector sel,void * ptr)122 long FXSwitcher::onUpdOpen(FXObject* sender,FXSelector sel,void* ptr){
123   sender->handle(this,((FXSELID(sel)-ID_OPEN_FIRST)==current) ? FXSEL(SEL_COMMAND,ID_CHECK) : FXSEL(SEL_COMMAND,ID_UNCHECK),ptr);
124   return 1;
125   }
126 
127 
128 // Get maximum child width
getDefaultWidth()129 FXint FXSwitcher::getDefaultWidth(){
130   register FXWindow* child;
131   register FXint i,w,wmax=0,wcur=0;
132   for(i=0,child=getFirst(); child; child=child->getNext(),i++){
133     if(i==current) wcur=child->getDefaultWidth();
134     if(wmax<(w=child->getDefaultWidth())) wmax=w;
135     }
136   if(options&SWITCHER_HCOLLAPSE) wmax=wcur;
137   return padleft+padright+(border<<1)+wmax;
138   }
139 
140 
141 // Get maximum child height
getDefaultHeight()142 FXint FXSwitcher::getDefaultHeight(){
143   register FXWindow* child;
144   register FXint i,h,hmax=0,hcur=0;
145   for(i=0,child=getFirst(); child; child=child->getNext(),i++){
146     if(i==current) hcur=child->getDefaultHeight();
147     if(hmax<(h=child->getDefaultHeight())) hmax=h;
148     }
149   if(options&SWITCHER_VCOLLAPSE) hmax=hcur;
150   return padtop+padbottom+(border<<1)+hmax;
151   }
152 
153 
154 // Recalculate layout
layout()155 void FXSwitcher::layout(){
156   register FXWindow *child;
157   register FXint i,x,y,w,h;
158   x=border+padleft;
159   y=border+padtop;
160   w=width-padright-padleft-(border<<1);
161   h=height-padtop-padbottom-(border<<1);
162   for(i=0,child=getFirst(); child; child=child->getNext(),i++){
163     child->position(x,y,w,h);
164     if(i==current){
165       child->show();
166       }
167     else{
168       child->hide();
169       }
170     }
171   flags&=~FLAG_DIRTY;
172   }
173 
174 
175 // Set current subwindow
setCurrent(FXint panel,FXbool notify)176 void FXSwitcher::setCurrent(FXint panel,FXbool notify){
177   if(0<=panel && panel<numChildren() && current!=panel){
178     current=panel;
179     recalc();
180     if(notify && target){ target->tryHandle(this,FXSEL(SEL_COMMAND,message),(void*)(FXival)current); }
181     }
182   }
183 
184 
185 // Set switcher style
setSwitcherStyle(FXuint style)186 void FXSwitcher::setSwitcherStyle(FXuint style){
187   FXuint opts=(options&~SWITCHER_MASK) | (style&SWITCHER_MASK);
188   if(options!=opts){
189     options=opts;
190     recalc();
191     }
192   }
193 
194 
195 // Get switcher style
getSwitcherStyle() const196 FXuint FXSwitcher::getSwitcherStyle() const {
197   return (options&SWITCHER_MASK);
198   }
199 
200 
201 // Save object to stream
save(FXStream & store) const202 void FXSwitcher::save(FXStream& store) const {
203   FXPacker::save(store);
204   store << current;
205   }
206 
207 
208 // Load object from stream
load(FXStream & store)209 void FXSwitcher::load(FXStream& store){
210   FXPacker::load(store);
211   store >> current;
212   }
213 
214 }
215