app.nit: fix name of `align` parameter for use in autoinit
[nit.git] / lib / app / ui.nit
index 2e30c76..cb45ac2 100644 (file)
@@ -17,13 +17,42 @@ module ui
 
 import app_base
 
+# Platform variations
+import linux::ui is conditional(linux)
+import android::ui is conditional(android)
+import ios::ui is conditional(ios)
+
 redef class App
        super AppComponent
 
        # The current `Window` of this activity
        #
-       # This attribute must be set by refinements of `App`.
-       var window: Window is writable
+       # This attribute is set by `push_window`.
+       var window: Window is noinit
+
+       # Make visible and push `window` on the top of `pop_window`
+       #
+       # This method must be called at least once within `App::on_create`.
+       # It can be called at any times while the app is active.
+       fun push_window(window: Window)
+       do
+               window_stack.add window
+               self.window = window
+       end
+
+       # Pop the current `window` from the stack and show the previous one
+       #
+       # Require: `window_stack.not_empty`
+       fun pop_window
+       do
+               assert window_stack.not_empty
+               window_stack.pop
+               window = window_stack.last
+               window.on_resume
+       end
+
+       # Stack of active windows
+       var window_stack = new Array[Window]
 
        redef fun on_create do window.on_create
 
@@ -101,16 +130,19 @@ end
 class CompositeControl
        super Control
 
-       private var items = new HashSet[Control]
+       protected var items = new Array[Control]
 
        # Add `item` as a child of `self`
        protected fun add(item: Control) do items.add item
 
        # Remove `item` from `self`
-       protected fun remove(item: Control) do if has(item) then items.remove item
+       fun remove(item: Control) do if has(item) then items.remove item
 
        # Is `item` in `self`?
-       protected fun has(item: Control): Bool do return items.has(item)
+       fun has(item: Control): Bool do return items.has(item)
+
+       # Remove all items from `self`
+       fun clear do for item in items.to_a do remove item
 
        redef fun on_create do for i in items do i.on_create
 
@@ -132,6 +164,12 @@ end
 # A window, root of the `Control` tree
 class Window
        super CompositeControl
+
+       # Should the back button be shown and used to go back to a previous window?
+       fun enable_back_button: Bool do return app.window_stack.length > 1
+
+       # The back button has been pressed, usually to open the previous window
+       fun on_back_button do app.pop_window
 end
 
 # A viewable `Control`
@@ -141,7 +179,7 @@ abstract class View
        # Is this control enabled so the user can interact with it?
        #
        # By default, or if set to `null`, the control is enabled.
-       var enabled: nullable Bool is writable #, abstract FIXME with #1311
+       var enabled: nullable Bool is writable, abstract, autoinit
 end
 
 # A control with some `text`
@@ -151,12 +189,37 @@ abstract class TextView
        # Main `Text` of this control
        #
        # By default, or if set to `null`, no text is shown.
-       var text: nullable Text is writable #, abstract FIXME with #1311
+       var text: nullable Text is writable, abstract, autoinit
+
+       # Set the relative size of the text
+       #
+       # A value of 1.0, the default, use the platform default text size.
+       # Values under 1.0 set a smaller text size, and over 1.0 a larger size.
+       #
+       # Implementation varies per platform, and some controls may be unaffected
+       # depending on the customization options of each platform.
+       # For consistent results, it is recommended to use only on instances
+       # of `Label` and `size` should be either 0.5, 1.0 or 1.5.
+       fun size=(size: nullable Float) is autoinit do end
+
+       # Align the text horizontally
+       #
+       # Use 0.0 to align left (the default), 0.5 to align in the center and
+       # 1.0 to align on the right.
+       #
+       # Implementation varies per platform, and some controls may be unaffected
+       # depending on the customization options of each platform.
+       # For consistent results, it is recommended to use only on instances
+       # of `Label` and `size` should be either 0.0, 0.5 or 1.0.
+       fun align=(align: nullable Float) is autoinit do end
 end
 
 # A control for the user to enter custom `text`
 class TextInput
        super TextView
+
+       # Hide password or any content entered in this view?
+       var is_password: nullable Bool is writable
 end
 
 # A pushable button, raises `ButtonPressEvent`
@@ -164,12 +227,42 @@ class Button
        super TextView
 end
 
+# A text label
+class Label
+       super TextView
+end
+
+# Toggle control with two states and a label
+class CheckBox
+       super TextView
+
+       # Is this control in the checked/on state?
+       var is_checked = false is writable
+end
+
+# Event sent from a `VIEW`
+class ViewEvent
+       super AppEvent
+
+       # The `VIEW` that raised this event
+       var sender: VIEW
+
+       # Type of the `sender`
+       type VIEW: View
+end
+
 # A `Button` press event
 class ButtonPressEvent
-       super AppEvent
+       super ViewEvent
+
+       redef type VIEW: Button
+end
 
-       # The `Button` that raised this event
-       var sender: Button
+# The `CheckBox` `sender` has been toggled
+class ToggleEvent
+       super ViewEvent
+
+       redef type VIEW: CheckBox
 end
 
 # A layout to visually organize `Control`s
@@ -187,3 +280,9 @@ end
 class VerticalLayout
        super Layout
 end
+
+# Scrollable list of views in a simple list
+class ListLayout
+       super View
+       super CompositeControl
+end