1 /********************************************************************************
2 *                                                                               *
3 *                           W i z a r d   W i d g e t                           *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 2002,2020 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 "FXApp.h"
40 #include "FXImage.h"
41 #include "FXGIFIcon.h"
42 #include "FXFrame.h"
43 #include "FXImageFrame.h"
44 #include "FXSeparator.h"
45 #include "FXLabel.h"
46 #include "FXButton.h"
47 #include "FXPacker.h"
48 #include "FXVerticalFrame.h"
49 #include "FXHorizontalFrame.h"
50 #include "FXSwitcher.h"
51 #include "FXWizard.h"
52 #include "icons.h"
53 
54 
55 
56 /*
57   Notes:
58   - It may be nice to be able to sensitize/desensitize the "Next" button based on
59     having whether the necessary info has been entered into a pane.
60   - Need callbacks to tell target whether FXWizard has switched panes.
61   - Need to allow for choices in successor panes.
62 */
63 
64 
65 // Padding for buttons
66 #define HORZ_PAD      12
67 #define VERT_PAD      2
68 
69 using namespace FX;
70 
71 /*******************************************************************************/
72 
73 namespace FX {
74 
75 // Map
76 FXDEFMAP(FXWizard) FXWizardMap[]={
77   FXMAPFUNC(SEL_COMMAND,FXWizard::ID_NEXT,FXWizard::onCmdNext),
78   FXMAPFUNC(SEL_UPDATE,FXWizard::ID_NEXT,FXWizard::onUpdNext),
79   FXMAPFUNC(SEL_COMMAND,FXWizard::ID_BACK,FXWizard::onCmdBack),
80   FXMAPFUNC(SEL_UPDATE,FXWizard::ID_BACK,FXWizard::onUpdBack),
81   FXMAPFUNC(SEL_UPDATE,FXWizard::ID_ACCEPT,FXWizard::onUpdFinish),
82   };
83 
84 
85 // Object implementation
FXIMPLEMENT(FXWizard,FXDialogBox,FXWizardMap,ARRAYNUMBER (FXWizardMap))86 FXIMPLEMENT(FXWizard,FXDialogBox,FXWizardMap,ARRAYNUMBER(FXWizardMap))
87 
88 
89 // Construct free-floating Wizard
90 FXWizard::FXWizard(FXApp* a,const FXString& name,FXImage *image,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs):FXDialogBox(a,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs){
91   construct();
92   setImage(image);
93   }
94 
95 
96 // Construct Wizard which will always float over the owner window
FXWizard(FXWindow * own,const FXString & name,FXImage * image,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs)97 FXWizard::FXWizard(FXWindow* own,const FXString& name,FXImage *image,FXuint opts,FXint x,FXint y,FXint w,FXint h,FXint pl,FXint pr,FXint pt,FXint pb,FXint hs,FXint vs):FXDialogBox(own,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs){
98   construct();
99   setImage(image);
100   }
101 
102 
103 // Common part of constructor
construct()104 void FXWizard::construct(){
105   nexticon=new FXGIFIcon(getApp(),arrownext);
106   backicon=new FXGIFIcon(getApp(),arrowprev);
107   finishicon=new FXGIFIcon(getApp(),entericon);
108   buttons=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH|PACK_UNIFORM_HEIGHT,0,0,0,0,0,0,0,0);
109   finish=new FXButton(buttons,tr("&Finish"),finishicon,this,ID_ACCEPT,ICON_AFTER_TEXT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD,HORZ_PAD,VERT_PAD,VERT_PAD);
110   advance=new FXButton(buttons,tr("&Next"),nexticon,this,ID_NEXT,BUTTON_INITIAL|BUTTON_DEFAULT|ICON_AFTER_TEXT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD,HORZ_PAD,VERT_PAD,VERT_PAD);
111   retreat=new FXButton(buttons,tr("&Back"),backicon,this,ID_BACK,ICON_BEFORE_TEXT|FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD+10,HORZ_PAD+10,VERT_PAD,VERT_PAD);
112   new FXFrame(buttons,LAYOUT_FIX_WIDTH|LAYOUT_RIGHT,0,0,10,0);
113   cancel=new FXButton(buttons,tr("&Cancel"),NULL,this,ID_CANCEL,BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD,HORZ_PAD,VERT_PAD,VERT_PAD);
114   new FXHorizontalSeparator(this,SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
115   sidebar=new FXImageFrame(this,NULL,FRAME_GROOVE|LAYOUT_SIDE_LEFT|LAYOUT_CENTER_Y);
116   panels=new FXSwitcher(this,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
117   finish->hide();
118   }
119 
120 
121 // Update finish panel
onUpdFinish(FXObject * sender,FXSelector,void *)122 long FXWizard::onUpdFinish(FXObject* sender,FXSelector,void*){
123   sender->handle(this,(getCurrentPanel()<getNumPanels()-1)?FXSEL(SEL_COMMAND,ID_HIDE):FXSEL(SEL_COMMAND,ID_SHOW),NULL);
124   return 1;
125   }
126 
127 
128 // Advance to next page
onCmdNext(FXObject *,FXSelector,void *)129 long FXWizard::onCmdNext(FXObject*,FXSelector,void*){
130   setCurrentPanel(getCurrentPanel()+1);
131   return 1;
132   }
133 
134 
135 // Update advance to next page
onUpdNext(FXObject * sender,FXSelector,void *)136 long FXWizard::onUpdNext(FXObject* sender,FXSelector,void*){
137   sender->handle(this,(getCurrentPanel()<getNumPanels()-1)?FXSEL(SEL_COMMAND,ID_SHOW):FXSEL(SEL_COMMAND,ID_HIDE),NULL);
138   return 1;
139   }
140 
141 
142 // Revert to next page
onCmdBack(FXObject *,FXSelector,void *)143 long FXWizard::onCmdBack(FXObject*,FXSelector,void*){
144   setCurrentPanel(getCurrentPanel()-1);
145   return 1;
146   }
147 
148 
149 // Update revert to next page
onUpdBack(FXObject * sender,FXSelector,void *)150 long FXWizard::onUpdBack(FXObject* sender,FXSelector,void*){
151   sender->handle(this,(0<getCurrentPanel())?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
152   return 1;
153   }
154 
155 
156 // Return number of panels
getNumPanels() const157 FXint FXWizard::getNumPanels() const {
158   return panels->numChildren();
159   }
160 
161 
162 // Bring the child window at index to the top
setCurrentPanel(FXint index)163 void FXWizard::setCurrentPanel(FXint index){
164   panels->setCurrent(index);
165   }
166 
167 
168 // Return the index of the child window currently on top
getCurrentPanel() const169 FXint FXWizard::getCurrentPanel() const {
170   return panels->getCurrent();
171   }
172 
173 
174 // Change the image being displayed
setImage(FXImage * img)175 void FXWizard::setImage(FXImage* img){
176   sidebar->setImage(img);
177   }
178 
179 
180 // Return the current image
getImage() const181 FXImage* FXWizard::getImage() const {
182   return sidebar->getImage();
183   }
184 
185 
186 // Save object to stream
save(FXStream & store) const187 void FXWizard::save(FXStream& store) const {
188   FXDialogBox::save(store);
189   store << buttons;
190   store << sidebar;
191   store << advance;
192   store << retreat;
193   store << finish;
194   store << cancel;
195   store << panels;
196   store << finishicon;
197   store << nexticon;
198   store << backicon;
199   }
200 
201 
202 // Load object from stream
load(FXStream & store)203 void FXWizard::load(FXStream& store){
204   FXDialogBox::load(store);
205   store >> buttons;
206   store >> sidebar;
207   store >> advance;
208   store >> retreat;
209   store >> finish;
210   store >> cancel;
211   store >> panels;
212   store >> finishicon;
213   store >> nexticon;
214   store >> backicon;
215   }
216 
217 
218 // Destroy
~FXWizard()219 FXWizard::~FXWizard(){
220   delete finishicon;
221   delete nexticon;
222   delete backicon;
223   buttons=(FXHorizontalFrame*)-1L;
224   sidebar=(FXImageFrame*)-1L;
225   advance=(FXButton*)-1L;
226   retreat=(FXButton*)-1L;
227   cancel=(FXButton*)-1L;
228   finishicon=(FXIcon*)-1L;
229   nexticon=(FXIcon*)-1L;
230   backicon=(FXIcon*)-1L;
231   }
232 
233 }
234