1 /********************************************************************************
2 *                                                                               *
3 *                              D a t a   T a r g e t                            *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1998,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 #ifndef FXDATATARGET_H
22 #define FXDATATARGET_H
23 
24 #ifndef FXOBJECT_H
25 #include "FXObject.h"
26 #endif
27 
28 namespace FX {
29 
30 
31 /**
32 * A Data Target allows a widget to be directly connected with a associated variable,
33 * without any additional "glue code".  This connection is bi-directional: widgets can
34 * not only only change the associated variable, but also query the associated variable,
35 * and reflect its value in the widget.
36 *
37 * The value of the associated variable is changed by the data target when it receives
38 * a SEL_COMMAND or SEL_CHANGED message from the widget.  Conversely, the widget's state
39 * may be updated from the data target's associated variable when the it receives a
40 * SEL_UPDATE query message from the widget.
41 *
42 * Valuator widgets should send an ID_VALUE message to the data target.  When a data
43 * target receives the ID_VALUE message, it will obtain the value of the sending valuator
44 * widget by querying it with a ID_GETINTVALUE, ID_GETLONGVALUE, ID_GETREALVALUE, or
45 * ID_GETSTRINGVALUE message, depending on the type of the associated variable.
46 *
47 * Radio Buttons, Menu Commands, and so on can also be connected to a data target.
48 * In this case, the widget must send an ID_OPTION+i message; the value of the associated
49 * variable will be obtained from the message itself, by simply subtracting ID_OPTION
50 * from the message ID, that is to say, the value will be i (-10000 <= i <= 10000).
51 *
52 * Updating of widgets from the data target is performed when the widget sends the data
53 * target a SEL_UPDATE message.  For ID_VALUE update queries, the data target responds
54 * with ID_SETINTVALUE, ID_SETLONGVALUE, ID_SETREALVALUE, or ID_SETSTRINGVALUE depending
55 * on the type of the associated variable.
56 * For ID_OPTION+i update queries, the data target responds with a ID_CHECK or ID_UNCHECK
57 * depending on whether the connected variable's value is equal to i or not.
58 *
59 * A data target may be subclassed to handle additional, user-defined data types; to
60 * this end, the message handlers return 1 if the type is one of DT_VOID...DT_STRING
61 * and 0 otherwise.
62 */
63 class FXAPI FXDataTarget : public FXObject {
64   FXDECLARE(FXDataTarget)
65 protected:
66   void         *data;           // Associated data
67   FXObject     *target;         // Target object
68   FXSelector    message;        // Message ID
69   FXuint        type;           // Type of data
70 private:
71   FXDataTarget(const FXDataTarget&);
72   FXDataTarget& operator=(const FXDataTarget&);
73 public:
74   long onCmdValue(FXObject*,FXSelector,void*);
75   long onUpdValue(FXObject*,FXSelector,void*);
76   long onCmdOption(FXObject*,FXSelector,void*);
77   long onUpdOption(FXObject*,FXSelector,void*);
78 public:
79   enum {
80     DT_VOID=0,
81     DT_BOOL,
82     DT_CHAR,
83     DT_UCHAR,
84     DT_SHORT,
85     DT_USHORT,
86     DT_INT,
87     DT_UINT,
88     DT_LONG,
89     DT_ULONG,
90     DT_FLOAT,
91     DT_DOUBLE,
92     DT_STRING,
93     DT_LAST
94     };
95 public:
96   enum {
97     ID_VALUE=1,                   /// Will cause the FXDataTarget to ask sender for value
98     ID_OPTION=ID_VALUE+10001,     /// ID_OPTION+i will set the value to i where -10000<=i<=10000
99     ID_LAST=ID_OPTION+10000
100     };
101 public:
102 
103   /// Associate with nothing
FXDataTarget()104   FXDataTarget():data(NULL),target(NULL),message(0),type(DT_VOID){}
105 
106   /// Associate with nothing
FXDataTarget(FXObject * tgt,FXSelector sel)107   FXDataTarget(FXObject* tgt,FXSelector sel):data(NULL),target(tgt),message(sel),type(DT_VOID){}
108 
109   /// Associate with character variable
110   FXDataTarget(FXbool& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_BOOL){}
111 
112   /// Associate with character variable
113   FXDataTarget(FXchar& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_CHAR){}
114 
115   /// Associate with unsigned character variable
116   FXDataTarget(FXuchar& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_UCHAR){}
117 
118   /// Associate with signed short variable
119   FXDataTarget(FXshort& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_SHORT){}
120 
121   /// Associate with unsigned short variable
122   FXDataTarget(FXushort& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_USHORT){}
123 
124   /// Associate with int variable
125   FXDataTarget(FXint& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_INT){}
126 
127   /// Associate with unsigned int variable
128   FXDataTarget(FXuint& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_UINT){}
129 
130   /// Associate with long variable
131   FXDataTarget(FXlong& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_LONG){}
132 
133   /// Associate with unsigned long variable
134   FXDataTarget(FXulong& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_ULONG){}
135 
136   /// Associate with float variable
137   FXDataTarget(FXfloat& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_FLOAT){}
138 
139   /// Associate with double variable
140   FXDataTarget(FXdouble& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_DOUBLE){}
141 
142   /// Associate with string variable
143   FXDataTarget(FXString& value,FXObject* tgt=NULL,FXSelector sel=0):data(&value),target(tgt),message(sel),type(DT_STRING){}
144 
145 
146   /// Set the message target object for this data target
setTarget(FXObject * t)147   void setTarget(FXObject *t){ target=t; }
148 
149   /// Get the message target object for this data target, if any
getTarget()150   FXObject* getTarget() const { return target; }
151 
152 
153   /// Set the message identifier for this data target
setSelector(FXSelector sel)154   void setSelector(FXSelector sel){ message=sel; }
155 
156   /// Get the message identifier for this data target
getSelector()157   FXSelector getSelector() const { return message; }
158 
159 
160   /// Return type of data its connected to
getType()161   FXuint getType() const { return type; }
162 
163   /// Return pointer to data its connected to
getData()164   void* getData() const { return data; }
165 
166 
167   /// Associate with nothing
connect()168   void connect(){ data=NULL; type=DT_VOID; }
169 
170   /// Associate with FXbool variable
connect(FXbool & value)171   void connect(FXbool& value){ data=&value; type=DT_BOOL; }
172 
173   /// Associate with character variable
connect(FXchar & value)174   void connect(FXchar& value){ data=&value; type=DT_CHAR; }
175 
176   /// Associate with unsigned character variable
connect(FXuchar & value)177   void connect(FXuchar& value){ data=&value; type=DT_UCHAR; }
178 
179   /// Associate with signed short variable
connect(FXshort & value)180   void connect(FXshort& value){ data=&value; type=DT_SHORT; }
181 
182   /// Associate with unsigned short variable
connect(FXushort & value)183   void connect(FXushort& value){ data=&value; type=DT_USHORT; }
184 
185   /// Associate with int variable
connect(FXint & value)186   void connect(FXint& value){ data=&value; type=DT_INT; }
187 
188   /// Associate with unsigned int variable
connect(FXuint & value)189   void connect(FXuint& value){ data=&value; type=DT_UINT; }
190 
191   /// Associate with long variable
connect(FXlong & value)192   void connect(FXlong& value){ data=&value; type=DT_LONG; }
193 
194   /// Associate with unsigned long variable
connect(FXulong & value)195   void connect(FXulong& value){ data=&value; type=DT_ULONG; }
196 
197   /// Associate with float variable
connect(FXfloat & value)198   void connect(FXfloat& value){ data=&value; type=DT_FLOAT; }
199 
200   /// Associate with double variable
connect(FXdouble & value)201   void connect(FXdouble& value){ data=&value; type=DT_DOUBLE; }
202 
203   /// Associate with string variable
connect(FXString & value)204   void connect(FXString& value){ data=&value; type=DT_STRING; }
205 
206 
207   /// Associate with nothing; also set target and message
connect(FXObject * tgt,FXSelector sel)208   void connect(FXObject* tgt,FXSelector sel){ data=NULL; target=tgt; message=sel; type=DT_VOID; }
209 
210   /// Associate with character variable; also set target and message
connect(FXbool & value,FXObject * tgt,FXSelector sel)211   void connect(FXbool& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_BOOL; }
212 
213   /// Associate with character variable; also set target and message
connect(FXchar & value,FXObject * tgt,FXSelector sel)214   void connect(FXchar& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_CHAR; }
215 
216   /// Associate with unsigned character variable; also set target and message
connect(FXuchar & value,FXObject * tgt,FXSelector sel)217   void connect(FXuchar& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_UCHAR; }
218 
219   /// Associate with signed short variable; also set target and message
connect(FXshort & value,FXObject * tgt,FXSelector sel)220   void connect(FXshort& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_SHORT; }
221 
222   /// Associate with unsigned short variable; also set target and message
connect(FXushort & value,FXObject * tgt,FXSelector sel)223   void connect(FXushort& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_USHORT; }
224 
225   /// Associate with int variable; also set target and message
connect(FXint & value,FXObject * tgt,FXSelector sel)226   void connect(FXint& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_INT; }
227 
228   /// Associate with unsigned int variable; also set target and message
connect(FXuint & value,FXObject * tgt,FXSelector sel)229   void connect(FXuint& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_UINT; }
230 
231   /// Associate with long variable; also set target and message
connect(FXlong & value,FXObject * tgt,FXSelector sel)232   void connect(FXlong& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_LONG; }
233 
234   /// Associate with unsigned long variable; also set target and message
connect(FXulong & value,FXObject * tgt,FXSelector sel)235   void connect(FXulong& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_ULONG; }
236 
237   /// Associate with float variable; also set target and message
connect(FXfloat & value,FXObject * tgt,FXSelector sel)238   void connect(FXfloat& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_FLOAT; }
239 
240   /// Associate with double variable; also set target and message
connect(FXdouble & value,FXObject * tgt,FXSelector sel)241   void connect(FXdouble& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_DOUBLE; }
242 
243   /// Associate with string variable; also set target and message
connect(FXString & value,FXObject * tgt,FXSelector sel)244   void connect(FXString& value,FXObject* tgt,FXSelector sel){ data=&value; target=tgt; message=sel; type=DT_STRING; }
245 
246 
247   /// Destroy
248   virtual ~FXDataTarget();
249   };
250 
251 }
252 
253 #endif
254