From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,26a21b9e317dc639 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Received: by 10.224.183.16 with SMTP id ce16mr4775279qab.8.1354480947200; Sun, 02 Dec 2012 12:42:27 -0800 (PST) Received: by 10.49.18.231 with SMTP id z7mr1823913qed.25.1354480947135; Sun, 02 Dec 2012 12:42:27 -0800 (PST) Path: gf5ni37485490qab.0!nntp.google.com!i9no641779qap.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sun, 2 Dec 2012 12:42:27 -0800 (PST) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=85.227.233.67; posting-account=l8k8IwoAAADeDydswOzwNzmn10qOk9gt NNTP-Posting-Host: 85.227.233.67 References: <9b0bcb37-8ae3-440f-af4f-a796702e4250@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <6344b2a2-6ce5-4381-ad41-8dc4bf47902f@googlegroups.com> Subject: Re: Access type to member procedure of instance (Object Oriented programming in Ada) From: ake.ragnar.dahlgren@gmail.com Cc: mailbox@dmitry-kazakov.de Injection-Date: Sun, 02 Dec 2012 20:42:27 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2012-12-02T12:42:27-08:00 List-Id: On Thursday, November 22, 2012 11:24:27 AM UTC+1, Dmitry A. Kazakov wrote: > On Thu, 22 Nov 2012 01:47:39 -0800 (PST), ake.ragnar.dahlgren@gmail.com >=20 > wrote: >=20 >=20 >=20 > > As for the Gtkada application I have given up on implementing the MVC >=20 > > pattern using tagged types. >=20 >=20 >=20 > Could you provide more details? >=20 >=20 >=20 > Gtk (and so GtkAda) deploys MVC. E.g. Gtk combo boxes, tree views, column >=20 > renderers are all using the MVC pattern. >=20 >=20 >=20 > > Instead I choose the same approach as was done >=20 > > in the Ada in Denmark wiki. >=20 >=20 >=20 > It is unclear what are the differences, but MVC is a real help when deali= ng >=20 > with Gtk and GUI in general. GtkAda should not pose any difficulties for >=20 > MVC. (You don't need pointers to members for MVC, plain pointers to objec= ts >=20 > are sufficient) >=20 >=20 >=20 > --=20 >=20 > Regards, >=20 > Dmitry A. Kazakov >=20 > http://www.dmitry-kazakov.de I gladly provide more details by giving an example of Ada code. The with st= atements have been omitted and the GUI described by the main_window.glade f= ile is assumed to contain a Label called Main_Label and the window has a de= stroy signal called Main_Window_Quit: procedure Main is begin Application.Main; end Main; package Application is pragma Elaborate_Body; procedure Main; end Application; package body Application is Main_Window_Controller : Controllers.Main_Window.Controller_Ref_Type; Main_Window : Views.Main_Window.Main_Window_Ref_Type; procedure On_Main_Window_Quit(Object : access Gtkada.Builder.Gtkada_Buil= der_Record'Class) renames Main_Window_Controller.On_Quit; procedure Main is begin Main_Window_Controller :=3D new Controllers.Main_Window.Controller_Ty= pe; Main_Window :=3D Views.Main_Window.Create_Main_Window(Main_Window_Con= troller, On_Main_Window_Qu= it'Access); Main_Window.Show; Gtk.Main.Main; -- Enter the main gtk loop. end Main; begin Gtk.Main.Init; end Application; package Controllers.Main_Window is type Controller_Type is tagged private; type Controller_Ref_Type is access all Controller_Type; procedure On_Quit (This : Controller_Type; Object : access Gtkada.Builder.Gtkada_Builder_Record'= Class); private type Controller_Type is new Ada.Finalization.Controlled with null record= ; end Controllers.Main_Window; package body Controllers.Main_Window is procedure On_Quit (This : Controller_Type; Object : access Gtkada.Builder.Gtkada_Builder_Record'Class) is begin GNAT.IO.Put_Line("Will exit the application!"); Gtk.Main.Main_Quit; end On_Quit; end Controllers.Main_Window; package Views.Main_Window is type Main_Window_Type(<>) is tagged private; type Main_Window_Ref_Type is access Main_Window_Type; procedure Show(Main_Window : Main_Window_Type); function Create_Main_Window(Controller : Controllers.Main_Window.Control= ler_Ref_Type; On_Quit : Gtkada.Builder.Builder_Handler) return Main_Window_Ref_Type; private type Main_Window_Type(Controller_Ref : Controllers.Main_Window.Controlle= r_Ref_Type) is new Ada.Finalization.Controlled with record Builder : Gtkada.Builder.Gtkada_Builder; end record; Label : Gtk.Label.Gtk_Label; -- Extracted widget from the xml file overriding procedure Initialize (Main_Window : in out Main_Window_Type); overriding procedure Finalize (Object : in out Main_Window_Type); end Views.Main_Window; package body Views.Main_Window is procedure Show(Main_Window : Main_Window_Type) is begin -- Find our main window, then display it and all of its children. Gtk.Widget.Show_All (Main_Window.Builder.Get_Widget ("Main_Window")); end Show; overriding procedure Initialize (Main_Window : in out Main_Window_Type) = is Error : Glib.Error.GError; =20 begin -- Step 1: create a Builder and add the XML data, Gtkada.Builder.Gtk_New (Main_Window.Builder); Error :=3D Main_Window.Builder.Add_From_File ("main_window.glade"); if Error /=3D null then Ada.Text_IO.Put_Line ("Error : " & Glib.Error.Get_Message (Error))= ; Glib.Error.Error_Free (Error); raise Constraint_Error; end if; -- Step 2: Extract all widgets the application wishes to update declare Widget : Gtk.Widget.Gtk_Widget; use type Gtk.Window.Gtk_Window; begin Widget :=3D Main_Window.Builder.Get_Widget("Main_Label"); if Widget /=3D null then Label :=3D Gtk.Label.Gtk_Label(Widget); if Label /=3D null then Label.Set_Text("Managed to set text successfully!"); else Ada.Text_IO.Put_Line("Could not convert widget to Label"); end if; else Ada.Text_IO.Put_Line("Widget not found!"); end if; end; end Initialize; function Create_Main_Window(Controller : Controllers.Main_Window.Control= ler_Ref_Type; On_Quit : Gtkada.Builder.Builder_Handler) re= turn Main_Window_Ref_Type is Main_Window : Main_Window_Ref_Type :=3D new Main_Window_Type(Controll= er); begin Gtkada.Builder.Register_Handler (Builder =3D> Main_Window.Builder, Handler_Name =3D> "Main_Window_Quit", Handler =3D> On_Quit); -- Step 3: Call Do_Connect once to connect all registered handlers Main_Window.Builder.Do_Connect; return Main_Window; end Create_Main_Window; overriding procedure Finalize (Object : in out Main_Window_Type) is begin Object.Builder.Unref; end Finalize; end Views.Main_Window; What I am trying to achieve is something like can be read in the Applicatio= n.Main procedure. And to be able to do that I've used the forbidden renames= feature of the GNAT compiler (as Brian and Randy has pointed out): procedure On_Main_Window_Quit(Object : access Gtkada.Builder.Gtkada_Buil= der_Record'Class) renames Main_Window_Controller.On_Quit; I hope it has been interesting reading these thoughts on Gtkada development= . Best regards, =C5ke Ragnar Dahlgren