Jump to content

Recommended Posts

After EmguCV (OpenCV wrapper) UDF , I wanted to improve the concept of generating autoit udf bindings from c/c++ source files.

GTK was a project that get my attention.

That means:

  • It is a heavy  UDF with more that 8900 functions since they were generated from the gtk source files
  • Complex gtk applications can be done with the UDF

Functions keep the same name as in the source files prefixed with an underscore.

The project is available here

Prerequisites

Examples

The classic Hello World

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#Region ; when you don't know where the functions are
; - include all files
; - use Ctrl+J at each function to go to their location
; - add an include of the located file
; - redo until all your functions are found
; - then you can remove the include of gtk_all.au3 which is two times slower to start with
; #include "gtk-autoit-bindings\gtk_all.au3"
#EndRegion ; when you don't know where the functions are

#Region ; when you know where the functions are
#include "gtk-autoit-bindings\include\glib-2.0\gio\gapplication.au3"
#include "gtk-autoit-bindings\include\glib-2.0\gobject\gobject.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkapplication.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkapplicationwindow.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkbutton.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkwindow.au3"
#EndRegion ; when you know where the functions are

#include "gtk-autoit-bindings\gtk_callback.au3"
#include "gtk-autoit-bindings\gtk_extra.au3"

_Gtk_Open("gtk-windows-4.3.2\bin")
main()
_Gtk_Close()

Func print_hello($widget, $data)
  ConsoleWrite("Hello World" & @CRLF)
EndFunc   ;==>print_hello

Func activate($app, $user_data)
  Local $window = _gtk_application_window_new($app)
  _gtk_window_set_title($window, "Window")
  _gtk_window_set_default_size($window, 200, 200)

  Local $button = _gtk_button_new_with_label("Hello World")
  _g_signal_connect($button, "clicked", _gtk_callback("print_hello"), NULL)
  _gtk_window_set_child($window, $button)

  _gtk_window_present($window)
EndFunc   ;==>activate

Func main()
  Local $app = _gtk_application_new("com.autoitscript.gtk.example", $G_APPLICATION_FLAGS_NONE)
  _g_signal_connect($app, "activate", _gtk_callback("activate"), NULL)
  Local $status = _g_application_run($app, 0, 0)
  _g_object_unref($app)
EndFunc   ;==>main

A more complex one

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

; Sources:
; https://docs.gtk.org/gtk4/getting_started.html#packing-buttons-with-gtkbuilder

Opt("MustDeclareVars", 1)

#Region ; when you don't know where the functions are
; - include all files
; - use Ctrl+J at each function to go to their location
; - add an include of the located file
; - redo until all your functions are found
; - then you can remove the include of gtk_all.au3 which is two times slower to start with
; #include "gtk-autoit-bindings\gtk_all.au3"
#EndRegion ; when you don't know where the functions are

#Region ; when you know where the functions are
#include "gtk-autoit-bindings\include\glib-2.0\gio\gapplication.au3"
#include "gtk-autoit-bindings\include\glib-2.0\gio\gfile.au3"
#include "gtk-autoit-bindings\include\glib-2.0\glib\gmem.au3"
#include "gtk-autoit-bindings\include\glib-2.0\gobject\gobject.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkapplication.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkbuilder.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkscrolledwindow.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkstack.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtktextbuffer.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtktextview.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkwidget.au3"
#include "gtk-autoit-bindings\include\gtk-4.0\gtk\gtkwindow.au3"
#EndRegion ; when you know where the functions are

#include "gtk-autoit-bindings\gtk_callback.au3"
#include "gtk-autoit-bindings\gtk_extra.au3"

Local $application = DllStructCreate("ptr window; ptr stack")

_Gtk_Open("gtk-windows-4.3.2\bin")
main()
_Gtk_Close()

Func application_init($app)
    ; Construct a GtkBuilder instance and load our UI description
    Local $builder = _gtk_builder_new()
    _gtk_builder_add_from_file($builder, "window.ui", Null)

    $application.window = _gtk_builder_get_object($builder, "window")
    $application.stack = _gtk_builder_get_object($builder, "stack")

    ; We do not need the builder any more
    _g_object_unref($builder)

    _gtk_window_set_application($application.window, $app)
EndFunc   ;==>application_init

Func activate($app, $user_data)
    application_init($app)

    ; show these files by default
    Local $argv[2] = ["main.au3", "window.ui"]
    Local $file

    For $i = 0 To UBound($argv) - 1
        $file = _g_file_new_for_path($argv[$i])
        open_file($file)
        _g_object_unref($file)
    Next

    _gtk_window_present($application.window)
EndFunc   ;==>activate

Func open_file($file)
    Local $contents = DllStructCreate("ptr value")
    Local $length = DllStructCreate("uint64 value")

    Local $basename = _g_file_get_basename($file)

    Local $scrolled = _gtk_scrolled_window_new()
    _gtk_widget_set_hexpand($scrolled, True)
    _gtk_widget_set_vexpand($scrolled, True)
    Local $view = _gtk_text_view_new()
    _gtk_text_view_set_editable($view, False)
    _gtk_text_view_set_cursor_visible($view, False)
    _gtk_scrolled_window_set_child($scrolled, $view)
    _gtk_stack_add_titled($application.stack, $scrolled, $basename, $basename)

    If _g_file_load_contents($file, Null, $contents, $length, Null, Null) Then
        Local $buffer = _gtk_text_view_get_buffer($view)
        _gtk_text_buffer_set_text($buffer, $contents.value, $length.value)
        _g_free($contents.value)
    EndIf

    _g_free($basename)
EndFunc   ;==>open_file

Func open($app, $files, $n_files, $hint)
    Local $windows = _gtk_application_get_windows($app)
    Local $win

    If $windows Then
        $windows = DllStructCreate($tagGList, $windows)
        $win = $windows.data
    Else
        application_init($app)
        $win = $application.window
    EndIf

    $files = DllStructCreate("ptr value[" & $n_files & "]", $files)
    For $i = 1 To $n_files
        open_file($files.value(($i)))
    Next

    _gtk_window_present($win)
EndFunc   ;==>open

Func main()
    Local $argc = UBound($CmdLine)
    Local $argv = DllStructCreate("ptr value[" & $argc & "]")

    ; create an array to keep reference to structs until the end of the function
    Local $tmp[$argc]
    Local $str

    For $i = 0 To $argc - 1
        $str = $CmdLine[$i]
        $tmp[$i] = DllStructCreate("char value[" & BinaryLen(StringToBinary($str)) + 1 & "]")
        $tmp[$i].value = $str
        $argv.value(($i + 1)) = DllStructGetPtr($tmp[$i])
    Next

    Local $app = _gtk_application_new("com.autoitscript.gtk.example", $G_APPLICATION_HANDLES_OPEN)
    _g_signal_connect($app, "activate", _gtk_callback("activate"), Null) ;
    _g_signal_connect($app, "open", _gtk_callback("open", "none:cdecl", "ptr;ptr;int;str"), Null)

    ; on windows, argv is completely ignored
    ; it is directly taken from the command line
    ; see https://gitlab.gnome.org/GNOME/glib/-/blob/2.69.2/gio/gapplication.c#L2460
    Local $status = _g_application_run($app, $argc, $argv)
    _g_object_unref($app)

    Return $status
EndFunc   ;==>main

window.ui

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <object id="window" class="GtkWindow">
    <property name="title" translatable="yes">Example Application</property>
    <property name="default-width">600</property>
    <property name="default-height">400</property>
    <child type="titlebar">
      <object class="GtkHeaderBar" id="header">
        <child type="title">
          <object class="GtkStackSwitcher" id="tabs">
            <property name="stack">stack</property>
          </object>
        </child>
      </object>
    </child>
    <child>
      <object class="GtkBox" id="content_box">
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkStack" id="stack"/>
        </child>
      </object>
    </child>
  </object>
</interface>

More examples are available here

A note on performance

Before trying to convert everything to the autoit equivalent, keep in mind that autoit is slow when dealing with loops.
For that reason, I recommend to create a dll that export functions that do the loops.
autoit-addon is a dll project example.

 

Link to post
Share on other sites
  • 2 weeks later...
4 hours ago, supersonic said:

Can you provide a ListView example with 10+ columns and at least 1000 rows, please?

It may sound surprising, but I only know the basics of GTK. The UDF was generated by a script.
The things I know can be found in the Docs / Getting Started / Hello World and Gtk - 4.0: Getting Started with GTK

However, if you have a c++ or python code, I can translate it into the UDF for you.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By prazetto
      GTK+ Framework | Widgets

      I'm doing experiment to use GTK+ Widgets on AutoIt3 and seems it sucessfull.
      Its cause some user on AutoIt3 forum requesting it.

      Well there are I'm using V2 of GTK+ which you can get binary file at http://www.gtk.org

      x32
      http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip

      x64
      http://ftp.gnome.org/pub/gnome/binaries/win64/gtk+/2.22/gtk+-bundle_2.22.1-20101229_win64.zip

      Don't get too happy. Because this far from complete.
      As for V3. Maybe I will release if V2 have been completed.

      Hah, its anonnying when get failed on implementing some function!

      So as far my work only go to:
      gtk2.zip (link fixed) or gtk2.zip

      There sample file how to use it.

      Oh yeah copy AutoIt3 Script to 'bin' folder of package you download from gtk.org

      If you interesting to join this project, please let me know. PM or E-Mail me.

      Thanks
       
      Screenshots
      ..
      ..
      ..

×
×
  • Create New...