comp.lang.ada
 help / color / mirror / Atom feed
* gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
@ 2019-11-02 10:22 Alain De Vos
  2019-11-02 11:00 ` Alain De Vos
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Alain De Vos @ 2019-11-02 10:22 UTC (permalink / raw)


I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.

procedure hello is
   Top     : Gtk.Window.Gtk_Window;
   Button  : Gtk_Button;
   Label   : Gtk_Label;
   VBox    : Gtk_Box;
   procedure Create_Window is
   begin
      Gtk.Window.Gtk_New
        (Window   => Top,
         The_Type => Gtk.Enums.Window_Toplevel);
      Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
      Gtk_New(Button);
      Button.On_Clicked (Call => On_Button_Click'Access, 
                         Slot => Top);
      Gtk_New(Label);
      Gtk_New_Vbox(VBox);
      Add (VBox,Button);
      Add (VBox,Label);
      Add (Top,VBox);
      Gtk.Window.Show_All (Top);
   end Create_Window;
begin
   Gtk.Main.Init;
   Create_Window;
   Gtk.Main.Main;
end hello;

I pass the topwindow to the eventhandler(slot).
In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
{The label is not directly visible in the handler ...}

package body buttonhandler is
   procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
   begin
      Put_line ("Hallo");
      -- I need to go from Top to Vbox to Label and set text ... ????
   end On_Button_Click;
end buttonhandler;


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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
@ 2019-11-02 11:00 ` Alain De Vos
  2019-11-02 11:03 ` Dmitry A. Kazakov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Alain De Vos @ 2019-11-02 11:00 UTC (permalink / raw)


On Saturday, November 2, 2019 at 11:22:49 AM UTC+1, Alain De Vos wrote:
> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
> 
> procedure hello is
>    Top     : Gtk.Window.Gtk_Window;
>    Button  : Gtk_Button;
>    Label   : Gtk_Label;
>    VBox    : Gtk_Box;
>    procedure Create_Window is
>    begin
>       Gtk.Window.Gtk_New
>         (Window   => Top,
>          The_Type => Gtk.Enums.Window_Toplevel);
>       Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>       Gtk_New(Button);
>       Button.On_Clicked (Call => On_Button_Click'Access, 
>                          Slot => Top);
>       Gtk_New(Label);
>       Gtk_New_Vbox(VBox);
>       Add (VBox,Button);
>       Add (VBox,Label);
>       Add (Top,VBox);
>       Gtk.Window.Show_All (Top);
>    end Create_Window;
> begin
>    Gtk.Main.Init;
>    Create_Window;
>    Gtk.Main.Main;
> end hello;
> 
> I pass the topwindow to the eventhandler(slot).
> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
> {The label is not directly visible in the handler ...}
> 
> package body buttonhandler is
>    procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>    begin
>       Put_line ("Hallo");
>       -- I need to go from Top to Vbox to Label and set text ... ????
>    end On_Button_Click;
> end buttonhandler;

Or should I subclass Gtk.Window.Gtk_Window ?

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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
  2019-11-02 11:00 ` Alain De Vos
@ 2019-11-02 11:03 ` Dmitry A. Kazakov
  2019-11-02 15:27 ` Alain De Vos
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2019-11-02 11:03 UTC (permalink / raw)


On 2019-11-02 11:22, Alain De Vos wrote:
> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
> 
> procedure hello is
>     Top     : Gtk.Window.Gtk_Window;
>     Button  : Gtk_Button;
>     Label   : Gtk_Label;
>     VBox    : Gtk_Box;
>     procedure Create_Window is
>     begin
>        Gtk.Window.Gtk_New
>          (Window   => Top,
>           The_Type => Gtk.Enums.Window_Toplevel);
>        Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>        Gtk_New(Button);
>        Button.On_Clicked (Call => On_Button_Click'Access,
>                           Slot => Top);
>        Gtk_New(Label);
>        Gtk_New_Vbox(VBox);
>        Add (VBox,Button);
>        Add (VBox,Label);
>        Add (Top,VBox);
>        Gtk.Window.Show_All (Top);
>     end Create_Window;
> begin
>     Gtk.Main.Init;
>     Create_Window;
>     Gtk.Main.Main;
> end hello;
> 
> I pass the topwindow to the eventhandler(slot).
> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
> {The label is not directly visible in the handler ...}
> 
> package body buttonhandler is
>     procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>     begin
>        Put_line ("Hallo");
>        -- I need to go from Top to Vbox to Label and set text ... ????
>     end On_Button_Click;
> end buttonhandler;

It is possible to enumerate children of a container, but that is not the 
recommended way as it is weakly typed and fragile. A better way is a 
derived widget. It is very easy to drive customized widgets in GtkAda. E.g.

    type My_Box_Record is new Gtk_VBox with -- Derive from VBox
        Button : Gtk_Button;
        Label  : Gtk_Label;
    end record;
    type My_Box is access all My_Box_Record;
    procedure Gtk_New (Box : out My_Box);

Creation:

    procedure Gtk_New (Box : out My_Box) is
    begin
       Box := new My_Box_Record;
       Initialize_Vbox (Box); -- Parent's initialization from Gtk_Box
       Gtk_New (Box.Button);
       Box.Add (Box.Button);
       Gtk_New (Box.Label);
       Box.Add (Box.Label);

       -- Connect signal handlers here, pass My_Box to them

    end Get_New;

Put declaration of the custom widget in a separate package. All handlers 
go into the package body. [This will reduce the inevitable mess GTK 
imposes on any otherwise cleanly designed Ada application]

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


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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
  2019-11-02 11:00 ` Alain De Vos
  2019-11-02 11:03 ` Dmitry A. Kazakov
@ 2019-11-02 15:27 ` Alain De Vos
  2019-11-02 16:18   ` Dmitry A. Kazakov
  2019-11-02 19:07 ` Alain De Vos
  2019-11-02 22:03 ` Alain De Vos
  4 siblings, 1 reply; 8+ messages in thread
From: Alain De Vos @ 2019-11-02 15:27 UTC (permalink / raw)


On Saturday, November 2, 2019 at 11:22:49 AM UTC+1, Alain De Vos wrote:
> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
> 
> procedure hello is
>    Top     : Gtk.Window.Gtk_Window;
>    Button  : Gtk_Button;
>    Label   : Gtk_Label;
>    VBox    : Gtk_Box;
>    procedure Create_Window is
>    begin
>       Gtk.Window.Gtk_New
>         (Window   => Top,
>          The_Type => Gtk.Enums.Window_Toplevel);
>       Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>       Gtk_New(Button);
>       Button.On_Clicked (Call => On_Button_Click'Access, 
>                          Slot => Top);
>       Gtk_New(Label);
>       Gtk_New_Vbox(VBox);
>       Add (VBox,Button);
>       Add (VBox,Label);
>       Add (Top,VBox);
>       Gtk.Window.Show_All (Top);
>    end Create_Window;
> begin
>    Gtk.Main.Init;
>    Create_Window;
>    Gtk.Main.Main;
> end hello;
> 
> I pass the topwindow to the eventhandler(slot).
> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
> {The label is not directly visible in the handler ...}
> 
> package body buttonhandler is
>    procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>    begin
>       Put_line ("Hallo");
>       -- I need to go from Top to Vbox to Label and set text ... ????
>    end On_Button_Click;
> end buttonhandler;

In the main program I can have,
MyVBox.Button.On_Clicked (Call => On_Button_Click'Access, Slot => Top);
MyVBox.Button.On_Clicked (Call => On_Button_Click'Access, Slot => MyVBox);
with
Top     : Gtk.Window.Gtk_Window;
MyVBox  : MyVBoxT;
Both work fine,

In handler i can have,
procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class),
this works fine,
But when i try :
procedure On_Button_Click (MyVBox : access Gtk_Button_Record'Class)
the error received is :

hello.adb:33:56: expected type "Cb_GObject_Void" defined at gtk-button.ads:445
hello.adb:33:56: found type access to procedure "On_Button_Click" defined at...

In the docs procedure On_Clicked is defined as :
   (Self  : not null access Gtk_Button_Record;
    Call  : Cb_Gtk_Button_Void;
    After : Boolean := False);


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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 15:27 ` Alain De Vos
@ 2019-11-02 16:18   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2019-11-02 16:18 UTC (permalink / raw)


On 2019-11-02 16:27, Alain De Vos wrote:

> In the main program I can have,
> MyVBox.Button.On_Clicked (Call => On_Button_Click'Access, Slot => Top);
> MyVBox.Button.On_Clicked (Call => On_Button_Click'Access, Slot => MyVBox);
> with
> Top     : Gtk.Window.Gtk_Window;
> MyVBox  : MyVBoxT;
> Both work fine,
> 
> In handler i can have,
> procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class),
> this works fine,
> But when i try :
> procedure On_Button_Click (MyVBox : access Gtk_Button_Record'Class)

Because Gtk_Button_Record'Class and GObject_Record'Class are two 
different types. On_Clicked with Slot parameter require downcasting, 
which is why you should use Gtk.Handlers.User_Callback instead.

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


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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
                   ` (2 preceding siblings ...)
  2019-11-02 15:27 ` Alain De Vos
@ 2019-11-02 19:07 ` Alain De Vos
  2019-11-02 19:21   ` Dmitry A. Kazakov
  2019-11-02 22:03 ` Alain De Vos
  4 siblings, 1 reply; 8+ messages in thread
From: Alain De Vos @ 2019-11-02 19:07 UTC (permalink / raw)


On Saturday, November 2, 2019 at 11:22:49 AM UTC+1, Alain De Vos wrote:
> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
> 
> procedure hello is
>    Top     : Gtk.Window.Gtk_Window;
>    Button  : Gtk_Button;
>    Label   : Gtk_Label;
>    VBox    : Gtk_Box;
>    procedure Create_Window is
>    begin
>       Gtk.Window.Gtk_New
>         (Window   => Top,
>          The_Type => Gtk.Enums.Window_Toplevel);
>       Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>       Gtk_New(Button);
>       Button.On_Clicked (Call => On_Button_Click'Access, 
>                          Slot => Top);
>       Gtk_New(Label);
>       Gtk_New_Vbox(VBox);
>       Add (VBox,Button);
>       Add (VBox,Label);
>       Add (Top,VBox);
>       Gtk.Window.Show_All (Top);
>    end Create_Window;
> begin
>    Gtk.Main.Init;
>    Create_Window;
>    Gtk.Main.Main;
> end hello;
> 
> I pass the topwindow to the eventhandler(slot).
> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
> {The label is not directly visible in the handler ...}
> 
> package body buttonhandler is
>    procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>    begin
>       Put_line ("Hallo");
>       -- I need to go from Top to Vbox to Label and set text ... ????
>    end On_Button_Click;
> end buttonhandler;

Ok, so now I try to force a casting, but I'm still not there,

package body buttonhandler is
   type MyVBoxR is new Gtk_VBox_Record with record
      Button : Gtk_Button;
      Label  : Gtk_Label;
   end record;
   type MyVBoxT is access all MyVBoxR'Class;
   procedure On_Button_Click (T : access Glib.Object.GObject_Record'Class) is
      MyVBox  : MyVBoxT;
   begin
      Put_line ("You pressed");
      MyVBox :=MyVBoxT (T);   -- Dangerous
      Gtk.Button.Set_Label (MyVBox.Button,"You pressed");
   end On_Button_Click;
end buttonhandler;

No compile time warning but a runtime error on "MyVBox :=MyVBoxT (T);"  ,
the error is :
Hallo
raised CONSTRAINT_ERROR : buttonhandler.adb:15 tag check failed

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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 19:07 ` Alain De Vos
@ 2019-11-02 19:21   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2019-11-02 19:21 UTC (permalink / raw)


On 2019-11-02 20:07, Alain De Vos wrote:
> On Saturday, November 2, 2019 at 11:22:49 AM UTC+1, Alain De Vos wrote:
>> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
>>
>> procedure hello is
>>     Top     : Gtk.Window.Gtk_Window;
>>     Button  : Gtk_Button;
>>     Label   : Gtk_Label;
>>     VBox    : Gtk_Box;
>>     procedure Create_Window is
>>     begin
>>        Gtk.Window.Gtk_New
>>          (Window   => Top,
>>           The_Type => Gtk.Enums.Window_Toplevel);
>>        Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>>        Gtk_New(Button);
>>        Button.On_Clicked (Call => On_Button_Click'Access,
>>                           Slot => Top);
>>        Gtk_New(Label);
>>        Gtk_New_Vbox(VBox);
>>        Add (VBox,Button);
>>        Add (VBox,Label);
>>        Add (Top,VBox);
>>        Gtk.Window.Show_All (Top);
>>     end Create_Window;
>> begin
>>     Gtk.Main.Init;
>>     Create_Window;
>>     Gtk.Main.Main;
>> end hello;
>>
>> I pass the topwindow to the eventhandler(slot).
>> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
>> {The label is not directly visible in the handler ...}
>>
>> package body buttonhandler is
>>     procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>>     begin
>>        Put_line ("Hallo");
>>        -- I need to go from Top to Vbox to Label and set text ... ????
>>     end On_Button_Click;
>> end buttonhandler;
> 
> Ok, so now I try to force a casting, but I'm still not there,
> 
> package body buttonhandler is
>     type MyVBoxR is new Gtk_VBox_Record with record
>        Button : Gtk_Button;
>        Label  : Gtk_Label;
>     end record;
>     type MyVBoxT is access all MyVBoxR'Class;
>     procedure On_Button_Click (T : access Glib.Object.GObject_Record'Class) is
>        MyVBox  : MyVBoxT;
>     begin
>        Put_line ("You pressed");
>        MyVBox :=MyVBoxT (T);   -- Dangerous
>        Gtk.Button.Set_Label (MyVBox.Button,"You pressed");
>     end On_Button_Click;
> end buttonhandler;
> 
> No compile time warning but a runtime error on "MyVBox :=MyVBoxT (T);"  ,
> the error is :
> Hallo
> raised CONSTRAINT_ERROR : buttonhandler.adb:15 tag check failed

Which is why the idea is bad.

The proper conversion would look like this:

    MyVBoxR'Class (T.all)'Unchecked_Access

However in Ada it is done rather this way:

    procedure On_Button_Click (T : access GObject_Record'Class) is
       MyVBox : MyVBoxR'Class renames MyVBoxR'Class (T.all);
    begin
       MyVBox.Button.Set_Label ("You pressed");
       ...

Note that in GtkAda you must catch and suppress exceptions. If Ada 
exceptions propagate into C code they kill all application. The right 
way is this:

    with GLib.Messages;  use GLib.Messages;

    procedure On_Button_Click (T : access GObject_Record'Class) is
    begin
       declare
          MyVBox : MyVBoxR'Class renames MyVBoxR'Class (T.all);
       begin
          MyVBox.Button.Set_Label ("You pressed");
          ...
       end;
    exception
       when Error : others =>
          Log
          (  "MyApp",
             Log_Level_Critical,
             (  "Fault: "
             &  Exception_Information (Error)
             &  " in On_Button_Click "
          )  );
    end On_Button_Click;

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


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

* Re: gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler
  2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
                   ` (3 preceding siblings ...)
  2019-11-02 19:07 ` Alain De Vos
@ 2019-11-02 22:03 ` Alain De Vos
  4 siblings, 0 replies; 8+ messages in thread
From: Alain De Vos @ 2019-11-02 22:03 UTC (permalink / raw)


On Saturday, November 2, 2019 at 11:22:49 AM UTC+1, Alain De Vos wrote:
> I have a window with obe button and one label and want to change the text on the label when the button is pressed in the eventhandler, I pass the top window.
> 
> procedure hello is
>    Top     : Gtk.Window.Gtk_Window;
>    Button  : Gtk_Button;
>    Label   : Gtk_Label;
>    VBox    : Gtk_Box;
>    procedure Create_Window is
>    begin
>       Gtk.Window.Gtk_New
>         (Window   => Top,
>          The_Type => Gtk.Enums.Window_Toplevel);
>       Gtk.Window.Set_Title (Window => Top, Title  => "Hello from ADA");
>       Gtk_New(Button);
>       Button.On_Clicked (Call => On_Button_Click'Access, 
>                          Slot => Top);
>       Gtk_New(Label);
>       Gtk_New_Vbox(VBox);
>       Add (VBox,Button);
>       Add (VBox,Label);
>       Add (Top,VBox);
>       Gtk.Window.Show_All (Top);
>    end Create_Window;
> begin
>    Gtk.Main.Init;
>    Create_Window;
>    Gtk.Main.Main;
> end hello;
> 
> I pass the topwindow to the eventhandler(slot).
> In the eventhandler I need go from the Top to the Vbox to the Label and set the text on the label ... button pressed. I probably need to set a property in the main and query it in the handler and cast the correct type ...
> {The label is not directly visible in the handler ...}
> 
> package body buttonhandler is
>    procedure On_Button_Click (Top : access Glib.Object.GObject_Record'Class) is
>    begin
>       Put_line ("Hallo");
>       -- I need to go from Top to Vbox to Label and set text ... ????
>    end On_Button_Click;
> end buttonhandler;

Now it worked. It was imperative to put the custom-widget-MVBox type declaration in only one place , the eventhandler .ads file.


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

end of thread, other threads:[~2019-11-02 22:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-02 10:22 gtkada evenhandler on_procedure method , how to access children of topwindow in the eventhandler Alain De Vos
2019-11-02 11:00 ` Alain De Vos
2019-11-02 11:03 ` Dmitry A. Kazakov
2019-11-02 15:27 ` Alain De Vos
2019-11-02 16:18   ` Dmitry A. Kazakov
2019-11-02 19:07 ` Alain De Vos
2019-11-02 19:21   ` Dmitry A. Kazakov
2019-11-02 22:03 ` Alain De Vos

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