comp.lang.ada
 help / color / mirror / Atom feed
* [wxAda] Problem with "limited with" in a *real* application
@ 2005-10-11 15:17 Lucretia
  2005-10-11 21:23 ` Randy Brukardt
  0 siblings, 1 reply; 9+ messages in thread
From: Lucretia @ 2005-10-11 15:17 UTC (permalink / raw)


I have a type hierarchy which is rooted at wx.Factory.Factory_Type,
inside this package there is a function which allows the programmer to
get the C++ pointer to the wx instance for any wxAda type
(Get_wxObject).

<wx.Factory>
package wx.Factory is

  -- This is the base type of all wxAda types.
  type Factory_Type is new Ada.Finalization.Limited_Controlled with
private;
  ...
  function Get_wxObject(Self : in Factory_Type) return System.Address;
  ...

end wx.Factory;
</wx.Factory>

Inside wx.Core.Sizer I have a Set_Sizer procedure which actually
belongs to the wxWindow class and thus should be inside wx.Core.Window.
It cannot go there currently, because of cyclic dependencies
(wx.Core.Sizer also requires access to wx.Core.Window). I have tried to
get this working using Ada 2005's "limited with" but for some reason I
just cannot get it to compile. I think wx.Core.Window needs to have the
full view of the Sizer_Type.

<wx.Core.Window>
limited with wx.Core.Sizer;

package wx.Core.Window is

  type Window_Type is new Event_Handler_Type with private;

  procedure Set_Sizer(
    Self : in Window_Type;
    Sizer : access wx.Core.Sizer.Sizer_Type;
    Delete_Old_Sizer : in Boolean := True);

end wx.Core.Window;


package body wx.Core.Window is

  procedure Set_Sizer(
    Self : in Window_Type;
    Sizer : access wx.Core.Sizer.Sizer_Type;
    Delete_Old_Sizer : in Boolean := True) is

    procedure wxWindow_SetSizer(
      Self, Sizer : in System.Address;
      Delete_Old_Sizer : in C.int);
    pragma Import(C, wxWindow_SetSizer, "wxWindow_SetSizer");

    Delete_Old_Sizer_Converted : C.int := 0;

  begin

    if Delete_Old_Sizer = True then

      Delete_Old_Sizer_Converted := 1;

    end if;

    wxWindow_SetSizer(Get_wxObject(Self), Get_wxObject(Sizer.all),
Delete_Old_Sizer_Converted);

  end Set_Sizer;

end wx.Core.Window;
</wx.Core.Window>

<log>
$ gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1-20050902/configure
--prefix=/opt/gcc-4.1-20050902 --enable-libada
--enable-languages=c,c++,objc,ada
Thread model: posix
gcc version 4.1.0 20050902 (experimental)

...

gcc -c -g -gnatf -gnatwj -gnat05 wx-core-window.adb
wx-core-window.adb:751:43: no candidate interpretations match the
actuals:
wx-core-window.adb:751:62: missing with_clause for scope of imported
type "Sizer.Sizer_Type"
wx-core-window.adb:751:62:   ==> in call to "get_wxobject" at
wx-core-window.ads:22(inherited)
wx-core-window.adb:751:62:   ==> in call to "get_wxobject" at
wx-core-colour.ads:9(inherited)
wx-core-window.adb:751:62:   ==> in call to "get_wxobject" at
wx-base-event_handler.ads:17(inherited)
wx-core-window.adb:751:62:   ==> in call to "get_wxobject" at
wx-base-event.ads:18(inherited)
wx-core-window.adb:751:62:   ==> in call to "get_wxobject" at
wx-base-object.ads:21(inherited)
wx-core-window.adb:751:62:   ==> in call to "Get_wxObject" at
wx-factory.ads:32
gnatmake: "wx-core-window.adb" compilation error

raised MAKE.COMPILATION_FAILED : make.adb:4791
</log>




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

* Re: [wxAda] Problem with "limited with" in a *real* application
  2005-10-11 15:17 [wxAda] Problem with "limited with" in a *real* application Lucretia
@ 2005-10-11 21:23 ` Randy Brukardt
  2005-10-12 17:06   ` Lucretia
  0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2005-10-11 21:23 UTC (permalink / raw)


"Lucretia" <lucretia9@lycos.co.uk> wrote in message
news:1129043820.987947.200870@z14g2000cwz.googlegroups.com...
...
> Inside wx.Core.Sizer I have a Set_Sizer procedure which actually
> belongs to the wxWindow class and thus should be inside wx.Core.Window.
> It cannot go there currently, because of cyclic dependencies
> (wx.Core.Sizer also requires access to wx.Core.Window). I have tried to
> get this working using Ada 2005's "limited with" but for some reason I
> just cannot get it to compile. I think wx.Core.Window needs to have the
> full view of the Sizer_Type.

Yes, it does. And you can get it by putting a *regular* with of
wx.Core.Sizer on the *body* of wx.Core.Window.

That's the expected pattern: limited with on the spec to break circularity,
(regular) with on the body to allow the use of the full type. You do need to
worry about elaboration issues when you do this, though (preferably, avoid
doing any calls during the elaboration of the packages). This latter concern
doesn't exist in the "default" GNAT elaboration mode (which isn't quite the
same as Ada's), but it does if you worry about portability of your code.

                                Randy.









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

* Re: Problem with "limited with" in a *real* application
  2005-10-11 21:23 ` Randy Brukardt
@ 2005-10-12 17:06   ` Lucretia
  2005-10-13 14:50     ` Lucretia
  0 siblings, 1 reply; 9+ messages in thread
From: Lucretia @ 2005-10-12 17:06 UTC (permalink / raw)


Thanks, I'll try that later.

Luke.




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

* Re: Problem with "limited with" in a *real* application
  2005-10-12 17:06   ` Lucretia
@ 2005-10-13 14:50     ` Lucretia
  2005-10-13 16:18       ` Lucretia
  0 siblings, 1 reply; 9+ messages in thread
From: Lucretia @ 2005-10-13 14:50 UTC (permalink / raw)


Ok, so I tried the above and got it compiling, so I tried to remove the
"access" in an attempt to make the interface a bit cleaner and there
are more problems...

<wx.Core.Window>
...
limited with wx.Core.Sizer;

package wx.Core.Window is

  -- This is the actual type (wxWindow) we are creating here.
  type Window_Type is new Event_Handler_Type with private;

  ...
  procedure Set_Sizer(
    Self : in Window_Type;
    Sizer : in wx.Core.Sizer.Sizer_Type;
    Delete_Old_Sizer : in Boolean := True);
  ...

end wx.Core.Window;
</wx.Core.Window>

<wx.Core.Window>
...
with wx.Core.Sizer; use wx.Core.Sizer;

package body wx.Core.Window is

  ...

  procedure Set_Sizer(
    Self : in Window_Type;
    Sizer : in wx.Core.Sizer.Sizer_Type;
    Delete_Old_Sizer : in Boolean := True) is

    procedure wxWindow_SetSizer(
      Self, Sizer : in System.Address;
      Delete_Old_Sizer : in C.int);
    pragma Import(C, wxWindow_SetSizer, "wxWindow_SetSizer");

    Delete_Old_Sizer_Converted : C.int := 0;

  begin

    if Delete_Old_Sizer = True then

      Delete_Old_Sizer_Converted := 1;

    end if;

    wxWindow_SetSizer(Get_wxObject(Self), Get_wxObject(Sizer),
Delete_Old_Sizer_Converted);

  end Set_Sizer;

  ...

end wx.Core.Window;
</wx.Core.Window>

I've had to cast the sizer type to the base sizer in the Set_Sizer
procedure call:

<Minimal_Frame>
package body Minimal_Frame is

  ...

  procedure New_Minimal_Frame(Self : in out Minimal_Frame_Type) is

    ...

  begin

    ...
    Set_Sizer(Window_Type(Self.Panel), Sizer_Type(Self.Sizer));
    ...

  end New_Minimal_Frame;

  ...

end Minimal_Frame;
</Minimal_Frame>

But for some reason, the app won't link because Set_Sizer is undefined:

<log>
gnatlink minimal.ali -o minimal -lwxada -L../../src
-L/home/laguest/opt/wxGTK/lib -pthread -lwx_gtk2d_xrc-2.6
-lwx_gtk2d_qa-2.6 -lwx_gtk2d_html-2.6 -lwx_gtk2d_dbgrid-2.6
-lwx_gtk2d_adv-2.6 -lwx_gtk2d_core-2.6 -lwx_based_odbc-2.6
-lwx_based_xml-2.6 -lwx_based_net-2.6 -lwx_based-2.6
../../src/ada/wx-core-window.o(.text+0x5b37): In function
`wx.core.window._elabs':
/home/laguest/src/svn-controlled/wxAda/src/ada/wx-core-window.ads:318:
undefined reference to `wx__core__window__set_sizer'
../../src/ada/wx-core-window.o(.text+0x5b48):/home/laguest/src/svn-controlled/wxAda/src/ada/wx-core-window.ads:318:
undefined reference to `wx__core__window__set_sizer'
./minimal_frame.o(.text+0x11d5): In function
`minimal_frame.new_minimal_frame':
/home/laguest/src/svn-controlled/wxAda/samples/minimal/minimal_frame.adb:214:
undefined reference to `wx__core__window__set_sizer'
collect2: ld returned 1 exit status
gnatlink: cannot call /opt/gcc-4.1-20050902/bin/gcc
</log>

And, yes wx-core-window.ad[sb] is getting compiled, I have already mde
sure of that by deleting the object and then recompiling and then doing
an objdump on wx-core-window.o only to find that set_sizer is undefined
for some reason!

But, ultimately I don't want to be casting all the time, so if I change
the specification of the procedure of Set_Sizer to read:

<wx.Core.Window>
  ...
  procedure Set_Sizer(
    Self : in Window_Type;
    Sizer : in wx.Core.Sizer.Sizer_Type'Class;
    Delete_Old_Sizer : in Boolean := True);
  ...
</wx.Core.Window>

and similarly in the body, things gets even weirder:

<log>
gcc -c -g -gnatf -gnatwj -gnat05 wx-core-window.adb
wx-core-window.adb:737:46: not type conformant with declaration at
wx-core-window.ads:141
wx-core-window.adb:737:46: type of "Sizer" does not match
gnatmake: "wx-core-window.adb" compilation error
</log>

What's going on in these cases?

Thanks,
Luke.




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

* Re: Problem with "limited with" in a *real* application
  2005-10-13 14:50     ` Lucretia
@ 2005-10-13 16:18       ` Lucretia
  2005-10-14  0:36         ` Randy Brukardt
  0 siblings, 1 reply; 9+ messages in thread
From: Lucretia @ 2005-10-13 16:18 UTC (permalink / raw)


In reference to the second part of my question above, am I using 'Class
correctly here? I am confused as to when to use them.

I'll bring in the Minimal_Frame package into the library tomorrow so I
can post it as I'm using way too much casting (I think) due to the
compiler throwing up errors. Yet as I understand it I shouldn't need to
cast all these calls, especially on the first parameter, Self, or maybe
I'm confused (most probably).

Luke.




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

* Re: Problem with "limited with" in a *real* application
  2005-10-13 16:18       ` Lucretia
@ 2005-10-14  0:36         ` Randy Brukardt
  2005-10-14 15:03           ` Lucretia
  0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2005-10-14  0:36 UTC (permalink / raw)


"Lucretia" <lucretia9@lycos.co.uk> wrote in message
news:1129220290.938615.36390@o13g2000cwo.googlegroups.com...
> In reference to the second part of my question above, am I using 'Class
> correctly here? I am confused as to when to use them.

I think so. My rule of thumb is that a non-controlling parameter of a
specific tagged type is almost always a bug. (The main exception being
constructors, as those generally only work for one kind of object.)

> I'll bring in the Minimal_Frame package into the library tomorrow so I
> can post it as I'm using way too much casting (I think) due to the
> compiler throwing up errors. Yet as I understand it I shouldn't need to
> cast all these calls, especially on the first parameter, Self, or maybe
> I'm confused (most probably).

I think there is some bug in the compiler, since what you are doing looks OK
to me. It's roughly what I would do in this circumstance. Certainly, the
conformance error suggests a compiler bug, because the types are clearly
exactly the same.

Given the newness of the compiler and the near total lack of test cases for
compiler writers to use, I'd expect a lot of bugs in these new Ada 200Y
features. So don't get too discouraged about that (but it might mean you
have to wait a while). We had to delay releasing Claw for almost 18 months,
because none of the compilers (including ours!) could compile it when we
first wrote it. We had to wait for the bug fixes to propagate into the
standard versions.

                                             Randy.






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

* Re: Problem with "limited with" in a *real* application
  2005-10-14  0:36         ` Randy Brukardt
@ 2005-10-14 15:03           ` Lucretia
  2005-10-14 23:47             ` Randy Brukardt
  0 siblings, 1 reply; 9+ messages in thread
From: Lucretia @ 2005-10-14 15:03 UTC (permalink / raw)


Inside the Sizer package I have an Add procedure which adds a
Window_Type (e.g. Button_Type, Check_Box_Type, etc) into the derived
type to Self, which is a Sizer_Type derived type. So, I want (ideally)
to minimize the casting, so I changed the Window type to take a
Window_Type'Class so that any type can be accepted. Now, this forces me
to cast the Self type in the New_Minimal_Frame procedure (See the
Add's) to the base Sizer_Type. Now in C++ the Add function can be
overridden (as in the case of wxGridBagSizer and they're not virtuals)
so in the case of mapping to Ada in this current form, the programmer
must know which Add to use, i.e. which cast to use, which is fair
enough, but surely it would be easier to let the compiler decide?
Should I use a 'Class type here?

So, with this in mind, it's a possibility that all of the wxAda
primitives could take 'Class types so that no casting is ever needed,
but surely this is wrong, Ada-wise?

The format of the following code might get a bit screwed by Google:

<wx.Core.Sizer>
package wx.Core.Sizer is

  -- This is the actual type (wxSizer) we are creating here.
  type Sizer_Type is new Object_Type with private;

  procedure Add(
    Self       : in out Sizer_Type;
    Window     : in Window_Type'Class;
    Proportion : in Sizer_Proportion_Type := 0;
    Flags      : in Sizer_Flag_Type := 0;
    Border     : in Integer := 0);

end wx.Core.Sizer;
</wx.Core.Sizer>

<Minimal_Frame>
package body Minimal_Frame is

  procedure New_Minimal_Frame(Self : in out Minimal_Frame_Type) is

    procedure Button_Connect is new
wxEvtHandler.Connect(Command_Event_Function);
    procedure Check_Box_Connect is new
wxEvtHandler.Connect(Command_Event_Function);
    procedure My_Test_Connect is new
wxEvtHandler.Connect(On_My_Test_Function);
    procedure Slider_Connect is new
wxEvtHandler.Connect(Scroll_Event_Function);
    procedure Size_Connect is new
wxEvtHandler.Connect(Size_Event_Function);
    procedure Paint_Connect is new
wxEvtHandler.Connect(Paint_Event_Function);

    Field_Widths : Field_Widths_Array(0 .. 1) := (-3, -1);

    package Address_To_Object is new
System.Address_To_Access_Conversions(Minimal_Frame_Type);
    use Address_To_Object;

  begin

    New_Frame(Self, ID_ANY, "Minimal wxAda App", Point_Type'(400,
300));
    Text_IO.Put_Line("Self'Access : " &
System.Address_Image(To_Address(Self'Access)));

    New_Panel(Self.Panel, Window_Type(Self), Id_Any);

    New_Validator(Self.Validator);

    New_Button(Self.Button, Window_Type(Self.Panel),
Id_Type(Id_Test_Button), "Test &Button", Default_Position,
Default_Size, 0);
    Set_Validator(Window_Type(Self.Button), Self.Validator);

    New_Check_Box(Self.Check_Box, Window_Type(Self.Panel), Id_Any,
"Test &Check Box", Style => Check_Box_Align_Right);
    New_Slider(Self.Slider, Window_Type(Self.Panel), Id_Any, 50, 0,
100, Style => Slider_Horizontal or Slider_Labels);
    New_Spin(Self.Spin, Window_Type(Self.Panel), Id_Any, "0", Style =>
Spin_Wrap or Spin_Arrow_Keys);
    New_Scroll_Bar(Self.Scroll_Bar, Window_Type(Self.Panel),
Id_Type(Id_Test_Slider));
    Set_Scroll_Bar(Self.Scroll_Bar, 20, 10, 100, 1000);

    New_Static_Box(Self.Box, Window_Type(Self.Panel), Id_Any,
"Testing...");
    New_Static_Box_Sizer(Self.Sizer, Self.Box'Unchecked_Access,
Box_Sizer_Orientation_Vertical);
    --New_Box_Sizer(Self.Sizer, Box_Sizer_Orientation_Vertical);
    Add(Sizer_Type(Self.Sizer), Self.Button, 1, Sizer_Expand or
Sizer_Border_All, 5);
    Add(Sizer_Type(Self.Sizer), Self.Check_Box, 1, Sizer_Expand or
Sizer_Border_All, 5);
    Add(Sizer_Type(Self.Sizer), Self.Slider, 1, Sizer_Expand or
Sizer_Border_All, 5);
    Add(Sizer_Type(Self.Sizer), Self.Spin, 1, Sizer_Expand or
Sizer_Border_All, 5);
    Add(Sizer_Type(Self.Sizer), Self.Scroll_Bar, 1, Sizer_Expand or
Sizer_Border_All, 5);

    New_Status_Bar(Self.Status_Bar, Window_Type(Self), Id_Any);
    Set_Fields_Count(Self.Status_Bar, Field_Widths);
    Set_Status_Bar(Self, Self.Status_Bar);
    Set_Status_Text(Self.Status_Bar, "Welcome to wxAda!");
--    Set_Status_Widths(Test_Status_Bar, Field_Widths'Length,
Field_Widths);

    Set_Size_Hints(Sizer_Type(Self.Sizer),
Self.Panel'Unchecked_Access);
--    Set_Sizer(Window_Type(Self.Panel), Self.Sizer'Unchecked_Access);
    Set_Sizer(Window_Type(Self.Panel), Sizer_Type(Self.Sizer)'Access);
--    Set_Sizer(Self.Panel, Sizer_Type(Self.Sizer));

    Test_Event.New_Test_Event(Self.My_Test);

    --Button_Connect(Self, Id_Type(ID_TEST_BUTTON), Id_Any,
wx.Base.Event.Command.Button_Clicked, On_Quit'Access);
    Button_Connect(Self, Id_Type(Id_Test_Button), Id_Any,
Evt_Button_Clicked, On_Quit'Access);
    --Check_Box_Connect(Self, Id_Type(ID_TEST_BUTTON), Id_Any,
wx.Base.Event.Command.Check_Box_Clicked, On_Quit'Access);
    Slider_Connect(Self, Id_Type(Id_Test_Slider), Id_Any,
Evt_Scroll_Thumb_Track, On_Scroll_Top'Access);
    Size_Connect(Self, Id_Any, Id_Any, Evt_Size, On_Size'Access);
    --Paint_Connect(Self.Panel, Id_Any, Id_Any, Evt_Paint,
On_Paint'Access);
    Dump(Self);
    My_Test_Connect(Self, Id_Any, Id_Any, Test_Event.My_Test_Event,
On_My_Test'Access);
    
  end New_Minimal_Frame;

end Minimal_Frame;
</Minimal_Frame>




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

* Re: Problem with "limited with" in a *real* application
  2005-10-14 15:03           ` Lucretia
@ 2005-10-14 23:47             ` Randy Brukardt
  2005-10-15 13:48               ` Lucretia
  0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2005-10-14 23:47 UTC (permalink / raw)


"Lucretia" <lucretia9@lycos.co.uk> wrote in message
news:1129302185.489627.266900@g47g2000cwa.googlegroups.com...
> Inside the Sizer package I have an Add procedure which adds a
> Window_Type (e.g. Button_Type, Check_Box_Type, etc) into the derived
> type to Self, which is a Sizer_Type derived type. So, I want (ideally)
> to minimize the casting, so I changed the Window type to take a
> Window_Type'Class so that any type can be accepted. Now, this forces me
> to cast the Self type in the New_Minimal_Frame procedure (See the
> Add's) to the base Sizer_Type. Now in C++ the Add function can be
> overridden (as in the case of wxGridBagSizer and they're not virtuals)
> so in the case of mapping to Ada in this current form, the programmer
> must know which Add to use, i.e. which cast to use, which is fair
> enough, but surely it would be easier to let the compiler decide?
> Should I use a 'Class type here?

Probably not. If you need overriding and/or dispatching somewhere, you'll
want to avoid 'Class. My rule of thumb is that primitives should be specific
unless you're absolutely certain that you'll never want to override them in
any child types. (And when is that true?).

You have to use a (view) type conversion (what you've been calling a "cast")
to all the operations of the parent type. That's just the way you write that
in Ada. OTOH, it's usually not necessary to do that for most operations,
because they are inherited, and you can just call them for the type itself.

> So, with this in mind, it's a possibility that all of the wxAda
> primitives could take 'Class types so that no casting is ever needed,
> but surely this is wrong, Ada-wise?

It's probably wrong, but I'd have to see your entire design to know for
sure. Which I'd rather not do...

> The format of the following code might get a bit screwed by Google:
>
> <wx.Core.Sizer>
> package wx.Core.Sizer is
>
>   -- This is the actual type (wxSizer) we are creating here.
>   type Sizer_Type is new Object_Type with private;

-- All of the (primitive) operations of the parent type are inherited here,
-- so you can call them without using any type conversions.

>   procedure Add(
>     Self       : in out Sizer_Type;
>     Window     : in Window_Type'Class;
>     Proportion : in Sizer_Proportion_Type := 0;
>     Flags      : in Sizer_Flag_Type := 0;
>     Border     : in Integer := 0);
>
> end wx.Core.Sizer;
> </wx.Core.Sizer>
>
> <Minimal_Frame>
> package body Minimal_Frame is
>
>   procedure New_Minimal_Frame(Self : in out Minimal_Frame_Type) is
>
>     procedure Button_Connect is new
> wxEvtHandler.Connect(Command_Event_Function);
>     procedure Check_Box_Connect is new
> wxEvtHandler.Connect(Command_Event_Function);
>     procedure My_Test_Connect is new
> wxEvtHandler.Connect(On_My_Test_Function);
>     procedure Slider_Connect is new
> wxEvtHandler.Connect(Scroll_Event_Function);
>     procedure Size_Connect is new
> wxEvtHandler.Connect(Size_Event_Function);
>     procedure Paint_Connect is new
> wxEvtHandler.Connect(Paint_Event_Function);
>
>     Field_Widths : Field_Widths_Array(0 .. 1) := (-3, -1);
>
>     package Address_To_Object is new
> System.Address_To_Access_Conversions(Minimal_Frame_Type);
>     use Address_To_Object;
>
>   begin
>
>     New_Frame(Self, ID_ANY, "Minimal wxAda App", Point_Type'(400,
> 300));
>     Text_IO.Put_Line("Self'Access : " &
> System.Address_Image(To_Address(Self'Access)));
>
>     New_Panel(Self.Panel, Window_Type(Self), Id_Any);

Here, the second parameter of New_Panel probably should be class-wide. A
subprogram with two specific different tagged types as parameters is almost
always wrong. (Dmitry will tell you why in excrutating details if you want
to know. :-)

>     New_Validator(Self.Validator);
>
>     New_Button(Self.Button, Window_Type(Self.Panel),
> Id_Type(Id_Test_Button), "Test &Button", Default_Position,
> Default_Size, 0);

Same is true here. In Claw, the Create routines look something like:

     procedure Create (Button : in out Button_Type;
                                  Parent : in out Root_Window_Type'Class;
                                  Size : in Size_Type;
                                  Position : in Point_Type;
                                  ....);

>     Set_Validator(Window_Type(Self.Button), Self.Validator);

Presuming that this is an operation on the root window type, you should be
able to just call this (a Button will have inherited it).

       Set_Validator (Self.Button, Self.Validator);

(or, in C++-like notation in Ada 200Y:)
      Self.Button.Set_Validator (Self.Validator);

The latter notation avoids the need for use-clauses.

If this isn't an operation on the root window type, then there is something
wrong with your design. Either the prefix should be class-wide (and no type
conversion is needed), or it should be primitive so it is inherited (and
thus can be overridden) by other tagged types (window classes).

>     New_Check_Box(Self.Check_Box, Window_Type(Self.Panel), Id_Any,
> "Test &Check Box", Style => Check_Box_Align_Right);
>     New_Slider(Self.Slider, Window_Type(Self.Panel), Id_Any, 50, 0,
> 100, Style => Slider_Horizontal or Slider_Labels);
>     New_Spin(Self.Spin, Window_Type(Self.Panel), Id_Any, "0", Style =>
> Spin_Wrap or Spin_Arrow_Keys);
>     New_Scroll_Bar(Self.Scroll_Bar, Window_Type(Self.Panel),
> Id_Type(Id_Test_Slider));
>     Set_Scroll_Bar(Self.Scroll_Bar, 20, 10, 100, 1000);
>
>     New_Static_Box(Self.Box, Window_Type(Self.Panel), Id_Any,
> "Testing...");
>     New_Static_Box_Sizer(Self.Sizer, Self.Box'Unchecked_Access,
> Box_Sizer_Orientation_Vertical);
>     --New_Box_Sizer(Self.Sizer, Box_Sizer_Orientation_Vertical);
>     Add(Sizer_Type(Self.Sizer), Self.Button, 1, Sizer_Expand or
> Sizer_Border_All, 5);
>     Add(Sizer_Type(Self.Sizer), Self.Check_Box, 1, Sizer_Expand or
> Sizer_Border_All, 5);
>     Add(Sizer_Type(Self.Sizer), Self.Slider, 1, Sizer_Expand or
> Sizer_Border_All, 5);
>     Add(Sizer_Type(Self.Sizer), Self.Spin, 1, Sizer_Expand or
> Sizer_Border_All, 5);
>     Add(Sizer_Type(Self.Sizer), Self.Scroll_Bar, 1, Sizer_Expand or
> Sizer_Border_All, 5);

I don't see any need for the conversions to Sizer_Type here. If Self.Sizer
is derived from Sizer_Type, then Add is inherited. Use that one without a
conversion. (That way, if it becomes necessary to override it in the future,
you'll use the overriding version for the type.) If it is actually
Sizer_Type, you don't need it.

The only problem is figuring out where the routine ("Add" in this case) is
declared, because you can't see inherited declarations. There are a number
of solutions to that:
1) Have a use_clause for every package that declares a type that you use. (I
hate this one myself.)
2) Use dot notation to specify that the routine comes from the package where
the type is declared;
3) or use the prefixed view call notation introduced by Ada 200Y:
    Self.Sizer.Add (Self.Scroll_Bar, 1, Sizer_Expand or Sizer_Border_All,
5);

>     New_Status_Bar(Self.Status_Bar, Window_Type(Self), Id_Any);
>     Set_Fields_Count(Self.Status_Bar, Field_Widths);
>     Set_Status_Bar(Self, Self.Status_Bar);
>     Set_Status_Text(Self.Status_Bar, "Welcome to wxAda!");
> --    Set_Status_Widths(Test_Status_Bar, Field_Widths'Length,
> Field_Widths);
>
>     Set_Size_Hints(Sizer_Type(Self.Sizer),
> Self.Panel'Unchecked_Access);
> --    Set_Sizer(Window_Type(Self.Panel), Self.Sizer'Unchecked_Access);
>     Set_Sizer(Window_Type(Self.Panel), Sizer_Type(Self.Sizer)'Access);
> --    Set_Sizer(Self.Panel, Sizer_Type(Self.Sizer));
>
>     Test_Event.New_Test_Event(Self.My_Test);
>
>     --Button_Connect(Self, Id_Type(ID_TEST_BUTTON), Id_Any,
> wx.Base.Event.Command.Button_Clicked, On_Quit'Access);
>     Button_Connect(Self, Id_Type(Id_Test_Button), Id_Any,
> Evt_Button_Clicked, On_Quit'Access);
>     --Check_Box_Connect(Self, Id_Type(ID_TEST_BUTTON), Id_Any,
> wx.Base.Event.Command.Check_Box_Clicked, On_Quit'Access);
>     Slider_Connect(Self, Id_Type(Id_Test_Slider), Id_Any,
> Evt_Scroll_Thumb_Track, On_Scroll_Top'Access);
>     Size_Connect(Self, Id_Any, Id_Any, Evt_Size, On_Size'Access);
>     --Paint_Connect(Self.Panel, Id_Any, Id_Any, Evt_Paint,
> On_Paint'Access);
>     Dump(Self);
>     My_Test_Connect(Self, Id_Any, Id_Any, Test_Event.My_Test_Event,
> On_My_Test'Access);
>
>   end New_Minimal_Frame;
>
> end Minimal_Frame;
> </Minimal_Frame>

Hope this helps.

                  Randy.






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

* Re: Problem with "limited with" in a *real* application
  2005-10-14 23:47             ` Randy Brukardt
@ 2005-10-15 13:48               ` Lucretia
  0 siblings, 0 replies; 9+ messages in thread
From: Lucretia @ 2005-10-15 13:48 UTC (permalink / raw)


<quote>
Here, the second parameter of New_Panel probably should be class-wide.
A
</quote>

Ok.

<quote>
subprogram with two specific different tagged types as parameters is
almost
always wrong. (Dmitry will tell you why in excrutating details if you
want
to know. :-)
</quote>

Yeah, why not ;-D Doesn't hurt to know.

<quote>
Presuming that this is an operation on the root window type, you should
be
able to just call this (a Button will have inherited it).

       Set_Validator (Self.Button, Self.Validator);
</quote>

Well, Button_Type is derived from Control_Type which in turn is derived
from Window_Type.

<quote>
(or, in C++-like notation in Ada 200Y:)
      Self.Button.Set_Validator (Self.Validator);

The latter notation avoids the need for use-clauses.
</quote>

I didn't know that.

<quote>
I don't see any need for the conversions to Sizer_Type here. If
Self.Sizer
is derived from Sizer_Type, then Add is inherited. Use that one without
a
conversion. (That way, if it becomes necessary to override it in the
future,
you'll use the overriding version for the type.) If it is actually
Sizer_Type, you don't need it.
</quote>

Add is defined in wx.Core.Sizer and the sizer I am using here is
derived from Sizer_Type (it's of Box_Sizer_Type), but by removing the
view conversions, the program doesn't compile for some reason.

<quote>
The only problem is figuring out where the routine ("Add" in this case)
is
declared, because you can't see inherited declarations. There are a
number
of solutions to that:
1) Have a use_clause for every package that declares a type that you
use. (I
hate this one myself.)
</quote>

I'm using this at the moment.

<quote>
2) Use dot notation to specify that the routine comes from the package
where
the type is declared;
3) or use the prefixed view call notation introduced by Ada 200Y:
    Self.Sizer.Add (Self.Scroll_Bar, 1, Sizer_Expand or
Sizer_Border_All,
</quote>

Hmmm, maybe 3 would be a good one?

Thanks,
Luke.




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

end of thread, other threads:[~2005-10-15 13:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-11 15:17 [wxAda] Problem with "limited with" in a *real* application Lucretia
2005-10-11 21:23 ` Randy Brukardt
2005-10-12 17:06   ` Lucretia
2005-10-13 14:50     ` Lucretia
2005-10-13 16:18       ` Lucretia
2005-10-14  0:36         ` Randy Brukardt
2005-10-14 15:03           ` Lucretia
2005-10-14 23:47             ` Randy Brukardt
2005-10-15 13:48               ` Lucretia

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