'Native' in single-quotes because there is no 'Native' in Linuxes is there?
I think that all of the GNOME projects like GTK are probably what people think of when they think Linux 'Native', right?
There are no real Linux 'Native' Widget examples to go on, but there are some (outdated and not fully functional example) bits of information in the Extension Builder guides.
I quickly had some success:
Code: Select all
widget org.openxtalk.gtkbutton
use com.livecode.canvas
use com.livecode.widget
use com.livecode.engine
use com.livecode.foreign
use com.livecode.arithmetic
use com.livecode.array
use com.livecode.assert
use com.livecode.binary
use com.livecode.bitwise
use com.livecode.byte
use com.livecode.char
use com.livecode.codeunit
use com.livecode.date
use com.livecode.file
use com.livecode.java
use com.livecode.list
use com.livecode.logic
use com.livecode.math
use com.livecode.mathfoundation
metadata title is "GTK Button"
metadata author is "Paul McClernan"
metadata version is "1.0.0"
metadata platforms is "desktop,mobile"
--- If the module makes use of external code that is only
-- available on specific Operating Systems or Platforms, use the "os"
-- and/or "platforms" metadata keys.
-- code/x86-linux/library.so
-- code/x86_64-linux/library.so
--- The key piece of syntax for creating widgets that hook into native view objects is `my native layer`:
--- set my native layer to mNativeView
private variable mNativeLayer as optional Pointer
// Store references to both the plug and button
private variable mPlug as optional Pointer
private variable mNativeView as optional Pointer
private variable mGTKBtn as optional Pointer
--- When using a native layer, a widget's `OnPaint` handler is not called. However it is recommended to provide some sort of
--- placeholder `OnPaint` method to represent the widget when the native layer is not supported on the current platform.
--- It is not yet possible to write a fully functional native widget on Linux, as there are some issues with event handling and focus. This will be addressed in future releases.
--- Native views on Linux are `GtkPlug`s. A `GtkSocket` is used internally to render the view from the process in which it is running. In most instances you will want to embed a `GtkWidget` in a `GtkPlug`.
-- The following snippet shows how to bind to `gtk_button_new_with_label`, and use it to set the native layer to a suitable gtk plug id:
-- Bind to various useful functions in libgtk.
--- We need to create a GTK plug, and GTK button, add the button to the plug and then show them.
foreign handler GTK_PlugNew(in pType as CUInt) returns Pointer binds to "c:libgtk-x11-2.0.so>gtk_plug_new"
foreign handler GTK_ButtonNewWithLabel(in pLabel as ZStringNative) returns Pointer binds to "c:libgtk-x11-2.0.so>gtk_button_new_with_label"
foreign handler GTK_ContainerAdd(in pContainer as Pointer, in pWidget as Pointer) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_container_add"
foreign handler GTK_WidgetShow(in pWidget as Pointer) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_widget_show"
// The actual native layer will be set to the plug id
foreign handler GTK_PlugGetId(in pPlug as Pointer) returns Pointer binds to "c:libgtk-x11-2.0.so>gtk_plug_get_id"
--- Event callbacks are pretty simple on Linux, as you can pass a (foreign) handler into `g_signal_connect_data` directly:
// Define the callback foreign handler type
public foreign handler type ClickCallback(in pWidget as Pointer, in pContext as optional Pointer) returns nothing
// Bind to g_signal_connect_data to connect a foreign handler to a gtk signal
foreign handler GTK_SignalConnect(in pObj as Pointer, in pEvent as ZStringNative, in pHandler as ClickCallback, in pData as optional Pointer, in pNotify as optional Pointer, in pFlags as CUInt) returns CULong binds to "c:libgtk-x11-2.0.so>g_signal_connect_data"
--- Properties of Linux native views can be set using the GTK Widget API.
--- For example, to hook up the enabled property of a Linux button (called "_sensitive_" in the GTK API):
foreign handler GTK_WidgetSetSensitive(in pWidget as Pointer, in pValue as CBool) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_widget_set_sensitive"
public handler OnOpen()
unsafe
put CreateNativeView() into mNativeLayer
set my native layer to mNativeLayer
end unsafe
end handler
private handler OnCreate()
unsafe
put CreateNativeView() into mNativeLayer
set my native layer to mNativeLayer
end unsafe
end handler
private handler OnClose()
unsafe
set my native layer to nothing
put nothing into mNativeLayer
end unsafe
end handler
private handler CreateNativeView() returns Pointer
unsafe
// Create a new default plug
put GTK_PlugNew(0) into mPlug
log ["Plug",mPlug]
// Create a button with empty label
put GTK_ButtonNewWithLabel("TEST BUTTON") into mGTKBtn
log ["Button",mGTKBtn]
GTK_WidgetSetSensitive(mGTKBtn, true)
GTK_SignalConnect(mGTKBtn, "clicked", OnButtonClick, nothing, nothing, 0)
// Add the button to the plug
GTK_ContainerAdd(mPlug, mGTKBtn)
// Ensure both button and plug are visible
GTK_WidgetShow(mGTKBtn)
GTK_WidgetShow(mPlug)
// Return the plug window id
return GTK_PlugGetId(mPlug)
end unsafe
end handler
private handler SetNativeLayer()
unsafe
set my native layer to CreateNativeView()
end unsafe
end handler
private handler OnButtonClick(in pWidget as Pointer, in pContext as optional Pointer) returns nothing
unsafe
// The widget object in LiveCode will receive the posted message
post "mouseUp"
end handler
// Actual handler that will be called when the button is clicked
private handler SignalConnect(in pButtonView as Pointer) returns nothing
unsafe
// Connect the foreign handler to the clicked signal. All other
// parameters are empty/default
GTK_SignalConnect(pButtonView, "clicked", OnButtonClick, nothing, nothing, 0)
end unsafe
end handler
private handler SetEnabled(in pButtonView as Pointer)
unsafe
GTK_WidgetSetSensitive(pButtonView, my enabled)
end unsafe
end handler
end widget
HOWEVER, it only triggers the 'mouseUp' message a single time, then the button seems like it is disabled. I'm thinking this is an object life-cycle issue, but it could be that it button needs to be re-armed by setting that property again?
GTK is a C API, which should kind of make things easy to work out.
Anyway, this is one small small step towards building something like a GStreamer widget.