lib/android: implement `TextAsset`
[nit.git] / lib / android / ui / ui.nit
index a37e572..90c513b 100644 (file)
@@ -1,7 +1,5 @@
 # This file is part of NIT (http://www.nitlanguage.org).
 #
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 # Views and services to use the Android native user interface
 module ui
 
+# Implementation note:
+#
+# We cannot rely on `Activity::on_restore_instance_state` to implement
+# `on_restore_state` is it only invoked if there is a bundled state,
+# and we don't use the Android bundled state.
+
 import native_ui
+import log
+import nit_activity
 
-# An event from the `app.nit` framework
-interface AppEvent
-       # Reaction to this event
-       fun react do end
+import app::ui
+private import data_store
+import assets
+
+redef class Control
+       # The Android element used to implement `self`
+       fun native: NATIVE is abstract
+
+       # Type of `native`
+       type NATIVE: JavaObject
 end
 
-# A control click event
-class ClickEvent
-       super AppEvent
+redef class Window
+       redef var native = app.native_activity.new_global_ref
 
-       # Sender of this event
-       var sender: Button
+       redef type NATIVE: NativeActivity
 
-       redef fun react do sender.click self
-end
+       redef fun add(item)
+       do
+               super
 
-# Receiver of events not handled directly by the sender
-interface EventCatcher
-       fun catch_event(event: AppEvent) do end
+               # FIXME abstract the Android restriction where `content_view` must be a layout
+               assert item isa Layout
+               native.content_view = item.native
+       end
 end
 
-redef class App
-       super EventCatcher
-end
+redef class View
+       redef type NATIVE: NativeView
 
-# An `Object` that raises events
-abstract class Eventful
-       var event_catcher: EventCatcher = app is lazy, writable
+       redef fun enabled=(enabled) do native.enabled = enabled or else true
+       redef fun enabled do return native.enabled
 end
 
-#
-## Nity classes and services
-#
+redef class Layout
+       redef type NATIVE: NativeViewGroup
 
-# An Android control with text
-abstract class TextView
-       super Finalizable
-       super Eventful
+       redef fun add(item)
+       do
+               super
 
-       # Native Java variant to this Nity class
-       type NATIVE: NativeTextView
+               assert item isa View
 
-       # The native Java object encapsulated by `self`
-       var native: NATIVE is noinit
+               # FIXME abstract the use either homogeneous or weight to balance views size in a layout
+               native.add_view_with_weight(item.native, 1.0)
+       end
 
-       # Get the text of this view
-       fun text: String
+       redef fun remove(item)
        do
-               var jstr = native.text
-               var str = jstr.to_s
-               jstr.delete_local_ref
-               return str
+               super
+               if item isa View then native.remove_view item.native
        end
+end
 
-       # Set the text of this view
-       fun text=(value: Text)
-       do
-               var jstr = value.to_s.to_java_string
-               native.text = jstr
-               jstr.delete_local_ref
+redef class HorizontalLayout
+       redef var native do
+               var layout = new NativeLinearLayout(app.native_activity)
+               layout = layout.new_global_ref
+               layout.set_horizontal
+               return layout
        end
+end
+
+redef class VerticalLayout
+       redef var native do
+               var layout = new NativeLinearLayout(app.native_activity)
+               layout = layout.new_global_ref
+               layout.set_vertical
+               return layout
+       end
+end
+
+redef class ListLayout
+       redef type NATIVE: Android_widget_ListView
 
-       # Get whether this view is enabled or not
-       fun enabled: Bool do return native.enabled
+       redef var native do
+               var layout = new Android_widget_ListView(app.native_activity)
+               layout = layout.new_global_ref
+               return layout
+       end
 
-       # Set if this view is enabled
-       fun enabled=(val: Bool) do native.enabled = val
+       private var adapter: Android_widget_ArrayAdapter do
+               var adapter = new Android_widget_ArrayAdapter(app.native_activity,
+                       android_r_layout_simple_list_item_1, self)
+               native.set_adapter adapter
+               return adapter
+       end
 
-       # Set the size of the text in this view at `dpi`
-       fun text_size=(dpi: Numeric) do native.text_size = dpi.to_f
+       redef fun add(item)
+       do
+               super
+               if item isa View then adapter.add item.native
+       end
 
-       private var finalized = false
-       redef fun finalize
+       private fun create_view(position: Int): NativeView
        do
-               if not finalized then
-                       native.delete_global_ref
-                       finalized = true
-               end
+               var ctrl = items[position]
+               assert ctrl isa View
+               return ctrl.native
        end
 end
 
-# An Android button
-class Button
-       super TextView
+redef class Android_widget_ArrayAdapter
+       private new (context: NativeContext, res: Int, sender: ListLayout)
+       import ListLayout.create_view in "Java" `{
+               final int final_sender_object = sender;
 
-       redef type NATIVE: NativeButton
+               return new android.widget.ArrayAdapter(context, (int)res) {
+                               @Override
+                               public android.view.View getView(int position, android.view.View convertView, android.view.ViewGroup parent) {
+                                       return ListLayout_create_view(final_sender_object, position);
+                               }
+                       };
+       `}
+end
 
-       init
-       do
-               var native = new NativeButton(app.native_activity, self)
-               self.native = native.new_global_ref
+redef class TextView
+       redef type NATIVE: NativeTextView
+
+       redef fun text do return native.text.to_s
+       redef fun text=(value) do
+               if value == null then value = ""
+               native.text = value.to_java_string
        end
 
-       # Click event
-       #
-       # By default, this method calls `app.catch_event`. It can be specialized
-       # with custom behavior or the receiver of `catch_event` can be changed
-       # with `event_catcher=`.
-       fun click(event: AppEvent) do event_catcher.catch_event(event)
+       # Size of the text
+       fun text_size: Float do return native.text_size
 
-       private fun click_from_native do click(new ClickEvent(self))
+       # Size of the text
+       fun text_size=(text_size: nullable Float) do
+               if text_size != null then native.text_size = text_size
+       end
 end
 
-# An Android editable text field
-class EditText
-       super TextView
+redef class Label
+       redef type NATIVE: NativeTextView
+       redef var native do return (new NativeTextView(app.native_activity)).new_global_ref
 
+       init do native.set_text_appearance(app.native_activity, android_r_style_text_appearance_medium)
+end
+
+redef class TextInput
        redef type NATIVE: NativeEditText
+       redef var native = (new NativeEditText(app.native_activity)).new_global_ref
+end
 
-       init
-       do
-               var native = new NativeEditText(app.activities.first.native)
-               self.native = native.new_global_ref
-       end
+redef class Button
+       super Finalizable
+
+       redef type NATIVE: NativeButton
+       redef var native = (new NativeButton(app.native_activity, self)).new_global_ref
+
+       private fun on_click do notify_observers new ButtonPressEvent(self)
+
+       redef fun finalize do native.delete_global_ref
 end
 
 redef class NativeButton
-       new (context: NativeActivity, sender_object: Object)
-       import Button.click_from_native in "Java" `{
+       private new (context: NativeActivity, sender_object: Button)
+       import Button.on_click in "Java" `{
                final int final_sender_object = sender_object;
 
                return new android.widget.Button(context){
                        @Override
                        public boolean onTouchEvent(android.view.MotionEvent event) {
                                if(event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
-                                       Button_click_from_native(final_sender_object);
+                                       Button_on_click(final_sender_object);
                                        return true;
                                }
                                return false;