1 /********************************************************************************
2 *                                                                               *
3 *                            C h o i c e   B o x                                *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 2004,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: FXChoiceBox.cpp 4937 2019-03-10 19:59:30Z arthurcnorman $                     *
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 "FXObjectList.h"
35 #include "FXRegistry.h"
36 #include "FXAccelTable.h"
37 #include "FXApp.h"
38 #include "FXIcon.h"
39 #include "FXSeparator.h"
40 #include "FXLabel.h"
41 #include "FXButton.h"
42 #include "FXHorizontalFrame.h"
43 #include "FXVerticalFrame.h"
44 #include "FXScrollBar.h"
45 #include "FXList.h"
46 #include "FXChoiceBox.h"
47 #include "icons.h"
48 
49 /*
50   Notes:
51   - Maybe allow setting initial value which selected.
52   - Maybe have multiple choice capability.
53   - Maybe have list of icons for each list item.
54 */
55 
56 // Padding for message box buttons
57 #define HORZ_PAD 30
58 #define VERT_PAD 2
59 
60 using namespace FX;
61 
62 /*******************************************************************************/
63 
64 namespace FX {
65 
66 // Map
67 FXDEFMAP(FXChoiceBox) FXChoiceBoxMap[]={
68   FXMAPFUNC(SEL_COMMAND,FXChoiceBox::ID_CANCEL,FXChoiceBox::onCmdCancel),
69   FXMAPFUNC(SEL_COMMAND,FXChoiceBox::ID_ACCEPT,FXChoiceBox::onCmdClicked),
70   FXMAPFUNC(SEL_DOUBLECLICKED,FXChoiceBox::ID_CLICKED,FXChoiceBox::onCmdClicked),
71   };
72 
73 
74 
75 // Object implementation
FXIMPLEMENT(FXChoiceBox,FXDialogBox,FXChoiceBoxMap,ARRAYNUMBER (FXChoiceBoxMap))76 FXIMPLEMENT(FXChoiceBox,FXDialogBox,FXChoiceBoxMap,ARRAYNUMBER(FXChoiceBoxMap))
77 
78 
79 // Construct choice box with given caption, icon, message text, and with choices from array of strings
80 FXChoiceBox::FXChoiceBox(FXWindow* owner,const FXString& caption,const FXString& text,FXIcon* icon,const FXchar** choices,FXuint opts,FXint x,FXint y,FXint w,FXint h):
81   FXDialogBox(owner,caption,opts|DECOR_TITLE|DECOR_BORDER,x,y,w,h,10,10,10,10, 10,10){
82   FXint n;
83   initialize(text,icon);
84   n=list->fillItems(choices);
85   list->setNumVisible(FXMIN(n,5));
86   }
87 
88 
89 // Construct choice box with given caption, icon, message text, and with choices from newline separated strings
FXChoiceBox(FXWindow * owner,const FXString & caption,const FXString & text,FXIcon * icon,const FXString & choices,FXuint opts,FXint x,FXint y,FXint w,FXint h)90 FXChoiceBox::FXChoiceBox(FXWindow* owner,const FXString& caption,const FXString& text,FXIcon* icon,const FXString& choices,FXuint opts,FXint x,FXint y,FXint w,FXint h):
91   FXDialogBox(owner,caption,opts|DECOR_TITLE|DECOR_BORDER,x,y,w,h,10,10,10,10, 10,10){
92   FXint n;
93   initialize(text,icon);
94   n=list->fillItems(choices);
95   list->setNumVisible(FXMIN(n,5));
96   }
97 
98 
99 // Construct free floating choice box with given caption, icon, message text, and with choices from array of strings
FXChoiceBox(FXApp * a,const FXString & caption,const FXString & text,FXIcon * icon,const FXchar ** choices,FXuint opts,FXint x,FXint y,FXint w,FXint h)100 FXChoiceBox::FXChoiceBox(FXApp* a,const FXString& caption,const FXString& text,FXIcon* icon,const FXchar** choices,FXuint opts,FXint x,FXint y,FXint w,FXint h):
101   FXDialogBox(a,caption,opts|DECOR_TITLE|DECOR_BORDER,x,y,w,h,10,10,10,10, 10,10){
102   FXint n;
103   initialize(text,icon);
104   n=list->fillItems(choices);
105   list->setNumVisible(FXMIN(n,5));
106   }
107 
108 
109 // Construct free floating choice box with given caption, icon, message text, and with choices from newline separated strings
FXChoiceBox(FXApp * a,const FXString & caption,const FXString & text,FXIcon * icon,const FXString & choices,FXuint opts,FXint x,FXint y,FXint w,FXint h)110 FXChoiceBox::FXChoiceBox(FXApp* a,const FXString& caption,const FXString& text,FXIcon* icon,const FXString& choices,FXuint opts,FXint x,FXint y,FXint w,FXint h):
111   FXDialogBox(a,caption,opts|DECOR_TITLE|DECOR_BORDER,x,y,w,h,10,10,10,10, 10,10){
112   FXint n;
113   initialize(text,icon);
114   n=list->fillItems(choices);
115   list->setNumVisible(FXMIN(n,5));
116   }
117 
118 
119 // Build contents
initialize(const FXString & text,FXIcon * icon)120 void FXChoiceBox::initialize(const FXString& text,FXIcon* icon){
121   FXHorizontalFrame* buttons=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,0,0,0,0,0,0,0,0);
122   new FXButton(buttons,tr("&OK"),NULL,this,ID_ACCEPT,BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD,HORZ_PAD,VERT_PAD,VERT_PAD);
123   new FXButton(buttons,tr("&Cancel"),NULL,this,ID_CANCEL,BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_RIGHT,0,0,0,0,HORZ_PAD,HORZ_PAD,VERT_PAD,VERT_PAD);
124   new FXHorizontalSeparator(this,SEPARATOR_GROOVE|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X);
125   FXHorizontalFrame* toppart=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0, 10,10);
126   new FXLabel(toppart,FXString::null,icon,ICON_BEFORE_TEXT|JUSTIFY_CENTER_X|JUSTIFY_CENTER_Y|LAYOUT_FILL_Y|LAYOUT_FILL_X);
127   new FXLabel(toppart,text,NULL,JUSTIFY_LEFT|ICON_BEFORE_TEXT|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FILL_X);
128   FXHorizontalFrame* midpart=new FXHorizontalFrame(this,FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0, 10,10);
129   list=new FXList(midpart,this,ID_CLICKED,LIST_BROWSESELECT|LAYOUT_FILL_Y|LAYOUT_FILL_X|HSCROLLING_OFF);
130   }
131 
132 
133 // Close dialog when double-clicked in list or hit accept
onCmdClicked(FXObject *,FXSelector,void *)134 long FXChoiceBox::onCmdClicked(FXObject*,FXSelector,void*){
135   getApp()->stopModal(this,list->getCurrentItem());
136   hide();
137   return 1;
138   }
139 
140 
141 // Close dialog with a cancel
onCmdCancel(FXObject *,FXSelector,void *)142 long FXChoiceBox::onCmdCancel(FXObject*,FXSelector,void*){
143   getApp()->stopModal(this,-1);
144   hide();
145   return 1;
146   }
147 
148 
149 // Save object to stream
save(FXStream & store) const150 void FXChoiceBox::save(FXStream& store) const {
151   FXDialogBox::save(store);
152   store << list;
153   }
154 
155 
156 // Load object from stream
load(FXStream & store)157 void FXChoiceBox::load(FXStream& store){
158   FXDialogBox::load(store);
159   store >> list;
160   }
161 
162 
163 // Destroy choice box
~FXChoiceBox()164 FXChoiceBox::~FXChoiceBox(){
165   list=(FXList*)-1L;
166   }
167 
168 
169 /*******************************************************************************/
170 
171 
172 // Show a modal choice dialog
ask(FXWindow * owner,FXuint opts,const FXString & caption,const FXString & text,FXIcon * icon,const FXchar ** choices)173 FXint FXChoiceBox::ask(FXWindow* owner,FXuint opts,const FXString& caption,const FXString& text,FXIcon* icon,const FXchar** choices){
174   FXChoiceBox box(owner,caption,text,icon,choices,opts);
175   return box.execute(PLACEMENT_OWNER);
176   }
177 
178 
179 // Show a modal choice dialog
ask(FXWindow * owner,FXuint opts,const FXString & caption,const FXString & text,FXIcon * icon,const FXString & choices)180 FXint FXChoiceBox::ask(FXWindow* owner,FXuint opts,const FXString& caption,const FXString& text,FXIcon* icon,const FXString& choices){
181   FXChoiceBox box(owner,caption,text,icon,choices,opts);
182   return box.execute(PLACEMENT_OWNER);
183   }
184 
185 
186 // Show a modal choice dialog, in free floating window
ask(FXApp * app,FXuint opts,const FXString & caption,const FXString & text,FXIcon * icon,const FXchar ** choices)187 FXint FXChoiceBox::ask(FXApp* app,FXuint opts,const FXString& caption,const FXString& text,FXIcon* icon,const FXchar** choices){
188   FXChoiceBox box(app,caption,text,icon,choices,opts);
189   return box.execute(PLACEMENT_SCREEN);
190   }
191 
192 
193 // Show a modal choice dialog, in free floating window
ask(FXApp * app,FXuint opts,const FXString & caption,const FXString & text,FXIcon * icon,const FXString & choices)194 FXint FXChoiceBox::ask(FXApp* app,FXuint opts,const FXString& caption,const FXString& text,FXIcon* icon,const FXString& choices){
195   FXChoiceBox box(app,caption,text,icon,choices,opts);
196   return box.execute(PLACEMENT_SCREEN);
197   }
198 
199 }
200 
201