User Tools

Site Tools


blog:xscalawt_stylesheets

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
blog:xscalawt_stylesheets [2009/03/05 00:38]
djo Clarified
blog:xscalawt_stylesheets [2014/10/17 22:08] (current)
Line 1: Line 1:
 +====== XScalaWT Stylesheets ======
 +
 +Tonight I finished a first cut at adding style sheet support to XScalaWT. ​ I'm interested in peoples'​ thoughts/​suggestions on the syntax and so forth.
 +
 +Here's how to define a style sheet in XScalaWT:
 +
 +<code java>
 +val WHITE = Display.getDefault.getSystemColor(SWT.COLOR_WHITE)
 +val RED = Display.getDefault.getSystemColor(SWT.COLOR_RED)
 +val INVALID_INPUT="​INVALID_INPUT"​
 +
 +object loginStyles extends Stylesheet(
 +  $[Control] (       // all Controls have a white background
 +    _.setBackground(WHITE)
 +  ),
 +  ​
 +  $class[Control](INVALID_INPUT) (
 +    _.setForeground(RED)
 +  )
 +)
 +</​code>​
 +
 +Here we're defining a login dialog box.  We want the entire background to be white, and we want to define a style class that can be used to control how things look when there'​s invalid input in the dialog.
 +
 +(Note that I changed the dollar-sign syntax to mean $tyle, rather than to be the generic object construction syntax. ​ We will see the new generic object construction syntax next.)
 +
 +Here is how we can use this style sheet:
 +
 +<code java>
 +var passwordLabel : Label = null
 +
 +val window = shell("​Please log in",
 +  group("​User information",​
 +    setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false)),
 +    setLayout(new GridLayout(1,​ false)),
 +  ​
 +    label("​Username"​),​
 +    text (
 +      setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false))
 +    ),
 +
 +    label(""​),​
 +
 +    label("​Password",​ passwordLabel = _),
 +    *[Text](SWT.BORDER | SWT.PASSWORD) (     // The manual, "​specify everything"​ syntax
 +      setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false))
 +    )
 +  ),
 +  ​
 +  // OK/Cancel buttons
 +  composite (
 +    setLayoutData(new GridData(SWT.CENTER,​ SWT.CENTER, false, false)),
 +    setLayout(new GridLayout(2,​ true)),
 +
 +    button("​OK",​ { e : SelectionEvent => passwordLabel.setStyleClass(INVALID_INPUT) }),
 +    button("​Cancel",​ { e : SelectionEvent => e.widget.asInstanceOf[Button].getShell.close() } )
 +  )
 +)
 +loginStyles.apply(window)
 +</​code>​
 +
 +Here we actually lay out our login dialog. ​ We apply the style sheet to the dialog on the last line of code.  And to prove that we can update a given widget'​s style class after the fact and have it automatically update, we make the OK button set the password label'​s style. ​ The result is that clicking "​OK"​ will turn the password label red.
 +
 +(This is accomplished by using Scala implicits to type-safe add the setStyleClass method to Widget and all of its subclasses.)
 +
 +The XScalaWT style sheet support is implemented in exactly 100 lines of Scala, including white space--another illustration of how flexible and expressive Scala is.
 +
 +As usual, full XScalaWT source code is available at [[http://​bitbucket.org/​djo/​xscalawt/​]]
 +
 +For reference, here is the source code to the entire example:
 +
 +<code java>
 +object LoginBoxStyled {
 +  def main(args : Array[String]) : Unit = {
 +    val WHITE = Display.getDefault.getSystemColor(SWT.COLOR_WHITE)
 +    val RED = Display.getDefault.getSystemColor(SWT.COLOR_RED)
 +
 +    var passwordLabel : Label = null
 +    ​
 +    val INVALID_INPUT="​INVALID_INPUT"​
 +
 +    object loginStyles extends Stylesheet(
 +      $[Control] (
 +        _.setBackground(WHITE)
 +      ),
 +   ​
 +      $class[Control](INVALID_INPUT) (
 +        _.setForeground(RED)
 +      )
 +    )
 +    ​
 +    val window = shell("​Please log in",
 +      group("​User information",​
 +        setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false)),
 +        setLayout(new GridLayout(1,​ false)),
 +      ​
 +        label("​Username"​),​
 +        text (
 +          setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false))
 +        ),
 +
 +        label(""​),​
 +
 +        label("​Password",​ passwordLabel = _),
 +        *[Text](SWT.BORDER | SWT.PASSWORD) (     // The manual, "​specify everything"​ syntax
 +          setLayoutData(new GridData(SWT.FILL,​ SWT.CENTER, true, false))
 +        )
 +      ),
 +      ​
 +      // OK/Cancel buttons
 +      composite (
 +        setLayoutData(new GridData(SWT.CENTER,​ SWT.CENTER, false, false)),
 +        setLayout(new GridLayout(2,​ true)),
 +
 +        button("​OK",​ { e : SelectionEvent => passwordLabel.setStyleClass(INVALID_INPUT) }),
 +        button("​Cancel",​ { e : SelectionEvent => e.widget.asInstanceOf[Button].getShell.close() } )
 +      )
 +    )
 +    loginStyles.apply(window)
 +
 +    window.pack
 +    val size = window.getSize()
 +    window.setSize(250,​ size.y)
 +
 +    runEventLoop(window)
 +  }
 +}
 +</​code>​
 +
 +~~LINKBACK~~
 +~~DISCUSSION~~