Updated GTK headers (GTK-2 and GTK-3)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Updated GTK headers (GTK-2 and GTK-3)

Post by TJF »

A new set of headers for GTK, all dependencies and some (also new) extensions is avialable. These headers are ment to substitute the current headers in the next FB release. So please test and report before they find their way into the final release. (In addition I added a header for SQLiteExtensions 3.6.23.1.)

The archive contains headers for the last GTK-2 version 2.24.1 and for GTK-3.0 with all depencies (2.8 Mb):
  • inc/atk/atk.bi« (1).
    inc/cairo/cairo-gl.bi« (2).
    inc/cairo/cairo-pdf.bi« (3).
    inc/cairo/cairo-ps.bi« (4).
    inc/cairo/cairo-svg.bi« (5).
    inc/cairo/cairo-win32.bi« (6).
    inc/crt/bits/locale.bi« (7).
    inc/crt/locale.bi« (8).
    inc/crt/xlocale.bi« (9).
    inc/gio/gio.bi« (10).
    inc/gtk/gdk-pixbuf/gdk-pixbuf.bi« (11).
    inc/gtk/gdk-2.24.bi« (12).
    inc/gtk/gdk-3.0.bi« (13).
    inc/gtk/gdk.bi« (14).
    inc/gtk/gdkgl.bi« (15).
    inc/gtk/gdkglext.bi« (16).
    inc/gtk/goocanvas.bi« (17).
    inc/gtk/gtk-2.24.bi« (18).
    inc/gtk/gtk-3.0.bi« (19).
    inc/gtk/gtk.bi« (20).
    inc/gtk/gtkgl.bi« (21).
    inc/gtk/gtkglext.bi« (22).
    inc/pango/pango.bi« (23).
    inc/pango/pangocairo.bi« (24).
    inc/cairo.bi« (25).
    inc/glib.bi« (26).
    inc/glib-object.bi« (27).
    inc/gmodule.bi« (28).
    inc/libintl.bi« (29).
    inc/sqlite3ext.bi« (30).
To install these files first rename (or remove) the 'gtk' folder in 'FreeBasic/inc'. Then unpack all files from the 7z archive mentioned below in to the 'FreeBasic/inc' folder. (Mixing old and new files in the 'gtk' folder will lead to 'duplicated definition errors'.)

By default
  • #INCLUDE ONCE "gtk/gtk.bi"
compiles against GTK-2. To switch to GTK-3 use
  • #DEFINE __FB_GTK3__
    #INCLUDE ONCE "gtk/gtk.bi"
(or use #INCLUDE ONCE "gtk/gtk-3.0.bi" directly). Instead, if you have an old GTK installation (as in FB releases up to 0.23), you can prepend
  • #DEFINE __FB_GTK_OLD__
    #INCLUDE ONCE "gtk/gtk.bi"
to omit the new libraries (GIO/PangoCairo).


The archive also contains reviewed examples. Some of the existing examples uses deprecated widgets and shouldn't be used at all. These I moved into a GTK-2 folder.

Most examples I could update so they can be used with both, GTK-2 and GTK-3. Also I added a few new examples for GooCanvas, for GLib, for Cairo and for GTK-3 (only). And both examples for libglade I replaced by one GtkBuilder example, the .glade files are replaced by a similar and an extended GtkBuilder GUI-XML-files.

These examples are included (452 Kb)
  • cairo/clock.bas
    cairo/cairo_output.bas
    cairo/cairo_elipsis.bas

    glib/g_Actions.bas
    glib/g_Arguments.bas
    glib/g_Assert.bas
    glib/g_Filenames.bas
    glib/g_HashTable.bas
    glib/g_SplitArguments.bas
    glib/g_VarArgMacros.bas

    Gtk/combo_test.bas
    Gtk/filechooser_test.bas
    Gtk/GtkBuilder.bas (and .ui/.png files)
    Gtk/GtkVersionCheck.bas
    Gtk/text_buffer.bas
    Gtk/Tutorials/arrow.bas
    Gtk/Tutorials/aspectframe.bas
    Gtk/Tutorials/base.bas
    Gtk/Tutorials/buttonbox.bas
    Gtk/Tutorials/calendar.bas
    Gtk/Tutorials/colorsel.bas
    Gtk/Tutorials/entry.bas
    Gtk/Tutorials/eventbox.bas
    Gtk/Tutorials/fixed.bas
    Gtk/Tutorials/frame.bas
    Gtk/Tutorials/helloworld.bas
    Gtk/Tutorials/helloworld2.bas
    Gtk/Tutorials/imagebutton.bas
    Gtk/Tutorials/label.bas
    Gtk/Tutorials/menu.bas
    Gtk/Tutorials/notebook.bas
    Gtk/Tutorials/packbox.bas
    Gtk/Tutorials/paned.bas
    Gtk/Tutorials/progressbar.bas
    Gtk/Tutorials/radiobuttons.bas
    Gtk/Tutorials/rangewidgets.bas
    Gtk/Tutorials/scrolledwin.bas
    Gtk/Tutorials/spinbutton.bas
    Gtk/Tutorials/statusbar.bas
    Gtk/Tutorials/table.bas
    Gtk/Tutorials/textview.bas
    Gtk/Tutorials/toolbar.bas

    Gtk/GooCanvas/demo-animation.bas
    Gtk/GooCanvas/demo-arrowhead.bas
    Gtk/GooCanvas/demo-features.bas
    Gtk/GooCanvas/demo-focus.bas
    Gtk/GooCanvas/demo-item.bas
    Gtk/GooCanvas/demo-table.bas
    Gtk/GooCanvas/goocanvas-2.0.0_Test.bas
    Gtk/GooCanvas/GooGrid.bas

    Gtk/FB_Calc/FB_Calc.bas (and others)

    Gtk-2/Tutorials_deprecated/clist.bas
    Gtk-2/Tutorials_deprecated/filesel.bas
    Gtk-2/Tutorials_deprecated/list.bas
    Gtk-2/Tutorials_deprecated/pixmap.bas
    Gtk-2/Tutorials_deprecated/rulers.bas
    Gtk-2/Tutorials_deprecated/scribble-simple.bas
    Gtk-2/Tutorials_deprecated/tree.bas
    Gtk-2/gdk_image.bas
    Gtk-2/opengl_button.bas

    Gtk-3/GtkBuilder_Cairo.bas
    Gtk-3/gtk_applicationE110.bas
I tested all files at 32 bit: windows XP and Ubuntu 11.04.

Download:

Headers, examples (as described above) and import libraries (DLL.a - 1.7 Mb .7z)
Binaries for windows (DLLs - 6.7 Mb .7z)

Again: please download and test before they are included into the next FB release. (We need test results for newer windows versions!)

EDIT: Hints for installation added.
Last edited by TJF on Nov 26, 2011 21:33, edited 1 time in total.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Post by dkl »

Looking interesting. I did start taking a look at the headers and .def files, though I can't do much testing. There seem to be some left-overs from the translation process that should perhaps be cleaned up.

I think it's ok the way they're organized, with the possibility to #include gtk.bi, gtk-2.24.bi or gtk-3.0.bi directly. Although __FB_GTK3__ should be renamed, so __FB_*__ stays reserved for built-in defines.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

dkl wrote:There seem to be some left-overs from the translation process that should perhaps be cleaned up.
I guess you're talking about the comments that mark the start and the end of the single files and the skiped INCLUDEs. I can (and like to) remove them.

I left this inside because some people asked for separating the files into the original file structure. But now this headers are published since month (and there are lots of downloads) and nobody did separate them. So it seems that nobody needs separated headers.
dkl wrote:I think it's ok the way they're organized, with the possibility to #include gtk.bi, gtk-2.24.bi or gtk-3.0.bi directly. Although __FB_GTK3__ should be renamed, so __FB_*__ stays reserved for built-in defines.
There's a second precompiler directive called __FB_GTK_OLD__ ATM.

How to rename them? __GTK_3__ / __GTK_OLD__ ? (But they are no GTK directives and used in FB headers only. __GTK_3_FB__ / __GTK_OLD_FB__ or __GTK_3_bi__ / __GTK_OLD_bi__ ? )
AGS
Posts: 1284
Joined: Sep 25, 2007 0:26
Location: the Netherlands

Post by AGS »

I've got win7 and will check if examples etc.... work on my machine (using fbc 023).
nobozoz
Posts: 238
Joined: Nov 17, 2005 6:24
Location: Chino Hills, CA, USA

Post by nobozoz »

Assuming C:\freebasic\, how are these files supposed to be installed after extraction so that the examples will compile with a minimum of hassle.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

nobozoz wrote:Assuming C:\freebasic\, how are these files supposed to be installed after extraction so that the examples will compile with a minimum of hassle.
There're several ways to do so. Here's an easy method (consuming HDD space):
  • make copies of your folders bin, examples, inc and lib inside C:\freebasic\ (ie name them 'bin_', 'examples_', 'inc_' and 'lib_').
  • download the archives from the first post and extract them (open the freebasic folder in the archive and extract the subfolders to C:\freebasic\, overwrite existing files)
  • compile and run the new files in the 'examples\libraries' folder (find them by sorting by date or check the list above).
To restore your system
  • remove the new folders bin, examples, inc and lib.
  • rename the copies ('bin_' -> 'bin', 'examples_' -> 'examples', ...)
Good luck! I'm looking forward to read your reports.
wallyg
Posts: 270
Joined: May 08, 2009 7:08
Location: Tucson Arizona

Post by wallyg »

TJF wrote:
nobozoz wrote:Assuming C:\freebasic\, how are these files supposed to be installed after extraction so that the examples will compile with a minimum of hassle.
There're several ways to do so. Here's an easy method (consuming HDD space):
  • make copies of your folders bin, examples, inc and lib inside C:\freebasic\ (ie name them 'bin_', 'examples_', 'inc_' and 'lib_').
  • download the archives from the first post and extract them (open the freebasic folder in the archive and extract the subfolders to C:\freebasic\, overwrite existing files)
  • compile and run the new files in the 'examples\libraries' folder (find them by sorting by date or check the list above).
To restore your system
  • remove the new folders bin, examples, inc and lib.
  • rename the copies ('bin_' -> 'bin', 'examples_' -> 'examples', ...)
Good luck! I'm looking forward to read your reports.
I tried running one of the examples (File Chooser) provided.

I loaded up a fresh copy of FreeBASIC 0.23 and followed the directions as specified above. On a windows 7 system completely up to date.

Compiles without error. When I click on Run. I get a Windows 7 window that specifies. "The program can't start because libgobject-2.0-0.dll is missing from your computer. Try reinstalling the program to fix this problem."

I tried adding the directory path where this file is to my enviroment Path variable with the same result. I tried a #libpath command to this directory path same result. I also tried putting the file in the source code directory same result. I even tried putting it in C:\Windows\System32\ with the same result. Where do I put the *.dll files so that the linker can find them and get rid of of this error.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

Hello wallyg, thanks for testing and and thanks for your report.
wallyg wrote:I tried adding the directory path where this file is to my enviroment Path variable with the same result. I tried a #libpath command to this directory path same result. I also tried putting the file in the source code directory same result. I even tried putting it in C:\Windows\System32\ with the same result. Where do I put the *.dll files so that the linker can find them and get rid of of this error.
#LIBPATH works for the linker only, it specifies the path to the *.dll.a import libraries. This works well, since you compiled successfully.

When you execute the program a runtime loader searches for the *.dll files. At least nine *.dll files are needed and the loader searches
  • in the actual folder
  • in all folders specified by your path environment variable.
So your first solution should work. Make sure that all *.dll files from the Gtk_Bin.7z archive are available.
AGS
Posts: 1284
Joined: Sep 25, 2007 0:26
Location: the Netherlands

Post by AGS »

GTK3 reared it's ugly head on win7.

I got the following message
(gtk_applicatione110.exe:3476): GLib-GIO-CRITICAL **: Cannot determine session bus address (not implemented for this OS)
when executing a gtk3 example (gtk_applicatione110.bas). I am not 100% sure but most gtk3 programs should work on windows. The part that does not work is the part the demo uses

Code: Select all

VAR status = g_application_run (G_APPLICATION (bloat_pad), __FB_ARGC__, __FB_ARGV__)
And I'm wondering why there are no parameter names in the header files (good job on the byval though).

The demos work though. And nice demos they are. That goo canvas thingy is fun. My brix program (tcl port) is almost done. Drag-n-drop is a bit hard to get right in goo canvas. Perhaps that´ll change in the future (or perhaps I'm doing something wrong?).

Code: Select all

#define SCALE_STEP 0.1

#INCLUDE ONCE "gtk/GTK-2.22.0_TJF.bi"
#INCLUDE ONCE "gtk/goocanvas-2.0.0.bi"

#ifndef NIL
#define NIL 0
#endif

type context__ as context_

type item_function as function (byval opt as integer, byval context as context__ ptr) as GooCanvasItem ptr

type context_
  dim canvas as GtkWidget ptr
  dim root as GooCanvasItem ptr
  dim mould as GooCanvasItem ptr          
  dim drawing as GooCanvasItem ptr
  dim drawn as GooCanvasItem ptr
  dim background as GooCanvasItem ptr
  dim funs as item_function ptr           ''array of functions responsible for drawing items in mould
  dim num_items as integer                ''number of items in mould
  dim drag_item as GooCanvasItem ptr      ''the item that is being dragged
  dim drag_x as double                    ''x value of item getting dragged at start of drag
  dim drag_y as double                    ''y value of item getting dragged at start of drag
  dim item_x as double                    ''x value of item getting dragged at end of drag
  dim item_y as double                    ''y value of item getting dragged at end of drag
  dim item_width as double                ''the width of the dragged item
  dim item_height as double               ''the height of the dragged item
  dim dragging as integer                 ''flag (dragging?)
end type

#define Xmax 1000
#define Ymax 1000

''Brix
''
''This example is a port of a tcl/tk program implementing a simple drawing program.

''On the left you see objects that can be placed on the canvas by drag-and-drop.
''These objects on the left are referred to collectively as 'the mould'. Items that are in
''the mould form a group.

''You can click on items in the mould and drop them on the right hand side of 
''the window. You cannot drop an item inside the mould.

''Drag-and-drop has been implemented by putting an item on top of
''each item in the mould. When clicking on an item in the mould the top
''item is the item that gets selected and dragged/dropped. As soon as a drag ends
''the dragged item is moved to another group. The items in the mould get 
''renewed (items are drawn on top of the mould items).

''The items that are on top of the items in the mould are member of the group drawing.

''A drop operation will not lead to the creation of items in the drawing group when
''an item is dropped on top of the mold. Dropping an item on the mold (or, for that matter,
''on the background) will remove the dropped item from the canvas. 

''Pushing button C will remove all the items from the group drawn (it clears the canvas but
''not the mould).
''Pushing + will scale all the items up by SCALE_STEP.
''Pushing - will scale all the items down by SCALE_STEP.

''Brix has been implemented using goocanvas (not part of official GTK+ but implemented on
''top of/using GTK+)

''To compile you need GTK+ version 0.22 (both dynamic libraries and import libraries).
''You also need the necessary header files. The header files and the source code 
''are part of the package you can download here. The GTK+ binaries you can download 
''here.

function on_button_drawn_press_event_cb cdecl (_
                                   byval item as GooCanvasItem ptr,_
                                   byval target_item as GooCanvasItem ptr,_
                                   byval event as GdkEventButton ptr,_
                                   byval context as context_ ptr ) As gboolean

    context->drag_item = target_item
    context->drag_x = event->x
    context->drag_y = event->y

    g_object_get (G_OBJECT (target_item),_
                  "x", @context->item_x,_
                  "y", @context->item_y,_
                  "width", @context->item_width,_
                  "height", @context->item_height,_
                  NIL)
  
   goo_canvas_pointer_grab (GOO_CANVAS(context->canvas), target_item, _
                            GDK_POINTER_MOTION_MASK or GDK_POINTER_MOTION_HINT_MASK or _
                            GDK_BUTTON_RELEASE_MASK, NIL, event->time)
   return TRUE
   
end function


function on_button_drawing_press_event_cb cdecl (_
                                   byval item as GooCanvasItem ptr,_
                                   byval target_item as GooCanvasItem ptr,_
                                   byval event as GdkEventButton ptr,_
                                   byval context as context_ ptr ) As gboolean

    var list = goo_canvas_get_items_at(GOO_CANVAS(context->canvas),event->x,event->y,FALSE)
    
    if (list <> NIL) then
      var item1 = g_list_first(list)
      ''only deal with items that are part of the drawing group
      while (item1 <> NIL)
        var parent = goo_canvas_item_get_parent(item1->data)
        if (parent = context->drawing) then
          context->drag_item = item1->data
          context->drag_x = event->x
          context->drag_y = event->y
          g_object_get (G_OBJECT (item1->data),_
                        "x", @context->item_x,_
                        "y", @context->item_y,_
                        "width", @context->item_width,_
                        "height", @context->item_height,_
                        NIL)
          goo_canvas_pointer_grab (GOO_CANVAS(context->canvas), item1->data, GDK_POINTER_MOTION_MASK or GDK_POINTER_MOTION_HINT_MASK or _
                               GDK_BUTTON_RELEASE_MASK, NIL, event->time)
          return TRUE
        end if
        item1 = g_list_next(item1)
      wend
      g_list_free(list)
    end if
    return TRUE
    
end function


function on_button_drawn_release_event_cb cdecl (byval item as GooCanvasItem  ptr,_
                                     byval target_item as GooCanvasItem ptr,_
                                     byval event as GdkEventButton ptr,_
                                     byval context as context_ ptr) as gboolean


  if (context->drag_item = target_item andalso context->drag_item <> NIL) then
    var list = goo_canvas_get_items_at(GOO_CANVAS(context->canvas),event->x,event->y,FALSE)
    var ll = g_list_length(list)
    if (ll) then
      var cur_item = g_list_first(list)
      while (cur_item <> NIL)
        ''do not allow dropping items onto the mould
        if (cur_item = context->background) then
          goo_canvas_pointer_ungrab (GOO_CANVAS(context->canvas), context->drag_item, event->time)
          goo_canvas_item_remove(target_item)
          context->drag_item = NIL
          g_list_free(list)
          return TRUE
        end if
        cur_item = g_list_next(list)
      wend      
    end if    
    goo_canvas_pointer_ungrab (GOO_CANVAS(context->canvas), context->drag_item, event->time)
    context->drag_item = NIL
    return TRUE
  end if

  return FALSE

end function

function on_button_drawing_release_event_cb cdecl (byval item as GooCanvasItem  ptr,_
                                     byval target_item as GooCanvasItem ptr,_
                                     byval event as GdkEventButton ptr,_
                                     byval context as context_ ptr) as gboolean

  dim bounding_box1 as goocanvasbounds
  dim bounding_box2 as goocanvasbounds 


  if (context->drag_item = target_item andalso context->drag_item <> NIL) then
    var list = goo_canvas_get_items_at(GOO_CANVAS(context->canvas),event->x,event->y,FALSE)
    var num_items = g_list_length(list)
    if (num_items) then
      var cur_item = g_list_first(list)
      while (cur_item <> NIL)
        ''do not allow dropping items onto the mould
        if (cur_item->data = context->background) then
          goo_canvas_pointer_ungrab (GOO_CANVAS(context->canvas), context->drag_item, event->time)
          goo_canvas_item_remove(target_item)
          context->drag_item = NIL          
          g_list_free(list)
          return TRUE
        end if
        cur_item = g_list_next(cur_item)
      wend
      g_list_free(list)
    end if
    goo_canvas_pointer_ungrab (GOO_CANVAS(context->canvas), context->drag_item, event->time)
    var parent = goo_canvas_item_get_parent(target_item)
    ''put item in the drawn group so it can be cleared
    if (parent <> context->drawn) then
      g_object_set(G_OBJECT(target_item),"parent",context->drawn)
    end if    
    context->drag_item = NIL
    ''redraw items on top of mould
    for i as integer = 1 to context->num_items
      var drawn_item = context->funs[i](1,context)    
    next i    
    ''remove items in group drawing that have been drawn on top of an item
    ''in group drawing. It would be more efficient to just redraw one item (the one
    ''that changed group).

    ''get all the items that are member of the group drawing
    dim background_area as GooCanvasBounds
    goo_canvas_item_get_bounds(context->background,@background_area)    
    var item_list = goo_canvas_get_items_in_area(GOO_CANVAS(context->canvas),@background_area,TRUE,TRUE,FALSE)
    var len_ = g_list_length(item_list)
    var next_ = g_list_first(item_list)
    redim drawing_list(0 to len_ - 1) as GooCanvasItem ptr
    dim ct as integer = 0 
    while (next_ <> NIL)
      var data_ = next_->data
      var parent = goo_canvas_item_get_parent(data_)
      if (parent = context->drawing) then
         drawing_list(ct) = data_
         ct += 1
      end if
      next_ = g_list_next(next_)
    wend
    redim preserve drawing_list(0 to ct)
    ''remove item if item was painted on top of an item from the drawing group
    dim lb as integer = lbound(drawing_list)
    dim ub as integer = ubound(drawing_list)
    for ct = lb to ub
      goo_canvas_item_get_bounds(drawing_list(ct),@bounding_box1)
      for idx as integer = lb to ub
        if (idx <> ct) then
          goo_canvas_item_get_bounds(drawing_list(idx),@bounding_box2)
          if (bounding_box2. x1 = bounding_box1.x1  andalso _
              bounding_box2. x2 = bounding_box1.x2  andalso _
              bounding_box2. y1 = bounding_box1.y1  andalso _
              bounding_box2. y2 = bounding_box1.y2 ) then
            ''two items in group drawing on top of each other -> drop item 
            goo_canvas_item_remove(drawing_list(idx))           
          end if
        end if
      next idx
    next ct
    g_list_free(item_list)    
    return TRUE
  end if

  return FALSE

end function


function on_motion_drawn_notify_event_cb cdecl (byval item as GooCanvasItem ptr,_
                                    byval target_item as GooCanvasItem ptr,_
                                    byval event as GdkEventMotion ptr,_
                                    byval context as context_ ptr) as gboolean

  if (context->drag_item = target_item andalso context->drag_item <> NIL) then
     dim rel_x as gdouble = event->x - context->drag_x
     dim rel_y as gdouble = event->y - context->drag_y
     g_object_set (G_OBJECT (target_item), "x", context->item_x + rel_x, "y", context->item_y + rel_y, NIL)
    return TRUE
  end if

  return FALSE

end function

function on_motion_drawing_notify_event_cb cdecl (byval item as GooCanvasItem ptr,_
                                    byval target_item as GooCanvasItem ptr,_
                                    byval event as GdkEventMotion ptr,_
                                    byval context as context_ ptr) as gboolean

  if (context->drag_item = target_item andalso context->drag_item <> NIL) then
     dim rel_x as gdouble = event->x - context->drag_x
     dim rel_y as gdouble = event->y - context->drag_y
     g_object_set (G_OBJECT (target_item), "x", context->item_x + rel_x, "y", context->item_y + rel_y, NIL)
    return TRUE
  end if

  return FALSE

end function


''GTKWidget callbacks (buttons clear, + and -)
function clear_cb cdecl alias "clear_cb"(byval widget as gtkwidget ptr,byval context as context_ ptr) as integer

  ''remove all the items that are in the drawing
  dim x as double
  dim y as double
  dim scale as double
  dim rotation as double
  dim item as GooCanvasItem ptr
  
  ''remove entire group
  goo_canvas_item_get_simple_transform(context->drawn,@x,@y,@scale,@rotation)
  var idx = goo_canvas_item_find_child(context->root,context->drawn)
  goo_canvas_item_remove_child(context->root,idx)
  context->drawn = goo_canvas_group_new(context->root,"x",0.0,"y",0.0,"width",1000.0,"height",1000.0,"line-width",0.5,NIL)  
  goo_canvas_item_set_simple_transform(context->drawn,x,y,scale,rotation)
  return 1
  
end function

function plus_cb cdecl alias "plus_cb" (byval widget as gtkwidget ptr,byval context as context_ ptr) as integer

  dim scale as double
  
  scale = goo_canvas_get_scale(GOO_CANVAS(context->canvas))
  goo_canvas_set_scale(GOO_CANVAS(context->canvas),scale+SCALE_STEP)
  
  return 1
  
end function

function min_cb cdecl alias "min_cb" (byval widget as gtkwidget ptr,byval context as context_ ptr) as integer

  ''when the scale gets too small the mould gets smaller than the scrolled window
  
  dim scale as double

  scale = goo_canvas_get_scale(GOO_CANVAS(context->canvas))
  goo_canvas_set_scale(GOO_CANVAS(context->canvas),scale-SCALE_STEP)
  
  return 1

end function



function create_mould(byval context as context_ ptr) as integer

  dim item as GooCanvasItem ptr
  for i as integer = 0 to context->num_items
    var item = context->funs[i](0,context)
  next i
  for i as integer = 1 to context->num_items
    item = context->funs[i](1,context)    
  next i
  return 1

end function

function create_background(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  dim scale as gdouble
  dim x as gdouble
  dim y as gdouble

  ''draw mould background(no callbacks needed)
  if (opt = 0) then
    item = goo_canvas_rect_new(context->background,0,0,200,1000,"fill-color","lightgray",NIL)
    return item
  end if
  return NIL

  
end function


function create_lrect(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  
  ''draw mould item (no callbacks needed)
  if (opt = 0) then
    item = goo_canvas_rect_new(context->mould,50,30,80,15,"fill-color-rgba",&h9999,NIL)
    return item
  end if
  item = goo_canvas_rect_new(context->drawn,50,30,80,15,"fill-color-rgba",&h9999,NIL)
  return item
  
end function


function create_cube(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  
  if (opt = 0) then
    item = goo_canvas_rect_new(context->mould,70,50,40,40,"fill-color","yellow",NIL)
    return item    
  end if
  item = goo_canvas_rect_new(context->drawing,70,50,40,40,"fill-color","yellow",NIL)
  goo_canvas_item_raise(item,NIL)
  return item

end function

function create_window(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  
  if (opt = 0) then
    item = goo_canvas_rect_new(context->mould,90.0,95.0,12,15,"fill-color","lightblue",NIL)
    return item
  end if
  item = goo_canvas_rect_new(context->drawing,90.0,95.0,12,15,"fill-color","lightblue",NIL)
  goo_canvas_item_raise(item,NIL)
  return item
  
end function


function create_door(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  
  if (opt = 0) then
    item = goo_canvas_rect_new(context->mould,125,55,12,30,"fill-color","brown",NIL)
    return item
  end if
  item = goo_canvas_rect_new(context->drawing,125,55,12,30,"fill-color","brown",NIL)
  ''setup_dnd_handlers(canvas,item)
  goo_canvas_item_raise(item,NIL)
  return item

end function

function create_roof(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,4,40.0,125.0,60.0,100.0,80.0,125.0,40.0,125.0,"fill-color","red",NIL)
    return item
  end if
  item = goo_canvas_polyline_new(context->drawing,TRUE,4,40.0,125.0,60.0,100.0,80.0,125.0,40.0,125.0,"fill-color","red",NIL)
  goo_canvas_item_raise(item,NIL)
  return item
  
end function


function create_flag(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,7,50.0,50.0,65.0,52.0,65.0,64.0,52.0,62.0,52.0,90.0,50.0,90.0,50.0,50.0,"fill-color","blue",NIL)
    ''g_object_set (G_OBJECT (item), "x", 15, "y", 40, NIL)  
    return item
  end if
  item = goo_canvas_polyline_new(context->drawing,TRUE,7,50.0,50.0,65.0,52.0,65.0,64.0,52.0,62.0,52.0,90.0,50.0,90.0,50.0,50.0,"fill-color","blue",NIL)  
  goo_canvas_item_raise(item,NIL)
  return item
  
end function 

function create_slope(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,4,50.0,145.0,120.0,110.0,120.0,145.0,50.0,145.0,"fill-color","green",NIL)
    return item
  end if
  item = goo_canvas_polyline_new(context->drawing,TRUE,4,50.0,145.0,120.0,110.0,120.0,145.0,50.0,145.0,"fill-color","green",NIL)
  goo_canvas_item_raise(item,NIL)  
  return item
    
end function


function create_arch(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,10,_
    70.0,155.0,_
    100.0,155.0,_
    100.0,185.0,_
    95.0,185.0,_
    95.0,165.0,_
    85.0,160.0,_
    75.0,165.0,_
    75.0,185.0,_
    70.0,185.0,_
    70.0,155.0,"fill-color","orange",NIL)    
    ''g_object_set (G_OBJECT (item), "x", 50, "y", 135, NIL)    
    return item
  end if  
    item = goo_canvas_polyline_new(context->drawing,TRUE,10,_
    70.0,155.0,_
    100.0,155.0,_
    100.0,185.0,_
    95.0,185.0,_
    95.0,165.0,_
    85.0,160.0,_
    75.0,165.0,_
    75.0,185.0,_
    70.0,185.0,_
    70.0,155.0,"fill-color","orange",NIL)
    goo_canvas_item_raise(item,NIL)
    return item
  
end function

function create_man(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,22,_
/' 1 '/  109.0, 172.0,_
/' 2 '/  116.4, 167.0,_
/' 3 '/  118.6, 167.0,_
/' 4 '/  117.6, 163.6,_
/' 5 '/  119.6, 160.6,_
/' 6 '/  122.8, 160.4,_
/' 7 '/  124.4, 163.8,_
/' 8 '/  123.4, 167.2,_
/' 9 '/  125.4, 167.4,_
/' 10 '/  130.4, 174.0,_
/' 11 '/  128.6, 175.0,_
/' 12 '/  123.6, 169.4,_
/' 13 '/  123.6, 174.4,_
/' 14 '/  125.2, 182.0,_
/' 15 '/  122.0, 182.0,_
/' 16 '/  120.0, 174.4,_
/' 17 '/  117.6, 182.0,_
/' 18 '/  114.4, 182.0,_
/' 19 '/  116.4, 174.4,_
/' 20 '/  116.6, 169.8,_
/' 21 '/  110.4, 174.0,_
/' 22 '/  109.0, 172.0,"fill-color","bisque",NIL)
    ''g_object_set (G_OBJECT (item), "x", 85, "y", 135, NIL)
    return item
  end if  
  item = goo_canvas_polyline_new(context->drawing,TRUE,22,_
/' 1 '/  109.0, 172.0,_
/' 2 '/  116.4, 167.0,_
/' 3 '/  118.6, 167.0,_
/' 4 '/  117.6, 163.6,_
/' 5 '/  119.6, 160.6,_
/' 6 '/  122.8, 160.4,_
/' 7 '/  124.4, 163.8,_
/' 8 '/  123.4, 167.2,_
/' 9 '/  125.4, 167.4,_
/' 10 '/  130.4, 174.0,_
/' 11 '/  128.6, 175.0,_
/' 12 '/  123.6, 169.4,_
/' 13 '/  123.6, 174.4,_
/' 14 '/  125.2, 182.0,_
/' 15 '/  122.0, 182.0,_
/' 16 '/  120.0, 174.4,_
/' 17 '/  117.6, 182.0,_
/' 18 '/  114.4, 182.0,_
/' 19 '/  116.4, 174.4,_
/' 20 '/  116.6, 169.8,_
/' 21 '/  110.4, 174.0,_
/' 22 '/  109.0, 172.0,"fill-color","bisque",NIL)
   goo_canvas_item_raise(item,NIL)
   return item
   
end function

function create_woman(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  
  if (opt = 0) then
    item = goo_canvas_polyline_new(context->mould,TRUE,22,_
/' 1 '/  39.0,172.0,_
/' 2 '/  46.4,167.0,_
/' 3 '/  48.6,167.0,_
/' 4 '/  47.6,163.6,_
/' 5 '/  49.6,160.6,_
/' 6 '/  52.8,160.4,_
/' 7 '/  54.4,163.8,_
/' 8 '/  53.4,167.2,_
/' 9 '/  55.4,167.4,_
/' 10 '/  60.4,174.0,_
/' 11 '/  58.6,175.0,_
/' 12 '/  53.6,169.4,_
/' 13 '/  53.6,174.4,_
/' 14 '/  55.2,182.0,_
/' 15 '/  52.0,182.0,_
/' 16 '/  49.0,182.0,_
/' 17 '/  47.6,182.0,_
/' 18 '/  44.4,182.0,_
/' 19 '/  46.4,174.4,_
/' 20 '/  46.6,169.8,_
/' 21 '/  40.4,174.0,_
/' 22 '/  39.0,172.0,"fill-color","purple",NIL)
    return item
  end if
 item = goo_canvas_polyline_new(context->drawing,TRUE,22,_
/' 1 '/  39.0,172.0,_
/' 2 '/  46.4,167.0,_
/' 3 '/  48.6,167.0,_
/' 4 '/  47.6,163.6,_
/' 5 '/  49.6,160.6,_
/' 6 '/  52.8,160.4,_
/' 7 '/  54.4,163.8,_
/' 8 '/  53.4,167.2,_
/' 9 '/  55.4,167.4,_
/' 10 '/  60.4,174.0,_
/' 11 '/  58.6,175.0,_
/' 12 '/  53.6,169.4,_
/' 13 '/  53.6,174.4,_
/' 14 '/  55.2,182.0,_
/' 15 '/  52.0,182.0,_
/' 16 '/  49.0,182.0,_
/' 17 '/  47.6,182.0,_
/' 18 '/  44.4,182.0,_
/' 19 '/  46.4,174.4,_
/' 20 '/  46.6,169.8,_
/' 21 '/  40.4,174.0,_
/' 22 '/  39.0,172.0,"fill-color","purple",NIL)
  goo_canvas_item_raise(item,NIL)
  return item

end function

function create_wheel(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr

  if (opt = 0) then
    item = goo_canvas_ellipse_new(context->mould,52,210,8,8,"fill-color","black",NIL)
    return item
  end if
  item = goo_canvas_ellipse_new(context->drawing,52,210,8,8,"fill-color","black",NIL)  
  goo_canvas_item_raise(item,NIL)  
  return item
  
end function

function create_bush(byval opt as integer, byval context as context_ ptr) as GooCanvasItem ptr

  dim item as GooCanvasItem ptr
  if (opt = 0) then
    item = goo_canvas_ellipse_new(context->mould,88,210,15,15,"fill-color","darkgreen","line-width",1,"stroke-color-rgba",0,NIL)
    return item
  end if
  item = goo_canvas_ellipse_new(context->drawing,88,210,15,15,"fill-color","darkgreen","line-width",1,"stroke-color-rgba",0,NIL)  
  goo_canvas_item_raise(item,NIL)  
  return item
  
end function



sub my_main(byval argc as integer,byval argv as zstring ptr ptr)
  
  gtk_init (@argc,@argv)

  dim context as context_ ptr = callocate(1,sizeof(context_))
  dim funs(0 to ...) as item_function => _
  {_
  @create_background,@create_lrect,@create_cube,@create_door,_
  @create_roof,@create_slope,@create_flag,_
  @create_arch,@create_man,@create_woman,_
  @create_wheel,@create_bush,@create_window _
  }
  ' Create the window and widgets.
  var win = gtk_window_new (GTK_WINDOW_TOPLEVEL)
  gtk_window_set_default_size (GTK_WINDOW (win), 640, 600)
  gtk_widget_show (win)
  g_signal_connect (win, "delete_event", G_CALLBACK(@gtk_main_quit), NIL)

  var scrolled_win = gtk_scrolled_window_new (NIL, NIL)
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), _
                                       GTK_SHADOW_IN)
  gtk_widget_show (scrolled_win)


  var clear_button = gtk_button_new_with_label("C")
  gtk_widget_show(clear_button)
  var min_button = gtk_button_new_with_label("-")
  gtk_widget_show(min_button)  
  var plus_button = gtk_button_new_with_label("+")
  gtk_widget_show(plus_button)    
  var horizontal_box = gtk_hbox_new(TRUE,1)
  gtk_widget_show(horizontal_box)
  
  /' Connect the "clicked" signal of the buttons to callbacks '/
  g_signal_connect (clear_button, "clicked",G_CALLBACK (@clear_cb), context)
  g_signal_connect (min_button, "clicked",G_CALLBACK (@min_cb), context) 
  g_signal_connect (plus_button, "clicked",G_CALLBACK (@plus_cb), context)
  
  
  gtk_container_add(GTK_CONTAINER(horizontal_box),clear_button)
  gtk_container_add(GTK_CONTAINER(horizontal_box),min_button)
  gtk_container_add(GTK_CONTAINER(horizontal_box),plus_button)
  var vertical_box = gtk_vpaned_new()
  gtk_widget_show(vertical_box)
  gtk_paned_add1(GTK_PANED(vertical_box),horizontal_box)
  gtk_paned_add2(GTK_PANED(vertical_box),scrolled_win)
  gtk_container_add (GTK_CONTAINER (win), vertical_box)

  
  dim canvas as GtkWidget ptr = goo_canvas_new ()
  g_object_set (G_OBJECT (canvas), "integer-layout", TRUE, NULL)
  goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, Xmax, ymax)
  goo_canvas_set_scale(GOO_CANVAS(canvas),1.5)
  gtk_widget_show (canvas)
  gtk_container_add (GTK_CONTAINER (scrolled_win), canvas)

  context->canvas = canvas  
  dim root as GooCanvasItem ptr = goo_canvas_get_root_item (GOO_CANVAS (canvas))
  context->root = root  
  context->background = goo_canvas_group_new(root,"x",0.0,"y",0.0,"width",1000.0,"height",1000.0,"line-width",0.5,NIL)
  context->mould = goo_canvas_group_new(root,"x",0.0,"y",0.0,"width",1000.0,"height",1000.0,"line-width",0.5,NIL)
  context->drawing = goo_canvas_group_new(root,"x",0.0,"y",0.0,"width",1000.0,"height",1000.0,"line-width",0.5,NIL)
  context->drawn = goo_canvas_group_new(root,"x",0.0,"y",0.0,"width",1000.0,"height",1000.0,"line-width",0.5,NIL)
  context->drag_item = NIL
  context->funs = @funs(0)
  context->num_items = ubound(funs)
  g_signal_connect(context->drawn,"button-press-event",G_CALLBACK(@on_button_drawn_press_event_cb),context)
  g_signal_connect(context->drawing,"button-press-event",G_CALLBACK(@on_button_drawing_press_event_cb),context)
  g_signal_connect(context->drawn,"button-release-event",G_CALLBACK(@on_button_drawn_release_event_cb),context)
  g_signal_connect(context->drawing,"button-release-event",G_CALLBACK(@on_button_drawing_release_event_cb),context)
  g_signal_connect(context->drawn, "motion-notify-event", G_CALLBACK (@on_motion_drawn_notify_event_cb), context)
  g_signal_connect(context->drawing, "motion-notify-event", G_CALLBACK (@on_motion_drawing_notify_event_cb), context)  
  create_mould(context)
  gtk_main()

end sub

my_main(__FB_ARGC__,__FB_ARGV__)
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

AGS wrote:The demos work though. And nice demos they are.
Glad to read that. Thanks for testing and reporting.
AGS wrote:GTK3 reared it's ugly head on win7.
I got the same message on XP too. I thought XP is too old but it seems that windows doesn't support that feature at all?
AGS wrote:And I'm wondering why there are no parameter names in the header files (good job on the byval though).
Because parameter names are not needed for the compiler. I try to save some HDD space and to increase compile speed. For the final version I'll remove the comments for the borders of the single files as well, as dkl proposed. (Hope to receive some more reports before I start the final version.)
AGS wrote:My brix program (tcl port) is almost done. Drag-n-drop is a bit hard to get right in goo canvas. Perhaps that´ll change in the future (or perhaps I'm doing something wrong?).
DnD is the supreme discipline (this is not a GooCanvas but a GTK feature). I had a look at your code:
  • In line 196 you didn't terminate the VARARG parameter list. It should be
    g_object_set(G_OBJECT(target_item),"parent",context->drawn,NIL)
  • In lines 213 to 224 the counter ct starts at zero and gets increased after the assignment. It counts one more than elements in the list. Better use

    Code: Select all

        dim ct as integer = -1
        while (next_ <> NIL)
          var data_ = next_->data
          var parent = goo_canvas_item_get_parent(data_)
          if (parent = context->drawing) then
             ct += 1
             drawing_list(ct) = data_
          end if
          next_ = g_list_next(next_)
        wend
        redim preserve drawing_list(0 to ct)
  • In the following code (lines 226 to 242) some elements of the drawing_list can be removed (line 238) but the drawing_list gets no update. So in the next run of the outer loop (FOR ct) the function goo_canvas_item_get_bounds gets called on an removed item (-> segment violation signal). Here's a quick and dirty solution

    Code: Select all

        dim lb as integer = lbound(drawing_list)
        dim ub as integer = ubound(drawing_list)
        for ct = lb to ub
    IF drawing_list(ct) THEN
          goo_canvas_item_get_bounds(drawing_list(ct),@bounding_box1)
          for idx as integer = lb to ub
    if drawing_list(idx) ANDALSO (idx <> ct) then
              goo_canvas_item_get_bounds(drawing_list(idx),@bounding_box2)
              if (bounding_box2. x1 = bounding_box1.x1  andalso _
                  bounding_box2. x2 = bounding_box1.x2  andalso _
                  bounding_box2. y1 = bounding_box1.y1  andalso _
                  bounding_box2. y2 = bounding_box1.y2 ) then
                ''two items in group drawing on top of each other -> drop item
                goo_canvas_item_remove(drawing_list(idx))
    drawing_list(idx) = 0
              end if
    end if
          next idx
    END IF
        next ct
AGS
Posts: 1284
Joined: Sep 25, 2007 0:26
Location: the Netherlands

Post by AGS »

Thanks for helping out with the code, TJF. I'll integrate your changes.

As for GTK+ 3 and windows. The problem is this: there is no dbus library support for win32. GTK+ 3 uses dbus for communication purposes.

I tested a simple GTK3 "hello world" program and that works as expected. As long as you stay away from the GtkApplication widget GTK3 should work on windows.

Hello world for gtk3

Code: Select all

#define  __FB_GTK3__
#include "gtk/gtk.bi"

#ifndef NULL
#define NULL 0
#endif 

/' This is a callback function. The data arguments are ignored
 * in this example. More on callbacks below.
 '/
sub print_hello cdecl (byval widget as GtkWidget ptr,_
             byval data_ as gpointer)

  g_print ("Hello World\n")

end sub

function on_delete_event (byval widget as GtkWidget ptr,_
                 byval event as GdkEvent ptr,_
                 byval data_ as gpointer) as gboolean 

  /' If you return FALSE in the "delete_event" signal handler,
   * GTK will emit the "destroy" signal. Returning TRUE means
   * you don't want the window to be destroyed.
   *
   * This is useful for popping up 'are you sure you want to quit?'
   * type dialogs.
   '/

  g_print ("delete event occurred\n")

  return TRUE

end function

sub my_main (byval argc as integer,byval argv as zstring ptr ptr)
      

  /' GtkWidget is the storage type for widgets '/
  dim as GtkWidget ptr window_
  dim as GtkWidget ptr button

  /' This is called in all GTK applications. Arguments are parsed
   * from the command line and are returned to the application.
   '/
  gtk_init (@argc, @argv)

  /' create a new window, and set its title '/
  window_ = gtk_window_new (GTK_WINDOW_TOPLEVEL)
  gtk_window_set_title (GTK_WINDOW (window_), "Hello")

  /' When the window emits the "delete-event" signal (which is emitted
   * by GTK+ in response to an event coming from the window manager,
   * usually as a result of clicking the "close" window control), we
   * ask it to call the on_delete_event() function as defined above.
   *
   * The data passed to the callback function is 0 and is ignored
   * in the callback function.
   '/
  g_signal_connect (window_, "delete-event", G_CALLBACK (@on_delete_event), 0)

  /' Here we connect the "destroy" event to the gtk_main_quit() function.
   *
   * This signal is emitted when we call gtk_widget_destroy() on the window,
   * or if we return FALSE in the "delete_event" callback.
   '/
  g_signal_connect (window_, "destroy", G_CALLBACK (@gtk_main_quit), 0)

  /' Sets the border width of the window. '/
  gtk_container_set_border_width (GTK_CONTAINER (window_), 10)

  /' Creates a new button with the label "Hello World". '/
  button = gtk_button_new_with_label ("Hello World")

  /' When the button receives the "clicked" signal, it will call the
   * function print_hello() passing it 0 as its argument.
   *
   * The print_hello() function is defined above.
   '/
  g_signal_connect (button, "clicked", G_CALLBACK (@print_hello), 0)

  /' The g_signal_connect_swapped() function will connect the "clicked" signal
   * of the button to the gtk_widget_destroy() function; instead of calling it
   * using the button as its argument, it will swap it with the user data
   * argument. This will cause the window to be destroyed by calling
   * gtk_widget_destroy() on the window.
   '/
  g_signal_connect_swapped (button, "clicked", G_CALLBACK (@gtk_widget_destroy), window_)

  /' This packs the button into the window. A GtkWindow inherits from GtkBin,
   * which is a special container that can only have one child
   '/
  gtk_container_add (GTK_CONTAINER (window_), button)

  /' The final step is to display this newly created widget... '/
  gtk_widget_show (button)

  /' ... and the window '/
  gtk_widget_show (window_)

  /' All GTK applications must have a gtk_main(). Control ends here
   * and waits for an event to occur (like a key press or a mouse event),
   * until gtk_main_quit() is called.
   '/
  gtk_main ()
  
end sub

my_main(__FB_ARGC__,__FB_ARGV__)
Nothing special but it works. There are not that many GTK3 examples though (not at the GNOME GIT repository anyway).

And have you seen/read http://de.wikibooks.org/wiki/GTK_mit_Builder
The title of the wikibook is GTK+ 3.x mit Builder . What do you think: is the book good enough to 'have' (for FreeBASIC users)? Good enough to have after translation to English of course (and C code translated to FB). Perhaps GtkBuilder does not work on windows.

A builder example from the book (uses GTK3+ and it works on win7)

Code: Select all

#define  __FB_GTK3__
#include "gtk/gtk.bi"

#ifndef NULL
#define NULL 0
#endif 

 
dim shared interface as string

interface = _
    !"<interface>"_
    !"  <object class=\"GtkWindow\" id=\"main-window\">"_
    !"    <signal name=\"destroy\" handler=\"gtk_main_quit\"/>"_
    !"    <child>"_
    !"      <object class=\"GtkButton\" id=\"my-button\">"_
    !"        <property name=\"label\">Hallo, Welt!</property>"_
    !"        <signal name=\"clicked\" handler=\"on_button_clicked\"/>"_
    !"      </object>"_
    !"    </child>"_
    !"  </object>"_
    !"</interface>"_
 
sub on_button_clicked cdecl (byval w as GtkWidget ptr, byval d as gpointer)

    g_print (!"Hallo, Welt!\n")

end sub
 
sub connection_mapper cdecl (byval builder as GtkBuilder ptr, byval object as GObject ptr,_
        byval signal_name as gchar ptr, byval handler_name as gchar ptr,_
        byval connect_object as GObject ptr, byval flags as GConnectFlags , byval user_data as gpointer)

    g_print (!"Verbinde %s mit %s\n", signal_name, handler_name)
 
    if (g_strcmp0 (handler_name, "gtk_main_quit") = 0) then
        g_signal_connect (object, signal_name, G_CALLBACK(@gtk_main_quit), 0)
    elseif (g_strcmp0 (handler_name, "on_button_clicked") = 0) then
        g_signal_connect (object, signal_name, G_CALLBACK(@on_button_clicked), 0)
    else
        g_print (!"unbekannte Callback\n")
    end if

end sub
 
sub my_main (byval argc as integer, byval argv as zstring ptr ptr)

    dim error_ as GError ptr = NULL
    dim window_ as GtkWidget ptr
    dim builder as GtkBuilder ptr
    
    gtk_init (@argc, @argv)
    builder = gtk_builder_new()
    gtk_builder_add_from_string (builder, strptr(interface), -1, @error_)
    gtk_builder_connect_signals_full (builder, @connection_mapper, NULL)
    window_ = GTK_WIDGET(gtk_builder_get_object (builder, "main-window"))
    gtk_widget_show_all (window_)
    gtk_main()

end sub

my_main(__FB_ARGC__,__FB_ARGV__)
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

AGS wrote:As for GTK+ 3 and windows. The problem is this: there is no dbus library support for win32. GTK+ 3 uses dbus for communication purposes.
Aha. Didn't know that dbus isn't available for win32. (What about win64?).
AGS wrote:I tested a simple GTK3 "hello world" program and that works as expected. As long as you stay away from the GtkApplication widget GTK3 should work on windows.

...

Nothing special but it works. There are not that many GTK3 examples though (not at the GNOME GIT repository anyway).
All examples in my Gtk folder are tested successfully agianst GTK-3 (on XP). There aren't many examples on the GTK website because most of the GTK-2 code runs under GTK-3. But in GTK-3 the API is reviewed and deprecated widgets/functions are removed. That's why I had to review the FB examples too.

Anyway, thanks for your additional and detailed example (it can be compiled agianst GTK-2 as well).
AGS wrote:And have you seen/read http://de.wikibooks.org/wiki/GTK_mit_Builder
The title of the wikibook is GTK+ 3.x mit Builder . What do you think: is the book good enough to 'have' (for FreeBASIC users)? Good enough to have after translation to English of course (and C code translated to FB). Perhaps GtkBuilder does not work on windows.
Haven't seen it jet, thanks for the link.

IMO the main advantage of GtkBuilder is that you can design your GUI with Glade3. But in a quick check I haven't found anything about Glade3 in the book :( Using GtkBuilder without Glade3 is like driving a car with handbrake firmly on. But the book provides good information about some GTK widgets.

BTW: To replace the old LibGlade examples I made a GtkBuilder example (in Gtk folder) with two GtkBuilder files (*.ui). As mentioned it's tested successfully (XP / LINUX -- GTK-2 / GTK-3).
vladimir777
Posts: 94
Joined: Aug 19, 2011 18:28

Post by vladimir777 »

http://www.moreplovac.com/demo.zip

Here are some nice GTK examples in C I fount on The Net.
I wanted to translate them in FB but right now I have no time
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Post by marcov »

TJF wrote:
AGS wrote:As for GTK+ 3 and windows. The problem is this: there is no dbus library support for win32. GTK+ 3 uses dbus for communication purposes.
Aha. Didn't know that dbus isn't available for win32. (What about win64?).
http://sourceforge.net/projects/windbus/
wallyg
Posts: 270
Joined: May 08, 2009 7:08
Location: Tucson Arizona

Duplicated definitions in win7

Post by wallyg »

TJF wrote:
nobozoz wrote:Assuming C:\freebasic\, how are these files supposed to be installed after extraction so that the examples will compile with a minimum of hassle.
There're several ways to do so. Here's an easy method (consuming HDD space):
  • make copies of your folders bin, examples, inc and lib inside C:\freebasic\ (ie name them 'bin_', 'examples_', 'inc_' and 'lib_').
  • download the archives from the first post and extract them (open the freebasic folder in the archive and extract the subfolders to C:\freebasic\, overwrite existing files)
  • compile and run the new files in the 'examples\libraries' folder (find them by sorting by date or check the list above).
To restore your system
  • remove the new folders bin, examples, inc and lib.
  • rename the copies ('bin_' -> 'bin', 'examples_' -> 'examples', ...)
Good luck! I'm looking forward to read your reports.
I have a win7/64 bit system up to date. I reloaded FreeBasic to start with a clean system. I unzip the *.7z files specified above to the FreeBasic system just loaded. I OKed the overwriting of the old GTK files from the *.7z files. I ran FBEdit and opened the file FB_Calc.bas file into FbEdit. I then tried to compile them with C:\FreeBASIC\fbc -g -s gui "FB_Calc.bas"

I got the following messages.

C:\FreeBASIC\inc\glib.bi(96) error 4: Duplicated definition, G_GNUC_FUNCTION in '#DEFINE G_GNUC_FUNCTION __FUNCTION__'
C:\FreeBASIC\inc\glib.bi(97) error 4: Duplicated definition, G_GNUC_PRETTY_FUNCTION in '#DEFINE G_GNUC_PRETTY_FUNCTION __FUNCTION__'
C:\FreeBASIC\inc\glib.bi(111) error 4: Duplicated definition, G_STRLOC in '#DEFINE G_STRLOC __FILE__ !":" G_STRINGIFY (__LINE__) !":" __FUNCTION__ !"()"'
C:\FreeBASIC\inc\glib.bi(179) error 4: Duplicated definition, G_GINT16_MODIFIER in '#DEFINE G_GINT16_MODIFIER !"h"'
C:\FreeBASIC\inc\glib.bi(180) error 4: Duplicated definition, G_GINT16_FORMAT in '#DEFINE G_GINT16_FORMAT !"hi"'
C:\FreeBASIC\inc\glib.bi(181) error 4: Duplicated definition, G_GUINT16_FORMAT in '#DEFINE G_GUINT16_FORMAT !"hu"'
C:\FreeBASIC\inc\glib.bi(186) error 4: Duplicated definition, G_GINT32_MODIFIER in '#DEFINE G_GINT32_MODIFIER !""'
C:\FreeBASIC\inc\glib.bi(187) error 4: Duplicated definition, G_GINT32_FORMAT in '#DEFINE G_GINT32_FORMAT !"i"'
C:\FreeBASIC\inc\glib.bi(188) error 4: Duplicated definition, G_GUINT32_FORMAT in '#DEFINE G_GUINT32_FORMAT !"u"'
C:\FreeBASIC\inc\glib.bi(196) error 4: Duplicated definition, G_GINT64_MODIFIER in '#DEFINE G_GINT64_MODIFIER !"ll"'
C:\FreeBASIC\inc\glib.bi(196) error 123: Too many errors, exiting

Build error(s)

What did I do wrong and what do I try next?
Post Reply