comp.lang.ada
 help / color / mirror / Atom feed
* GTK 3.8 Graphic programming
@ 2014-01-03 10:44 ldries46
  2014-01-05  7:43 ` ldries46
  0 siblings, 1 reply; 5+ messages in thread
From: ldries46 @ 2014-01-03 10:44 UTC (permalink / raw)


I am trying to learn myself simple graphical programming in GTK 3.8 
(GtkAda).
I want to draw a a simple grid in a drawing area.
With Glade 3 I created a window with a GtkdrawingArea with in a GtkViewport 
with in a GtkScrolledWindow
within a GtkVBox within a GtkWindow. So far the program works.
With Get_Object the GtkdrawingArea  was extracted from the builder and used 
to create a Cairo context C
Now I want to draw a grid using

Gdkw := Get_Window (Gtk_Drawing_Area);
CR := Create(Gdkw);
Save(CR);
Set_Source_Rgb(CR, 1.0, 0.0, 0.0);
Paint(CR);
Restore(CR);
Number := Width * Height;
Total_W := Init_W + W * W * CW;
Total_H := Init_H + H * H * CW;
Set_Line_Width(CR, 3.0);
Set_Source_Rgb(CR, 1.0, 1.0, 1.0);
for n in 0.. H * H loop
   Move_To(CR, GDouble(Init_W + n * CW), GDouble(Init_H));
   Rel_Line_To(CR, GDouble(Total_W), 0.0);
   Stroke(CR);
end loop;
for n in 0.. W * W loop
   Move_To(CR, GDouble(Init_W), GDouble(Init_H + n * CW));
   Rel_Line_To(CR, 0.0, GDouble(Total_H));
   Stroke(CR);
end loop;

The result is still an empty drawing area. The back round is still white 
(Should be red) the lines are invisisble
I still am missing something.
I tried to find Ada examples how to create a running program but I cannot 
find anything.
Who can help either by directing me to Ada examples or by telling me what I 
do miss in this program 



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GTK 3.8 Graphic programming
  2014-01-03 10:44 GTK 3.8 Graphic programming ldries46
@ 2014-01-05  7:43 ` ldries46
  2014-01-05  9:12   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 5+ messages in thread
From: ldries46 @ 2014-01-05  7:43 UTC (permalink / raw)


In the meantime I isolated the problem. Setting a breakpoint before I call 
Gtk.Main.Main I can see then grid I am drawing, the moment I start again the 
drawing disappears.
The problem seems to be that the position where I must create a starting 
grid that is necessary before any further action in the program should be 
taken. How can I do such a thing.

"ldries46"  schreef in bericht news:52c69509$0$22518$703f8584@news.kpn.nl...

I am trying to learn myself simple graphical programming in GTK 3.8
(GtkAda).
I want to draw a a simple grid in a drawing area.
With Glade 3 I created a window with a GtkdrawingArea with in a GtkViewport
with in a GtkScrolledWindow
within a GtkVBox within a GtkWindow. So far the program works.
With Get_Object the GtkdrawingArea  was extracted from the builder and used
to create a Cairo context C
Now I want to draw a grid using

Gdkw := Get_Window (Gtk_Drawing_Area);
CR := Create(Gdkw);
Save(CR);
Set_Source_Rgb(CR, 1.0, 0.0, 0.0);
Paint(CR);
Restore(CR);
Number := Width * Height;
Total_W := Init_W + W * W * CW;
Total_H := Init_H + H * H * CW;
Set_Line_Width(CR, 3.0);
Set_Source_Rgb(CR, 1.0, 1.0, 1.0);
for n in 0.. H * H loop
   Move_To(CR, GDouble(Init_W + n * CW), GDouble(Init_H));
   Rel_Line_To(CR, GDouble(Total_W), 0.0);
   Stroke(CR);
end loop;
for n in 0.. W * W loop
   Move_To(CR, GDouble(Init_W), GDouble(Init_H + n * CW));
   Rel_Line_To(CR, 0.0, GDouble(Total_H));
   Stroke(CR);
end loop;

The result is still an empty drawing area. The back round is still white
(Should be red) the lines are invisisble
I still am missing something.
I tried to find Ada examples how to create a running program but I cannot
find anything.
Who can help either by directing me to Ada examples or by telling me what I
do miss in this program 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GTK 3.8 Graphic programming
  2014-01-05  7:43 ` ldries46
@ 2014-01-05  9:12   ` Dmitry A. Kazakov
  2014-01-05 16:45     ` ldries46
  0 siblings, 1 reply; 5+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-05  9:12 UTC (permalink / raw)


On Sun, 5 Jan 2014 08:43:58 +0100, ldries46 wrote:

> I am trying to learn myself simple graphical programming in GTK 3.8
> (GtkAda).

First of all, where did you get GtkAda 3.8? The GNAT GPL 2013 version is
3.4. The latest official Windows GTK+ release is 3.6. GtkAda 3.x was never
packaged for Linux. The actual GTK+ version for Linux is 3.10.

[ OT: I tried to build Gtk 3.11 from sources under MinGW. It is a huge
work, because they do not compile without bootstrapping and modification of
both code and auto-configuration files. Neither the latest GtkAda 3.8 does
compile under MinGW. After much fixing, I managed to compile both using gcc
3.7 (from GNAT GPL) or 3.8 (form MinGW), but the result is appalling. It
either does not link or there are problems with handling exceptions which
crash the program. It is far beyond my knowledge of gcc's internals to fix
this mess. ]

> I want to draw a a simple grid in a drawing area.
> With Glade 3 I created a window with a GtkdrawingArea with in a GtkViewport
> with in a GtkScrolledWindow
> within a GtkVBox within a GtkWindow. So far the program works.
> With Get_Object the GtkdrawingArea  was extracted from the builder and used
> to create a Cairo context C
> Now I want to draw a grid using
> 
> Gdkw := Get_Window (Gtk_Drawing_Area);
> CR := Create(Gdkw);
> Save(CR);
> Set_Source_Rgb(CR, 1.0, 0.0, 0.0);
> Paint(CR);
> Restore(CR);
> Number := Width * Height;
> Total_W := Init_W + W * W * CW;
> Total_H := Init_H + H * H * CW;
> Set_Line_Width(CR, 3.0);
> Set_Source_Rgb(CR, 1.0, 1.0, 1.0);
> for n in 0.. H * H loop
>    Move_To(CR, GDouble(Init_W + n * CW), GDouble(Init_H));
>    Rel_Line_To(CR, GDouble(Total_W), 0.0);
>    Stroke(CR);
> end loop;
> for n in 0.. W * W loop
>    Move_To(CR, GDouble(Init_W), GDouble(Init_H + n * CW));
>    Rel_Line_To(CR, 0.0, GDouble(Total_H));
>    Stroke(CR);
> end loop;

You could use Stroke once.

> The result is still an empty drawing area. The back round is still white
> (Should be red) the lines are invisisble
> I still am missing something.

Yes, the drawing model is event-driven. You must draw from the signal
handler.

1. You should derive your widget from Gtk_Drawing_Area_Record

   type My_Custom_Drawn_Widget_Record is
      new Gtk_Drawing_Area_Record with ...

2. In the implementation of Initialize (which you call from widget's
Gtk_New) you connect to the signal "draw". The profile is:

   function Draw
            (  Widget  : access My_Custom_Drawn_Widget_Record'Class;
               Context : Cairo.Cairo_Context
            )  return Boolean;

Caution! AdaCore changed the interface yet again since 2.24 and then 3.4.
See Glib.Object for the procedure of registering the widget's class record
and its type.

3. From Draw you perform whatever drawing you wanted on Context, which is
already clipped. Use Get_Allocation to obtain actual widget sizes.

P.S. The described method works fine with GtkAda 3.4 and used here:

   http://www.dmitry-kazakov.de/ada/aicwl.htm

I don't publish the version for GTK 3.x because no GtkAda is available.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GTK 3.8 Graphic programming
  2014-01-05  9:12   ` Dmitry A. Kazakov
@ 2014-01-05 16:45     ` ldries46
  2014-01-05 18:10       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 5+ messages in thread
From: ldries46 @ 2014-01-05 16:45 UTC (permalink / raw)




"Dmitry A. Kazakov"  schreef in bericht 
news:z154dfja3q0m.17hbcu4i3o1u8.dlg@40tude.net...

On Sun, 5 Jan 2014 08:43:58 +0100, ldries46 wrote:

> First of all, where did you get GtkAda 3.8?

I probably get all different versions mixed up. Possibly a mix-up of 
versions  of GTK, GtkAda and Glade. I am sorry if this made it difficult for 
you.

I wanted a standard grid in the window at the moment of initialization. This 
meant that the first try was the drawing procedure using before I carried 
out Gtk.Main.Main . By inserting a breakpoint just before this point I found 
the grid was visible but it vanished when I executed the next step.
My next step was putting the routine in the callback procedure from 
File/New. Now also the grid became visible except for the part that was 
under the pull-down menu from File.
All this means that I am missing the part that fixes the grid in the 
Gtk_Drawing_Area.


> You could use Stroke once.

It is nice to find that only one Stroke is necessary. But in the Testcairo 
example in the  GTK distribution also more stroke routines are used.

> Yes, the drawing model is event-driven. You must draw from the signal
> handler.

Firstly the initial grid is never drawn from a event so there should be an 
event handler which is triggered by starting the program.

> 1. You should derive your widget from Gtk_Drawing_Area_Record

With glade3 I get the drawing area with

Object :=  Get_Object (Builder, "My_drawing_area");
My_Area := Gtk_Drawing_Area(Object);

> 2. In the implementation of Initialize (which you call from widget's
> Gtk_New) you connect to the signal "draw". The profile is:

>    function Draw
>             (  Widget  : access My_Custom_Drawn_Widget_Record'Class;
>                Context : Cairo.Cairo_Context
>            )  return Boolean;

I think initialization is also done in this case. The draw function I could 
not find but. Maybe I did not understand your meaning and maybe I am using 
the GtkAda version of 2013 with a somewhat newer version of Glade3 because 
of the visibility of a number of items.

> Caution! AdaCore changed the interface yet again since 2.24 and then 3.4.
> See Glib.Object for the procedure of registering the widget's class record
> and its type.

> 3. From Draw you perform whatever drawing you wanted on Context, which is
> already clipped. Use Get_Allocation to obtain actual widget sizes.

> P.S. The described method works fine with GtkAda 3.4 and used here:

>    http://www.dmitry-kazakov.de/ada/aicwl.htm

I will study your link and hopes that I can conclude my program soon

L. Dries 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: GTK 3.8 Graphic programming
  2014-01-05 16:45     ` ldries46
@ 2014-01-05 18:10       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-05 18:10 UTC (permalink / raw)


On Sun, 5 Jan 2014 17:45:32 +0100, ldries46 wrote:

> "Dmitry A. Kazakov"  schreef in bericht 
> news:z154dfja3q0m.17hbcu4i3o1u8.dlg@40tude.net...
> 
> On Sun, 5 Jan 2014 08:43:58 +0100, ldries46 wrote:
> 
>> First of all, where did you get GtkAda 3.8?
> 
> I probably get all different versions mixed up. Possibly a mix-up of 
> versions  of GTK, GtkAda and Glade. I am sorry if this made it difficult for 
> you.

That won't work. I tested GtkAda 3.4 mixed with GTK+ 3.6, 3.8, 3.10 from
various builds, they do not work together. Even if it appears working it
has serious problems like heap corruption and failures in Ada exception
propagation.

> I wanted a standard grid in the window at the moment of initialization. This 
> meant that the first try was the drawing procedure using before I carried 
> out Gtk.Main.Main.

It does not work this way. You should never draw directly into a window.

> By inserting a breakpoint just before this point I found 
> the grid was visible but it vanished when I executed the next step.
> My next step was putting the routine in the callback procedure from 
> File/New. Now also the grid became visible except for the part that was 
> under the pull-down menu from File.

Because it gets drawn over by the default handler. This is why you must
override the handler.

> All this means that I am missing the part that fixes the grid in the 
> Gtk_Drawing_Area.

See:

https://developer.gnome.org/gtk3/3.2/GtkWidget.html#GtkWidget-draw
 
>> You could use Stroke once.
> 
> It is nice to find that only one Stroke is necessary. But in the Testcairo 
> example in the  GTK distribution also more stroke routines are used.

Single Stroke is more efficient.

You should also take care about line alignments. When you draw vertical or
horizontal lines at whole pixel positions, as you do, lines get blurred due
to aliasing. In order to draw sharp lines you should draw at the positions
"between" the pixels, e.g. at 1.5 instead of 1.0.

>> Yes, the drawing model is event-driven. You must draw from the signal
>> handler.
> 
> Firstly the initial grid is never drawn from a event so there should be an 
> event handler which is triggered by starting the program.

Of course it gets drawn. First, when you call Show on the widget, and then
any time the widget contents gets exposed.

>> 1. You should derive your widget from Gtk_Drawing_Area_Record
> 
> With glade3 I get the drawing area with
> 
> Object :=  Get_Object (Builder, "My_drawing_area");
> My_Area := Gtk_Drawing_Area(Object);

I cannot comment on Glade, I have no idea what it does under the hood (and
why people are so obsessed with it).

Anyway, the relevant documentation about GtkDrawingArea is here:

https://developer.gnome.org/gtk3/stable/GtkDrawingArea.html

It contains description of the "draw" signal and a small sample. Note that
though it also refers to "configure-event", that signal cannot be caught
and thus cannot be handled. Widget resizing is dealt with by other means.

>> 2. In the implementation of Initialize (which you call from widget's
>> Gtk_New) you connect to the signal "draw". The profile is:
> 
>>    function Draw
>>             (  Widget  : access My_Custom_Drawn_Widget_Record'Class;
>>                Context : Cairo.Cairo_Context
>>            )  return Boolean;
> 
> I think initialization is also done in this case. The draw function I could 
> not find but.

The Draw function is the callback you have to declare and implement. It is
then connected to "draw." See On_Draw in Gtk.Widget. You can use it in
order to connect your Draw to the signal. The corresponding access to
function type is named Cb_Gtk_Widget_Cairo_Context_Boolean. In the same
package.

From Initialize, you would do:

   procedure Initialize
       (Widget : not null access My_Custom_Draw_Record'Class, ...) is
   begin 
      ...
      -- Registering the class, initialization of the parent
      ...
      Widget.On_Draw (Draw'Access); -- Connect to the signal
   end Initialize;

This is the simplest way, but it will require a type conversion of the
first argument of Draw.

So if you don't like casts, you should instantiate Return_Callback from
Gtk.Handlers this way:

   package Return_Boolean_Callback is
      new Gtk.Handlers.Return_Callback (My_Custom_Draw_Record, Boolean);

And connect to the signal so:

   Return_Boolean_Callback.Connect
      (  Widget,
         "draw",
         Return_Boolean_Callback.To_Marshaller (Draw'Access),
         True
      );

>> Caution! AdaCore changed the interface yet again since 2.24 and then 3.4.
>> See Glib.Object for the procedure of registering the widget's class record
>> and its type.
> 
>> 3. From Draw you perform whatever drawing you wanted on Context, which is
>> already clipped. Use Get_Allocation to obtain actual widget sizes.
> 
>> P.S. The described method works fine with GtkAda 3.4 and used here:
> 
>>    http://www.dmitry-kazakov.de/ada/aicwl.htm
> 
> I will study your link and hopes that I can conclude my program soon

Remember, that the latest published version of AICWL is for GtkAda 2.24.
GtkAda 3.x is *significantly* different with regard to drawing and the
procedure of registering a custom widget. You cannot use this code as a
sample for GtkAda 3.x!

Furthermore, if your GtkAda is 3.4 you would wasting your time, because, as
I said, AdaCore screwed it again in the parts you would use in your widget.
You should start with 3.8 and hope that they stop changing interfaces.

Presently I see no other alternative as to wait for GNAT GPL 2014... (:-()

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-01-05 18:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-03 10:44 GTK 3.8 Graphic programming ldries46
2014-01-05  7:43 ` ldries46
2014-01-05  9:12   ` Dmitry A. Kazakov
2014-01-05 16:45     ` ldries46
2014-01-05 18:10       ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox