OptionBox.st
changeset 6468 dbd77c7b3738
parent 6235 c9af202cf052
child 6499 82f16794a274
--- a/OptionBox.st	Thu Oct 25 21:30:16 2018 +0200
+++ b/OptionBox.st	Fri Oct 26 11:03:54 2018 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1991 by Claus Gittinger
 	      All Rights Reserved
@@ -14,7 +16,8 @@
 "{ NameSpace: Smalltalk }"
 
 DialogBox subclass:#OptionBox
-	instanceVariableNames:'labelPanel formLabel textLabel buttons actions defaultButtonIndex'
+	instanceVariableNames:'labelPanel formLabel textLabel textView buttons actions
+		defaultButtonIndex'
 	classVariableNames:'WarnBitmap InfoBitmap YesNoBitmap'
 	poolDictionaries:''
 	category:'Views-DialogBoxes'
@@ -52,13 +55,15 @@
       be moved fully into Dialog, and the subclasses will be replaced by dummy
       delegators. (They will be kept for backward compatibility, though).
 
-
-    OptionBoxes are like YesNoBoxes but with as many buttons as you like;
-    this will finally be a superclass of WarnBox and YesNoBox - or maybe merged
-    all into DialogBox..
-    Use them for multiway questions.
-    For a consistent user interface, the rightmost button is the default return
-    button (i.e. pressing return in the box performs this buttons function).
+    Description:
+      OptionBoxes are like YesNoBoxes but with as many buttons as you like;
+      this will finally be a superclass of WarnBox and YesNoBox - or maybe merged
+      all into DialogBox..
+      Use them for multiway questions.
+      For a consistent user interface, the rightmost (last) button should be the default return
+      button (i.e. pressing return in the box performs this buttons function).
+      However, this is reversed automatically if the viewStyle says so (Windows vs. OSX vs. Linux),
+      so the programmer MUST always put the no-actions (i.e. cancel) first and the ok-actions (yes) last.
 
     [author:]
         Claus Gittinger
@@ -70,6 +75,9 @@
 
 examples
 "
+ just opening 
+ (not real world examples, as you'd have to ask the box instance about the choice afterwards;
+  see better usage examples below):
                                                                         [exBegin]
     |box|
 
@@ -80,8 +88,18 @@
 
                                                                         [exBegin]
     |box|
-    box := OptionBox title:'hello' numberOfOptions:3.
+    box := OptionBox title:'hello'.
     box buttonTitles:#('one' 'two' 'three').
+    box defaultButtonIndex:3.
+    box showAtPointer
+                                                                        [exEnd]
+
+ showing a long list:                                                                    
+                                                                        [exBegin]
+    |box|
+    box := OptionBox title:(1 to:100 collect:#asString) numberOfOptions:3.
+    box buttonTitles:#('one' 'two' 'three').
+    box defaultButtonIndex:3.
     box showAtPointer
                                                                         [exEnd]
 
@@ -139,18 +157,32 @@
 
 !OptionBox class methodsFor:'instance creation'!
 
+title:titleString
+    "create a new optionBox with title, aTitleString"
+
+    |box|
+
+    box := self basicNew.
+    box device:Screen current.
+    box initialize.
+    box title:titleString.
+    ^ box
+
+    "Created: / 26-10-2018 / 10:56:42 / Claus Gittinger"
+!
+
 title:titleString numberOfOptions:nOptions
     "create a new optionBox with title, aTitleString and nOptions options"
 
     |box|
 
     box := self basicNew numberOfOptions:nOptions.
-"/ Later...
-"/    box initializeForDevice:Screen current.
     box device:Screen current.
     box initialize.
     box title:titleString.
     ^ box
+
+    "Modified (comment): / 26-10-2018 / 10:56:48 / Claus Gittinger"
 ! !
 
 !OptionBox class methodsFor:'easy startup'!
@@ -443,8 +475,8 @@
 
 defaultButtonIndex:index
     "define which button is the default (i.e. return-) button.
-     By default, no returnButton is setup. The argument must be an
-     index 1..nButtons, or nil"
+     By default, no returnButton is setup. 
+     The argument must be an index 1..nButtons, or nil"
 
     defaultButtonIndex notNil ifTrue:[
         (buttons at:defaultButtonIndex) isReturnButton:false
@@ -456,7 +488,8 @@
         ].
     ]
 
-    "Modified: 18.10.1996 / 14:53:36 / cg"
+    "Modified: / 18-10-1996 / 14:53:36 / cg"
+    "Modified (comment): / 26-10-2018 / 10:53:10 / Claus Gittinger"
 !
 
 numberOfOptions
@@ -491,6 +524,8 @@
 buttonTitles:titles
     "set the button titles"
 
+    buttons isNil ifTrue:[ self numberOfOptions:titles size; initializeButtons ].
+    
     titles keysAndValuesDo:[:index :aString |
         |b|
 
@@ -499,6 +534,8 @@
         b resize.
     ].
     shown ifTrue:[self resize]
+
+    "Modified: / 26-10-2018 / 11:02:48 / Claus Gittinger"
 !
 
 form:aFormOrImage
@@ -531,14 +568,34 @@
     ^ textLabel
 !
 
-title:aString
+title:aStringOrStringCollection
     "set the boxes title"
 
-    aString ~= textLabel label ifTrue:[
-	textLabel label:aString withoutSeparators.
-	textLabel forceResize.
-	shown ifTrue:[self resize]
+    |textShown lines|
+
+    aStringOrStringCollection isString ifTrue:[
+        textShown := aStringOrStringCollection withoutSeparators.
+    ] ifFalse:[
+        textShown := aStringOrStringCollection asStringCollection.
+    ].        
+    textShown ~= textLabel label ifTrue:[
+        (lines := textShown asStringCollection) size > 25 ifTrue:[
+            verticalPanel verticalLayout:#topFit.
+            textLabel label:''.
+            labelPanel height:(labelPanel preferredHeight).
+            textView beVisible.
+            textLabel beInvisible.
+            textView contents:lines.
+        ] ifFalse:[
+            textView beInvisible.
+            textLabel beVisible.
+            textLabel label:textShown.
+            textLabel forceResize.
+        ].
+        shown ifTrue:[self resize]
     ]
+
+    "Modified: / 26-10-2018 / 10:46:16 / Claus Gittinger"
 !
 
 title:aString numberOfOptions:nOptions
@@ -636,6 +693,12 @@
     textLabel borderWidth:0.
 "/    textLabel origin:((mm + formLabel width + mm) @ mm).
 
+    textView := ScrollableView for:TextView in:verticalPanel.
+    textView backgroundColor:(textLabel backgroundColor).
+    textView viewBackground:(textLabel viewBackground).
+    textView borderWidth:0.
+    textView hiddenOnRealize:true.
+
     verticalPanel resize.
     "/ cannot be done here - verticalPanel still has its defaul height and may be
     "/ not yet filled...
@@ -651,6 +714,20 @@
         borderWidth:0;
         horizontalLayout:#fitSpace.
 
+    self initializeButtons
+
+    "
+     |box|
+
+     box := OptionBox title:'hello' numberOfOptions:4.
+     box open
+    "
+
+    "Modified: / 28-02-2012 / 15:56:57 / cg"
+    "Modified: / 26-10-2018 / 11:00:59 / Claus Gittinger"
+!
+
+initializeButtons
     1 to:(buttons size) do:[:index |
         |button|
 
@@ -660,13 +737,13 @@
                        self hide.
                        (actions at:index) value
                       ].
-"/        index == nButt ifTrue:[
-"/            button isReturnButton:true
-"/        ].
         buttonPanel addSubView:button.
         buttons at:index put:button.
     ].
 
+    "/ no longer make the last button the default!!
+    "/ buttons last isReturnButton:true
+
     "
      |box|
 
@@ -674,7 +751,7 @@
      box open
     "
 
-    "Modified: / 28-02-2012 / 15:56:57 / cg"
+    "Created: / 26-10-2018 / 11:00:50 / Claus Gittinger"
 ! !
 
 !OptionBox methodsFor:'queries'!