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