1
votes

I want to draw geometric forms by code into a Gtk_Window .

I already code the Gtk_window , my only problem is to use it with Cairo .

Next, the code after using andlabs's method .

So this code contain a gtk_drawing_area in the window , and the "draw" signal in the connect procedure , which is connected to the new handler ( instantiation of generic ).

In fact , i used this C code : https://developer.gnome.org/gtk3/stable/GtkDrawingArea.html

There is errors in 2 lines at compile time .

WITH Gtk.Main ;          USE Gtk.Main ;
WITH Gtk.Window ;        USE Gtk.Window ;
WITH Gtk.Enums ;         USE Gtk.Enums ;
WITH Gtk.Button ;        USE Gtk.Button ;
WITH Gtk.Alignment ;     USE Gtk.Alignment ;
WITH Gtk.Box ;           USE Gtk.Box ;
WITH Gtk.Gentry;         USE Gtk.Gentry;
WITH Gtk.Widget ;        USE Gtk.Widget ;
with Gtk.Handlers;
WITH Gtk.Drawing_Area;  USE Gtk.Drawing_Area;
WITH Cairo ;            USE Cairo ;
WITH Gdk.Color ;        USE Gdk.Color ;
WITH Gdk.Cairo ;        USE Gdk.Cairo ;
WITH Gtk.Style ;        USE Gtk.Style ;
WITH Glib ;             USE Glib ;

PROCEDURE dessine_avec_cairo IS

-----------------------
   -- VARIABLES --    |
----------------------------------------------------------
   win : Gtk_window ;

   Btn1, Btn2 ,Btn3  : Gtk_Button ;

   alignG, alignM ,alignD  : Gtk_Alignment ;

   Boite  : Gtk_VBox ;

   Boutons :  Gtk_HBox ;

   saisie : Gtk_Entry ;

   zone_dessin : Gtk_Drawing_Area ;

----------------------------------------------------------
--Instanciation package(s) for connexion
----------------------------------------------------------

   PACKAGE P_Callback IS NEW Gtk.Handlers.Callback(Gtk_Widget_Record);

   USE P_Callback ;

   PACKAGE P2_Callback IS NEW Gtk.Handlers.User_Callback(Gtk_Widget_Record , Boolean);

   USE P2_Callback ;

----------------------------------------------------------
--  Handlers (or callbacks)   |
----------------------------------------------------------

   procedure Stop_Program(Emetteur : access Gtk_Widget_Record'class)
   is

      PRAGMA Unreferenced (Emetteur);

   begin

      Main_Quit;

   end Stop_Program ;

   function draw_callback (the_Widget : access Gtk_Widget_Record'Class ;
                           cairo_t : Cairo_Context ) return boolean
   is

   width : Allocation_Int ;

   height : Allocation_Int ;

   color : Gdk_Color ;

   begin

   Queue_Draw (Widget => zone_dessin);

   width := Get_Allocation_Width (Widget => the_Widget) ;

   height := Get_Allocation_Height (Widget => the_Widget) ;

   Arc
     (Cr     => cairo_t ,
      Xc     => 2.0 ,
      Yc     => 2.0 ,
      Radius => 2.0 ,
      Angle1 => 0.0 ,
      Angle2 => 2.0 * 3.14 );

    color := Get_Fg
     (Style   => Get_Style (Widget => the_Widget) ,
      State_Type => State_Active) ;


    Set_Source_Color
     (Cr       => cairo_t ,
      Color    => color);

    Set_Fill_Rule
     (Cr        => cairo_t ,
      Fill_Rule => Cairo_Fill_Rule_Winding);

    return false ;

    end draw_callback ;



-------------------------------------------------
BEGIN

   Init ;

----------------
   -- NEW --   |
-------------------------------------------------

   Gtk_New(zone_dessin);

   Gtk_New(win);

   Gtk_New(saisie);

   Gtk_New(Btn1, "Bouton 1") ;
   Gtk_New(Btn2, "Bouton 2") ;
   Gtk_New(Btn3, "Bouton 3") ;

   Gtk_New(alignG,0.0,1.0,1.0,1.0);
   Gtk_New(alignM,0.5,1.0,1.0,1.0);
   Gtk_New(alignD,1.0,1.0,1.0,1.0);

  Gtk_New_VBox
  (Boite, homogeneous => false, Spacing => 0) ;

  Gtk_New_HBox
  (Boutons, homogeneous => false, Spacing => 0) ;

---------------------------------
--  Add                    |
---------------------------------

   alignG.add(Btn1) ;
   alignM.add(Btn2) ;
   alignD.add(Btn3) ;

   win.Add(Boite);

------------------------------------------
--  Connect                |
------------------------------------------

Connect(Widget => win ,
          Name => "destroy" ,
            Cb => Stop_Program'access);

Connect(Widget => zone_dessin ,
          Name => "draw" ,
            Cb => draw_callback'access);

------------------------------------------
--  Design Window          |
------------------------------------------

   Size_Allocate
     (Widget  => zone_dessin ,
      Allocation =>  ( X => 0 , Y => 0 , Width => 150 , Height => 150 ) ) ;

   Pack_Start
      (In_Box => Boite ,
       Child  => zone_dessin ,
       Expand => true ,
       Fill => true );

   Pack_Start
      (In_Box => Boite ,
       Child  => saisie ,
       Expand => false );

   Pack_Start
      (In_Box => Boite ,
       Child => Boutons ,
       Expand => true ,
       Fill => true );


   Pack_Start
      (In_Box => Boutons ,
       Child => alignG ,
       Expand => true ,
       Fill => true );

   Pack_Start
      (In_Box => Boutons ,
       Child => alignM ,
       Expand => true ,
       Fill => true );

   Pack_Start
      (In_Box => Boutons ,
       Child => alignD ,
       Expand => true ,
       Fill => true );



   win.Set_Default_Size(600,500) ;

   win.set_position(Win_Pos_Mouse) ;

   win.set_opacity(0.7) ;

   win.Show_all ;
   Main ;

END dessine_avec_cairo ; 
1
With GTK+ you do not create your own cairo contexts; GTK+ gives you a cairo context to draw on. Do this with the draw signal. The easiest way is to use a Gtk_Drawing_Area, which is specifically designed for drawing on. Once you have that, connect to its 'draw' signal. Here are some resources from the official GTK+ site; you'll need to transcribe them to Ada. Good luck!andlabs
Still up to date and nothing new...infinite
What exactly are you stuck on?andlabs
Like i said in 2nd part of the post , i have no idea of how to create the package instanciation + the callback (function ?) + the connect procedure . I'm stuck after creating the gtk_drawing_area .infinite
Topic edited with new codeinfinite

1 Answers

2
votes

I finally succeed with the GTK2 version .

The result : http://i.stack.imgur.com/5twOg.png

Source Code :

WITH Gtk.Main ;          USE Gtk.Main ;
WITH Gtk.Window ;        USE Gtk.Window ;
WITH Gtk.Enums ;         USE Gtk.Enums ;
WITH Gtk.Widget ;        USE Gtk.Widget ;
with Gtk.Handlers;
WITH Gtk.Drawing_Area;   USE Gtk.Drawing_Area;


WITH Cairo ;            USE Cairo ;
WITH Gdk.Color ;        USE Gdk.Color ;
WITH Gdk.Cairo ;        USE Gdk.Cairo ;
WITH Gtk.Style ;        USE Gtk.Style ;
WITH Glib ;             USE Glib ;
WITH Gdk.Event ;        USE Gdk.Event ;
WITH Gdk.Rectangle ;    USE Gdk.Rectangle ;
WITH Gdk ;              USE Gdk ;

PROCEDURE dessine_avec_cairo IS

-----------------------
   -- VARIABLES --    |
----------------------------------------------------------
   win : Gtk_window ;

   zone_dessin : Gtk_Drawing_Area ;

----------------------------------------------------------
--Instanciation package(s) for connexion
----------------------------------------------------------

   PACKAGE P_Callback IS NEW Gtk.Handlers.Callback(Gtk_Widget_Record);

   USE P_Callback ;

   PACKAGE Configured IS NEW Gtk.Handlers.Return_Callback
     (Widget_Type => Gtk_Drawing_Area_Record,
      Return_Type => Boolean);

----------------------------------------------------------
--  Handlers (or callbacks)   |
----------------------------------------------------------

   procedure Stop_Program(Emetteur : access Gtk_Widget_Record'class)
   is

      PRAGMA Unreferenced (Emetteur);

   begin

      Main_Quit;

   end Stop_Program ;



   function Expose_Event
     (the_Widget : access Gtk_Drawing_Area_Record'Class;
      Event : Gdk.Event.Gdk_Event )
      return Boolean
   is
    Area : Gdk_Rectangle := Get_Area (Event);
    Region : Gdk_Rectangle;

    Context : Cairo_Context ;
    Win2 : Gdk_Window ;
    drawable : Gdk_Drawable ;

    begin

    Win2 := Get_Window (Widget => the_Widget) ;
    drawable := Gdk_Drawable (Win2) ;-- type conversion
    Context := Create ( drawable ) ;

    Region.Width := Area.Width / 2;
    Region.Height := Area.Height / 2;
    Region.X := Region.Width / 2;
    Region.Y := Region.Height / 2;

    Set_Source_Rgb(Context, 1.0, 0.0, 0.0);
    Cairo.Rectangle(Cr => Context, X => GDouble(Region.X), Y => GDouble(Region.Y), Width => GDouble(Region.Width), Height => GDouble(Region.Height));
    Cairo.Fill_Preserve(Context);

    Set_Line_Width(Context, 1.0);
    Set_Source_Rgb(Context, 0.0, 0.0, 1.0);
    Cairo.Stroke(Context);


    return false ;

    end expose_event;


-------------------------------------------------
BEGIN

   Init ;

----------------
   -- NEW --   |
-------------------------------------------------

   Gtk_New(zone_dessin);

   Gtk_New(win);

---------------------------------
--  Add                    |
---------------------------------

   win.Add( zone_dessin );

------------------------------------------
--  Connect                |
------------------------------------------

Connect(Widget => win ,
          Name => "destroy" ,
            Cb => Stop_Program'access);


Configured.Connect (Widget => zone_dessin,
                       Name   => "expose_event",
                       Marsh  => Configured.To_Marshaller
                          (Expose_Event'Access));

------------------------------------------
--  Design Window          |
------------------------------------------

   win.Set_Default_Size(500,500) ;

   win.set_position(Win_Pos_Center) ;

   win.set_opacity(0.7) ;

   win.Show_all ;
   Main ;

END dessine_avec_cairo ;