This PR intro a service to open a URL using the platform default browser, and an example for the UI API. The example uses most of the available controls, multiple windows and the new `open_in_browser` feature.
The changes to `core::exec` are updates for compatibility with `Text`, and some minor improvements to its doc.
Pull-Request: #2206
Reviewed-by: Jean Privat <jean@pryen.org>
};
`}
end
+
+redef class Text
+ redef fun open_in_browser
+ do to_java_string.native_open_in_browser(app.native_activity)
+end
+
+redef class JavaString
+ private fun native_open_in_browser(context: NativeContext)
+ in "Java" `{
+ android.content.Intent intent = new android.content.Intent(
+ android.content.Intent.ACTION_VIEW,
+ android.net.Uri.parse(self));
+ context.startActivity(intent);
+ `}
+end
## Usage Example
-The calculator example (at `../../examples/calculator/src/calculator.nit`) is a concrete,
-simple and complete use of the _app.nit_ portable UI.
+The example at `examples/ui_example.nit` shows off most features of `app::ui` in a minimal program.
+You can also take a look at the calculator (`../../examples/calculator/src/calculator.nit`) which is a concrete usage example.
## Platform-specific UI
http_request_example
-http_request_example.apk
-http_request_example.app
+ui_example
+*.apk
+*.app
-all: http_request_example
+all: http_request_example ui_example
+
+android: http_request_example.apk ui_example.apk
+
+ios: http_request_example.app ui_example.app
http_request_example: $(shell nitls -M http_request_example.nit linux)
nitc http_request_example.nit -m linux
http_request_example.app: $(shell nitls -M http_request_example.nit ios)
nitc http_request_example.nit -m ios
+
+ui_example: $(shell nitls -M ui_example.nit linux)
+ nitc ui_example.nit -m linux
+
+ui_example.apk: $(shell nitls -M ui_example.nit android)
+ nitc ui_example.nit -m android
+
+ui_example.app: $(shell nitls -M ui_example.nit ios)
+ nitc ui_example.nit -m ios
+
+clean:
+ rm -rf http_request_example http_request_example.apk http_request_example.app ui_example ui_example.apk ui_example.app
# limitations under the License.
# Example for the `app::http_request` main service `AsyncHttpRequest`
-module http_request_example
+module http_request_example is
+ app_name "app.nit HTTP"
+ app_namespace "org.nitlanguage.http_example"
+ android_api_target 15
+end
import app::ui
import app::http_request
+import android::aware # for android_api_target
# Simple asynchronous HTTP request to http://example.com/ displaying feedback to the window
class MyHttpRequest
super Window
# Root layout
- var layout = new VerticalLayout(parent=self)
+ var layout = new ListLayout(parent=self)
# Button to send request
var button_request = new Button(parent=layout, text="Press to send HTTP request")
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# 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
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# User interface example using `app::ui`
+module ui_example is
+ app_name "app.nit UI"
+ app_namespace "org.nitlanguage.ui_example"
+ android_api_target 15
+end
+
+import app::ui
+import app::data_store
+import android::aware # for android_api_target
+
+# Window showing off some the available controls
+class UiExampleWindow
+ super Window
+
+ # Root layout
+ var layout = new ListLayout(parent=self)
+
+ # Some label
+ var some_label = new Label(parent=layout, text="This Window uses a ListLayout.")
+
+ # A checkbox
+ var checkbox = new CheckBox(parent=layout, text="A CheckBox")
+
+ # Horizontal organization
+ var h_layout = new HorizontalLayout(parent=layout)
+
+ # Description for the `user_input`
+ var user_input_label = new Label(parent=h_layout, text="Input some text:", align=0.5)
+
+ # Field for the user to enter data
+ var user_input = new TextInput(parent=h_layout, text="Default text")
+
+ # Button to open a new window with a ListLayout
+ var button_window = new Button(parent=layout, text="Open a new window")
+
+ # URL to open
+ var example_url = "http://nitlanguage.org/"
+
+ # Button to open the browser
+ var button_browser = new Button(parent=layout, text="Open {example_url}")
+
+ redef fun on_event(event)
+ do
+ if event isa ButtonPressEvent then
+ if event.sender == button_browser then
+ example_url.open_in_browser
+ else if event.sender == button_window then
+ app.push_window new SecondWindow
+ end
+ else if event isa ToggleEvent then
+ if event.sender == checkbox then checkbox.text = if checkbox.is_checked then "Checked" else "Unchecked"
+ end
+ end
+end
+
+# Another window with a small `VerticalLayout`
+class SecondWindow
+ super Window
+
+ # Root layout
+ var layout = new VerticalLayout(parent=self)
+
+ # Some label
+ var a_label = new Label(parent=layout, text="This window uses a VerticalLayout.")
+
+ # Another label
+ var another_label = new Label(parent=layout, text="Close it by tapping the back button.")
+end
+
+redef class App
+ redef fun on_create
+ do
+ # Create the main window
+ push_window new UiExampleWindow
+ super
+ end
+end
super View
super CompositeControl
end
+
+redef class Text
+ # Open the URL `self` with the default browser
+ fun open_in_browser do print_error "Text::open_in_browser not implemented on this platform."
+end
end
# The status once finished
+ #
+ # Require: `is_finished`
fun status: Int
do
assert is_finished
return data.status
end
- # The executable run
- # Is a filepath, or a executable found in PATH
- var command: String
+ # The target executable
+ # Either a file path or the name of an executable available in PATH.
+ var command: Text
# The arguments of the command
# Starts with the first real arguments---ie. does not include the progname (`argv[0]`, in C)
- var arguments: nullable Array[String]
+ var arguments: nullable Array[Text]
# Launch a command with some arguments
- init(command: String, arguments: String...) is old_style_init do
+ init(command: Text, arguments: Text...) is old_style_init do
self.command = command
self.arguments = arguments
execute
end
# Launch a simple command with arguments passed as an array
- init from_a(command: String, arguments: nullable Array[String])
+ init from_a(command: Text, arguments: nullable Array[Text])
do
self.command = command
self.arguments = arguments
execute
end
- # flags used internally to know whith pipe to open
+ # Flags used internally to know which pipe to open
private fun pipeflags: Int do return 0
# Internal code to handle execution
protected fun execute
do
- # The pass the arguments as a big C string where elements are separated with '\0'
+ # Pass the arguments as a big C string where elements are separated with '\0'
var args = new FlatBuffer
var l = 1 # Number of elements in args
args.append(command)
if arguments != null then
for a in arguments do
args.add('\0')
- #a.output_class_name
args.append(a)
end
l += arguments.length
# ~~~
fun write_and_read(input: Text): String
do
- var read = new Buffer #new Array[String]
+ var read = new Buffer
# Main loop, read and write line by line
var prev = 0
redef class Sys
# Execute a shell command and return its error code
- fun system(command: String): Int
+ fun system(command: Text): Int
do
return command.to_cstring.system
end
self.dataSource = objc_delegate;
`}
end
+
+redef class Text
+ redef fun open_in_browser do to_nsstring.native_open_in_browser
+end
+
+redef class NSString
+ private fun native_open_in_browser
+ in "ObjC" `{
+ NSURL *nsurl = [NSURL URLWithString: self];
+ [[UIApplication sharedApplication] openURL: nsurl];
+ `}
+end
super
end
end
+
+redef class Text
+ redef fun open_in_browser do system("xdg-open '{self.escape_to_sh}' &")
+end