source: trunk/MESOSCALE/PLOT/MINIMAL/fsc/fsc_droplist.pro @ 205

Last change on this file since 205 was 85, checked in by aslmd, 14 years ago

LMD_MM_MARS et LMD_LES_MARS: ajout des routines IDL pour tracer les sorties --> voir mesoscale/PLOT

File size: 21.3 KB
Line 
1;+
2; NAME:
3;   FSC_DROPLIST
4;
5; PURPOSE:
6;
7;   The purpose of this compound widget is to provide an alternative
8;   to the DROPLIST widget offered in the IDL distribution. What has
9;   always annoyed me about a droplist is that you can't get the current
10;   "value" of a droplist easily. This compound widget makes this and
11;   other tasks much easier.
12;
13; AUTHOR:
14;
15;   FANNING SOFTWARE CONSULTING
16;   David Fanning, Ph.D.
17;   1645 Sheely Drive
18;   Fort Collins, CO 80526 USA
19;   Phone: 970-221-0438
20;   E-mail: davidf@dfanning.com
21;   Coyote's Guide to IDL Programming: http://www.dfanning.com/
22;
23; CATEGORY:
24;
25;   General programming.
26;
27; CALLING SEQUENCE:
28;
29;   droplistObj = FSC_Droplist(parent, Title='Animals: ", Value=['Dog'. 'Cat', 'Coyote'], Index=2)
30;
31;   The return value of the FSC_Droplist (droplistObj in this example) is
32;   an object reference. Interaction with the droplist will occur through
33;   object methods.
34;
35; INPUT PARAMETERS:
36;
37;   parent -- The parent widget ID of the compound widget. Required.
38;
39; INPUT KEYWORDS:
40;
41; Any keyword that is appropriate for the Widget_Droplist function can be used.
42; In addition, these keywords are explicitly defined.
43;
44;   EVENT_FUNC -- Set this keyword to the name of an Event Handler Function.
45;   EVENT_PRO -- Set this keyword to the name of an Event Handler Procedure.
46;   FORMAT -- A format specifier for the "format" of the values in the droplist.
47;   INDEX -- The index number of the current selection.
48;   SPACES -- A two-element array that indicates the number of blank spaces to be added
49;             to the the beginning and end of the formatted values. If a single number
50;             is provided, this number of blank spaces is added to both the beginning
51;             and the end of the value.
52;   TITLE -- The title of the droplist widget.
53;   UNAME -- The user name of the droplist widget. (Only available in IDL 5.2 and higher.)
54;   UVALUE -- The normal "user value" of the droplist.
55;   VALUE -- An array of the droplist "selections". May be any data type.
56;
57; COMMON BLOCKS:
58;
59;   None.
60;
61; DEPENDENCIES:
62;
63;   Requires ERROR_MESSAGE from the Coyote Library..
64;
65; EVENT STRUCTURE:
66;
67;   An event is returned each time the droplist value is changed. The event structure
68;   is defined like this:
69;
70;   event = { FSC_DROPLIST_EVENT, $ ; The name of the event structure.
71;             ID: 0L, $             ; The ID of the compound widget's top-level base.
72;             TOP: 0L, $            ; The widget ID of the top-level base of the hierarchy.
73;             HANDLER: 0L, $        ; The event handler ID. Filled out by IDL.
74;             INDEX: 0L, $          ; The index number of the current selection.
75;             SELECTION:Ptr_New() $ ; A pointer to the current selection "value".
76;             SELF:Obj_New() }      ; The object reference of the compound widget.
77;
78; PUBLIC OBJECT METHODS:
79;
80;   GetID -- A function with no arguments that returns the widget identifier
81;      of the droplist widget.
82;
83;      droplistID = droplistObj->GetID()
84;
85;   GetIndex -- A function with no arguments that returns the index
86;      number of the current droplist selection.
87;
88;      currentIndex = droplistObj->GetIndex()
89;
90;   GetSelection -- A function with no arguments that returns the current
91;      droplist selection.
92;
93;      currentSelection = droplistObj->GetSelection()
94;
95;   GetUValue -- A function with no arguments that returns the "user value"
96;      of the compound widget i.e., the value set with the UVALUE keyword).
97;
98;      myUValue = droplistObj->GetUValue()
99;
100;   GetValues -- A function with no arguments that returns the "values" or
101;      "selections" for the droplist.
102;
103;      possibleSelections = droplistObj->GetValues()
104;
105;   Resize -- A procedure that sets the X screen size of the droplist. It is
106;      defined like this:
107;
108;      PRO Resize, newSize, ParentSize=parentSize
109;
110;      The "newSize" keyword is the new X screen size. If this argument is
111;      missing, the screen X size of the compound widget's parent is used.
112;      The parentSize keyword is an output keyword that returns the X screen
113;      size of the compound widget's parent.
114;
115;      droplistObj->Resize, 400
116;
117;      Note that not all devices (e.g., X Windows devices) support droplist resizing.
118;
119;   SetIndex -- A procedure that sets the current droplist selection based on
120;      the given index. This is equivalent to Widget_Control, droplistID, Set_Droplist_Select=newIndex
121;
122;      droplistObj->SetIndex, newIndex
123;
124;   SetSelection -- Whereas a regular droplist widget can only be set by index
125;      number, this compound widget can also be set by a "selection". The new selection
126;      can be any data type and corresponds to one of the "values" of the droplist.
127;
128;      droplistObj->SetSelection, newSelection
129;
130;   SetValues -- Sets the possible selections of the droplist widget. The CurrentIndex keyword
131;      will allow the current index of the selection to be changed to:
132;
133;      newChoices = ['dog', 'cat', 'coyote']
134;      droplistObj->SetValues, newChoices, CurrentIndex=2
135;
136;
137; EXAMPLE:
138;
139;   An example program is provided at the end of the FSC_DROPLIST code. To run it,
140;   type these commands:
141;
142;      IDL> .Compile FSC_DROPLIST
143;      IDL> Example
144;
145; MODIFICATION HISTORY:
146;
147;   Written by: David W Fanning, 17 Jan 2000. DWF.
148;   Added FORMAT and SPACES keywords 28 April 2000. DWF.
149;   Fixed a small problem with event processing when the EVENT_FUNC keyword
150;      was used. 29 Dec 2000. DWF.
151;   Attached the UNAME value to the TLB of the compound widget instead
152;      of to the droplist widget itself. 11 Jan 2001. DWF.
153;   Fixed a problem when the droplist was part of a modal widget and used the
154;      EVENT_PRO keyword. 27 Oct 2003. DWF.
155;   Added a SetValue method for setting all the values in the droplist at once. 12 Nov 2004. DWF.
156;   Fixed type on line 346/ 6 Feb 2008. DWF.
157;-
158;###########################################################################
159;
160; LICENSE
161;
162; This software is OSI Certified Open Source Software.
163; OSI Certified is a certification mark of the Open Source Initiative.
164;
165; Copyright 2000-2008 Fanning Software Consulting
166;
167; This software is provided "as-is", without any express or
168; implied warranty. In no event will the authors be held liable
169; for any damages arising from the use of this software.
170;
171; Permission is granted to anyone to use this software for any
172; purpose, including commercial applications, and to alter it and
173; redistribute it freely, subject to the following restrictions:
174;
175; 1. The origin of this software must not be misrepresented; you must
176;    not claim you wrote the original software. If you use this software
177;    in a product, an acknowledgment in the product documentation
178;    would be appreciated, but is not required.
179;
180; 2. Altered source versions must be plainly marked as such, and must
181;    not be misrepresented as being the original software.
182;
183; 3. This notice may not be removed or altered from any source distribution.
184;
185; For more information on Open Source Software, visit the Open Source
186; web site: http://www.opensource.org.
187;
188;###########################################################################
189;
190
191
192
193PRO FSC_Droplist_Kill_Notify, droplistID
194
195; This procedure is called automatically when the droplist is destroy. The
196; purpose is to destroy the self object so there are no memory leaks.
197
198Widget_Control,droplistID, Get_UValue=self
199Obj_Destroy, self
200END ;--------------------------------------------------------------------------
201
202
203FUNCTION FSC_Droplist::EventHandler, event
204
205; This is the event handler method of the object. The purpose is to set the
206; object's current selection and index number. If an event handler has
207; been specified, a FSC_DROPLIST event is sent to the proper event handler.
208
209   ; Set the current selection and index number.
210
211*self.selection = (*self.value)[event.index]
212self.index = event.index
213
214   ; If we need to send an event package the event up. Include both
215   ; the index number (what normal droplist events produce), the current
216   ; selection, and the self object reference.
217
218thisEvent = {FSC_Droplist_EVENT, ID:self.tlb, TOP:event.top, HANDLER:event.handler, $
219 INDEX:self.index, SELECTION:self.selection, SELF:self}
220
221   ; Send the event if requested. If it is requested, no events returned.
222
223IF self.event_pro NE "" THEN BEGIN
224   Call_Procedure, self.event_pro, thisEvent
225   thisEvent = 0
226   IF Obj_Valid(self) EQ 0 THEN RETURN, thisEvent ; Modal widget destroyed.
227ENDIF
228
229IF self.event_func NE "" THEN BEGIN
230   ok = Call_Function(self.event_func, thisEvent)
231   thisEvent = 0
232ENDIF
233
234RETURN, thisEvent
235END ;--------------------------------------------------------------------------
236
237
238
239FUNCTION FSC_Droplist_Events, event
240
241; This is the droplist event handler. The purpose of this procedure is to
242; get the self object reference and call the object's own event method.
243; The event handler method will return 0 if an event handler procedure or
244; function has been called. Otherwise, it will return the event.
245
246Widget_Control, event.id, Get_UValue=self
247theEvent = self->EventHandler(event)
248RETURN, theEvent
249END ;--------------------------------------------------------------------------
250
251
252
253PRO FSC_Droplist::Sensitive, value
254
255; This method makes the droplist sensitive (value=1) or insensitive (value=0).
256
257Widget_Control, self.droplistID, Sensitive=value
258END ;--------------------------------------------------------------------------
259
260
261
262PRO FSC_Droplist::Resize, newSize,  ParentSize=parentSize
263
264; This method resizes the droplist. If the variable "newSize" is not provided,
265; the new size is set by the parent widget's X screen size. This makes it possible
266; to have the droplist sized to fit it's parent base widget.
267
268   ; Get the parent widget's geometry and X screen size.
269
270parentGeometry = Widget_Info(self.parent, /Geometry)
271parentSize = parentGeometry.scr_xsize
272
273   ; Has a size been provided? In not, use the parent's X screen size.
274
275IF N_Elements(newSize) EQ 0 THEN BEGIN
276   newSize = parentGeometry.scr_xsize
277ENDIF
278
279   ; Resize the droplist widget.
280
281Widget_Control, self.droplistID, Scr_XSize=newSize
282END ;--------------------------------------------------------------------------
283
284
285
286PRO FSC_Droplist::SetSelection, selection
287
288; This method sets the current selection of the droplist by means of
289; the selection "value". With a normal droplist you must set the selection
290; by specifying an index number.
291
292   ; Find the selection in the value. Return it's index number.
293
294IF N_Elements(selection) EQ 0 THEN selection = (*self.value)[0]
295index = Where(StrUpCase( Strtrim(*self.value,2) ) EQ StrUpCase( StrTrim(selection,2) ), count)
296
297   ; If you can't find the selection, print an error message.
298
299IF count EQ 0 THEN BEGIN
300   uname = Widget_Info(self.droplistID,/UName)
301   ok = Error_Message('No item with name "' + uname + ':' + $
302      StrTrim(selection,2) + '" exists. Returning...')
303   RETURN
304ENDIF
305
306   ; Set the current index and selection for the object.
307
308index = 0 > index < (N_Elements(*self.value) - 1)
309self.index = index
310*self.selection = selection
311
312   ; Set the current selection for the droplist widget.
313
314Widget_Control, self.droplistID, Set_Droplist_Select=self.index
315END ;--------------------------------------------------------------------------
316
317
318
319PRO FSC_Droplist::SetIndex, index
320
321; This method sets the current selection by means of its index number.
322
323   ; Make sure the index number is there and valid.
324
325IF N_Elements(index) EQ 0 THEN index = 0
326self.index = 0 > index < (N_Elements(*self.value) - 1)
327
328   ; Set the current selection.
329
330*self.selection = (*self.value)[index]
331
332   ; Set the selection on the droplist widget.
333
334Widget_Control, self.droplistID, Set_Droplist_Select=self.index
335
336END ;--------------------------------------------------------------------------
337
338
339
340PRO FSC_Droplist::SetValues, theValues, CurrentIndex=currentIndex
341
342; This method allows all the values in the droplist to be changed simultaneously.
343
344  IF Ptr_Valid(self.value) THEN *self.value = theValues ELSE self.value = Ptr_New(theValues)
345  Widget_Control, self.droplistID, Set_Value=*self.value
346
347  IF N_Elements(currentIndex) EQ 0 THEN currentIndex = self.index ELSE self.index = currentIndex < (N_Elements(theValues)-1)
348  IF currentIndex GT (N_Elements(*self.value)-1) THEN BEGIN
349     currentIndex = 0
350     self.index = currentIndex
351  ENDIF
352  IF Ptr_Valid(self.selection) THEN *self.selection = (*self.value)[self.index] ELSE $
353    self.selection = Ptr_New((*self.value)[self.index])
354  Widget_Control, self.droplistID, Set_Droplist_Select=self.index
355END ;--------------------------------------------------------------------------
356
357
358
359FUNCTION FSC_Droplist::GetIndex
360
361; This method returns the index number of the current selection.
362
363RETURN, self.index
364END ;--------------------------------------------------------------------------
365
366
367
368FUNCTION FSC_Droplist::GetSelection
369
370; This method returns the "value" of the current selection.
371
372RETURN, *self.selection
373END ;--------------------------------------------------------------------------
374
375
376
377FUNCTION FSC_Droplist::GetValues
378
379; This method returns the current "values" or "selections" of the droplist.
380
381RETURN, *self.value
382END ;--------------------------------------------------------------------------
383
384
385
386FUNCTION FSC_Droplist::GetUValue
387
388; This method returns the "user value" of the droplist.
389
390RETURN, *self.storage
391END ;--------------------------------------------------------------------------
392
393
394
395FUNCTION FSC_Droplist::GetID
396
397; This method returns the droplist widget identifier.
398
399RETURN, self.droplistID
400END ;--------------------------------------------------------------------------
401
402
403
404PRO FSC_Droplist::CLEANUP
405
406; This is the object's cleanup method. Free's up all the pointers used in the
407; object.
408
409Ptr_Free, self.value
410Ptr_Free, self.selection
411Ptr_Free, self.storage
412END ;--------------------------------------------------------------------------
413
414
415
416FUNCTION FSC_Droplist::INIT, $
417   parent, $                    ; The widget ID of the droplist's parent widget. Required.
418   debug=debug, $               ; Turns full error handling on for INIT catch error handler.
419   Event_Func=event_func, $     ; The name of an event handler function.
420   Event_Pro=event_pro, $       ; The name of an event handler procedure.
421   _Extra=extra, $              ; A keyword that allows any droplist keyword to be used in initialization.
422   Format=format, $             ; The format of the "value" of the droplist.
423   Index=index, $               ; The index number of the current selection.
424   Spaces=spaces, $             ; Number of blank spaces to add to formatted "values".
425   Title=title, $               ; The text that goes in the TITLE of the droplist.
426   UName=uname, $               ; A user name. Left for the user of the cw_droplist program.
427   UValue=storage, $            ; A user value. Left for the user of the cw_droplist program.
428   Value=value                  ; The "value" or selections of the droplist. May be any data type.
429
430   ; Catch any errors.
431
432Catch, theError
433IF theError NE 0 THEN BEGIN
434   Catch, /Cancel
435   ok = Error_Message(!Error_State.Msg, Traceback=Keyword_Set(debug))
436   RETURN, 0
437ENDIF
438
439; This is the object's initialization method.
440
441IF N_Elements(parent) EQ 0 THEN BEGIN
442   ok = Error_Message('Parent parameter must be provided. Returning...')
443   RETURN, 0
444ENDIF
445
446   ; Check for presence of keywords.
447
448IF N_Elements(title) EQ 0 THEN title = 'Selection: '
449IF N_Elements(value) EQ 0 THEN value = ['Dog', 'Cat', 'Coyote']
450IF N_Elements(storage) EQ 0 THEN storage = ""
451IF N_Elements(index) EQ 0 THEN index = 0
452IF N_Elements(event_pro) EQ 0 THEN event_pro = ""
453IF N_Elements(event_func) EQ 0 THEN event_func = ""
454IF N_Elements(uname) EQ 0 THEN uname = ""
455IF N_Elements(spaces) EQ 0 THEN BEGIN
456   forwardSpace = ""
457   trailingSpace = ""
458ENDIF ELSE BEGIN
459   IF N_Elements(spaces) EQ 2 THEN BEGIN
460      IF spaces[0] LE 0 THEN forwardSpace = "" ELSE forwardSpace = String(Replicate(32B,spaces[0]))
461      IF spaces[1] LE 0 THEN trailingSpace = "" ELSE trailingSpace = String(Replicate(32B,spaces[1]))
462   ENDIF ELSE BEGIN
463      IF spaces[0] LE 0 THEN forwardSpace = "" ELSE forwardSpace = String(Replicate(32B,spaces[0]))
464      IF spaces[0] LE 0 THEN trailingSpace = "" ELSE trailingSpace = String(Replicate(32B,spaces[0]))
465   ENDELSE
466ENDELSE
467index = 0 > index < (N_Elements(value) - 1)
468
469   ; Create the droplist widget. UName only available for IDL 5.2 and higher.
470
471IF Float(!Version.Release) GE 5.2 THEN BEGIN
472
473   IF Keyword_Set(format) THEN theValue = String(value, Format=format) ELSE theValue = StrTrim(value,2)
474   self.tlb = Widget_Base(parent, UValue=storage, UName=uname)
475   self.droplistID = Widget_Droplist(self.tlb, $
476         Title=title, $
477         Value=forwardSpace + theValue + trailingSpace, $
478         _Extra=extra, $
479         Kill_Notify='FSC_Droplist_Kill_Notify', $
480         Event_Func='FSC_Droplist_Events', $
481         UValue=self)
482
483 ENDIF ELSE BEGIN
484
485   IF Keyword_Set(format) THEN theValue = String(value, Format=format) ELSE theValue = StrTrim(value,2)
486   self.tlb = Widget_Base(parent, UValue=storage)
487   self.droplistID = Widget_Droplist(self.tlb, $
488         Title=title, $
489         Value=forwardSpace + theValue + trailingSpace, $
490         _Extra=extra, $
491         Kill_Notify='FSC_Droplist_Kill_Notify', $
492         Event_Func='FSC_Droplist_Events', $
493         UValue=self)
494
495ENDELSE
496
497   ; Set the current selection on the droplist.
498
499selection = Value[index]
500Widget_Control, self.droplistID, Set_Droplist_Select=index
501
502   ; Populate the object.
503
504self.storage = Ptr_New(storage)
505self.index = index
506self.title = title
507self.parent = parent
508self.selection = Ptr_New(selection)
509self.event_func = event_func
510self.event_pro = event_pro
511self.value = Ptr_New(value)
512
513RETURN, 1
514END ;--------------------------------------------------------------------------
515
516
517
518PRO FSC_Droplist__DEFINE
519
520   struct = { FSC_Droplist, $          ; The FSC_DROPLIST object class definition.
521              title:"", $              ; The droplist title.
522              value:Ptr_New(), $       ; The values or selections on the droplist.
523              parent:0L, $             ; The widget identifer of the parent widget.
524              tlb:0L, $                ; The top-level base of the compound widget. .
525              droplistID:0L, $         ; The droplist widget identifier.
526              selection:Ptr_New(), $   ; The current droplist selection.
527              storage:Ptr_New(), $     ; The storage locaton for the "user value".
528              event_pro:"", $          ; The name of an event handler procedure.
529              event_func:"", $         ; The name of an event handler function.
530              index:0 $                ; The index number of the current selecton.
531            }
532END ;--------------------------------------------------------------------------
533
534
535
536FUNCTION FSC_Droplist, parent, Title=title, Value=value, _Extra=extra
537
538   ; This is the compound widget function call. It's purpose is to
539   ; create the compound widget object and return it.
540
541RETURN, Obj_New('FSC_Droplist', parent, Title=title, Value=value, _Extra=extra)
542END ;--------------------------------------------------------------------------
543
544
545
546PRO Example_Events, event
547Widget_Control, event.top, Get_UValue=droplists
548thisEvent = Tag_Names(event, /Structure_Name)
549CASE thisEvent OF
550   'FSC_DROPLIST_EVENT': BEGIN
551      thisDroplist = event.self->GetUValue()
552      Print, ""
553      Print, thisDroplist + ' Selection: ', *event.selection
554      Print, thisDroplist + ' Index Number: ', event.index
555      ENDCASE
556   'WIDGET_BUTTON': BEGIN
557      Widget_Control, event.id, Get_UValue=thisValue
558      CASE thisValue OF ; Set the droplists by "selection".
559         'SET_DROPLIST1': droplists[0]->SetSelection, 'Coyote'
560         'SET_DROPLIST2': droplists[1]->SetSelection, 99.8
561         ELSE: Widget_Control, event.top, /Destroy
562      ENDCASE
563      ENDCASE
564ENDCASE
565END ;---------------------------------------------------------------------------
566
567
568PRO Example
569
570; Droplist 1 is filled with string selections.
571; Droplist 2 is filled with number selections.
572
573tlb = Widget_Base(Title='FSC_Droplist Example', Column=1)
574animals = ['Dog', 'Cat', 'Opposum', 'Coyote']
575numbers = [45.6, 18.3, 21.5, 99.8]
576
577   ; Create the droplists.
578
579droplist1 = FSC_Droplist(tlb, Value=animals, Index=3, UValue='DROPLIST 1')
580droplist2 = FSC_Droplist(tlb, Value=numbers, Index=1, UValue='DROPLIST 2', $
581   Format='(F5.2)', Spaces=[2,0], Debug=1)
582
583   ; Other widgets.
584
585button = Widget_Button(tlb, Value='Set Droplist 1 to "Coyote"', UValue='SET_DROPLIST1')
586button = Widget_Button(tlb, Value='Set Droplist 2 to 99.8', UValue='SET_DROPLIST2')
587button = Widget_Button(tlb, Value='Quit', UValue='QUIT')
588
589   ; Resize the droplists.
590
591droplist1->Resize, 200
592droplist2->Resize, 200
593
594Widget_Control, tlb, /Realize, Set_UValue=[droplist1, droplist2]
595XManager, 'Example', tlb, Event_Handler='Example_Events', /No_Block
596
597; Test of SetValues method:
598;      Wait, 2
599;      newChoices = ['dog', 'cat', 'coyote']
600;      droplist1->SetValues, newChoices, CurrentIndex=2
601
602END ;---------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.