3006a47b072c8707e8664aa9acaf9fa6d8da321a
[nit.git] / lib / app / ui.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Portable UI API for the _app.nit_ framework
16 module ui
17
18 import app_base
19
20 # Platform variations
21 # TODO: move on the platform once qualified names are understand in the condition
22 import linux::ui is conditional(linux)
23 import android::ui is conditional(android)
24
25 redef class App
26 super AppComponent
27
28 # The current `Window` of this activity
29 #
30 # This attribute must be set by refinements of `App`.
31 var window: Window is writable
32
33 redef fun on_create do window.on_create
34
35 redef fun on_start do window.on_start
36
37 redef fun on_resume do window.on_resume
38
39 redef fun on_pause do window.on_pause
40
41 redef fun on_stop do window.on_stop
42
43 redef fun on_destroy do window.on_destroy
44
45 redef fun on_restore_state do window.on_restore_state
46
47 redef fun on_save_state do window.on_save_state
48 end
49
50 # An event created by an `AppComponent` and sent to `AppObserver`s
51 interface AppEvent
52 end
53
54 # Observer of `AppEvent`s raised by `AppComponent`s
55 interface AppObserver
56 # Notification of `event` raised by `sender`
57 #
58 # To be implemented in subclasses as needed.
59 fun on_event(event: AppEvent) do end
60 end
61
62 redef class AppComponent
63 super AppObserver
64
65 # All `AppObserver` notified of events raised by `self`
66 #
67 # By default, only `self` is an observer.
68 # Any other `AppObserver` can be added to this collection.
69 var observers = new HashSet[AppObserver].from([self: AppObserver])
70
71 # Propagate `event` to all `observers` by calling `AppObserver::on_event`
72 fun notify_observers(event: AppEvent)
73 do
74 for observer in observers do
75 observer.on_event(event)
76 end
77 end
78 end
79
80 # A control implementing the UI
81 class Control
82 super AppComponent
83
84 # Direct parent `Control` in the control tree
85 #
86 # If `null` then `self` is at the root of the tree, or not yet attached.
87 var parent: nullable CompositeControl = null is private writable(set_parent)
88
89 # Direct parent `Control` in the control tree
90 #
91 # Setting `parent` calls `remove` on the old parent and `add` on the new one.
92 fun parent=(parent: nullable CompositeControl)
93 is autoinit do
94 var old_parent = self.parent
95 if old_parent != null and old_parent != parent then
96 old_parent.remove self
97 end
98
99 if parent != null then parent.add self
100
101 set_parent parent
102 end
103 end
104
105 # A `Control` grouping other controls
106 class CompositeControl
107 super Control
108
109 private var items = new HashSet[Control]
110
111 # Add `item` as a child of `self`
112 protected fun add(item: Control) do items.add item
113
114 # Remove `item` from `self`
115 protected fun remove(item: Control) do if has(item) then items.remove item
116
117 # Is `item` in `self`?
118 protected fun has(item: Control): Bool do return items.has(item)
119
120 redef fun on_create do for i in items do i.on_create
121
122 redef fun on_start do for i in items do i.on_start
123
124 redef fun on_resume do for i in items do i.on_resume
125
126 redef fun on_pause do for i in items do i.on_pause
127
128 redef fun on_stop do for i in items do i.on_stop
129
130 redef fun on_destroy do for i in items do i.on_destroy
131
132 redef fun on_restore_state do for i in items do i.on_restore_state
133
134 redef fun on_save_state do for i in items do i.on_save_state
135 end
136
137 # A window, root of the `Control` tree
138 class Window
139 super CompositeControl
140 end
141
142 # A viewable `Control`
143 abstract class View
144 super Control
145
146 # Is this control enabled so the user can interact with it?
147 #
148 # By default, or if set to `null`, the control is enabled.
149 var enabled: nullable Bool is writable #, abstract FIXME with #1311
150 end
151
152 # A control with some `text`
153 abstract class TextView
154 super View
155
156 # Main `Text` of this control
157 #
158 # By default, or if set to `null`, no text is shown.
159 var text: nullable Text is writable #, abstract FIXME with #1311
160 end
161
162 # A control for the user to enter custom `text`
163 class TextInput
164 super TextView
165 end
166
167 # A pushable button, raises `ButtonPressEvent`
168 class Button
169 super TextView
170 end
171
172 # A `Button` press event
173 class ButtonPressEvent
174 super AppEvent
175
176 # The `Button` that raised this event
177 var sender: Button
178 end
179
180 # A layout to visually organize `Control`s
181 abstract class Layout
182 super View
183 super CompositeControl
184 end
185
186 # An horizontal linear organization
187 class HorizontalLayout
188 super Layout
189 end
190
191 # A vertical linear organization
192 class VerticalLayout
193 super Layout
194 end