private with Ada.Containers.Indefinite_Doubly_Linked_Lists;
package Widgets.Containers is
-- A Container widget is a parent widget that contains multiple child
-- widgets. Each child widget is drawn within the content area of the
-- parent. Widget layouts applied to child widgets are relative to the
-- content area of their container. An input event not handled by a widget
-- will be passed up the widget tree to its container.
type Container is abstract new Widget with private;
type A_Container is access all Container'Class;
-- Adds 'child' as a child widget of this container. The child's parent is
-- set by this procedure. If 'consume' is True, 'child' will be consumed,
-- otherwise it will be left as-is. In either case, however, the Container
-- will own 'child' after this is called, and will delete it if it's still a
-- child at the time of deletion.
procedure Add( this : access Container;
child : in out A_Widget;
consume : Boolean := True );
pragma Precondition( child /= null );
pragma Postcondition( consume xor child /= null );
-- Brings the 'child' widget to the front of the drawing Z-order within this
-- container. If 'child' overlaps any sibling widgets, it will be drawn on
-- top.
procedure Bring_To_Front( this : access Container;
child : not null A_Widget );
-- Applies the container's special child layout to the given child widget.
procedure Apply_Container_Layout( this : access Container;
child : not null A_Widget );
-- Removes and deletes all child widgets.
procedure Delete_Children( this : access Container );
-- Draws the container's content behind its children. This will be called
-- before child widgets are drawn, in the back-to-front drawing model.
procedure Draw_Content( this : access Container; dc : Drawing_Context ) is abstract;
-- Removes the widget from the child list without deleting it. The child's
-- parent reference is not modified.
procedure Remove( this : access Container; child : not null A_Widget );
private
WIDGET_NOT_FOUND : exception;
-- provides a linked list of widgets
package Widget_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists( A_Widget, "=" );
----------------------------------------------------------------------------
type Container is abstract new Widget with
record
childbmp : A_Bitmap := null;
children : Widget_Lists.List;
childLayout : A_Layout := null;
-- If True, Draw_Content will be called a second time after drawing
-- children, with the layer of the drawing context set to Foreground.
-- This is so the widget can draw over its children. Setting this to
-- True will cause Draw_Content to be called twice on every redraw,
-- regardless of the container's dirty flag, which is expensive.
drawForeground : Boolean := False;
end record;
procedure Delete( this : in out Container );
-- Removes and deletes a child widget. If the given widget is not a child
-- then a WIDGET_NOT_FOUND exception will be raised. 'child' will be
-- consumed if successful.
procedure Delete_Child( this : access Container; child : in out A_Widget );
pragma Precondition( child /= null );
pragma Postcondition( child = null );
-- Draws self before drawing children, in a back-to-front order.
procedure Draw( this : access Container;
bmp : not null A_Bitmap;
x, y : Integer );
-- Draws each of the children onto 'bmp'. 'bmp' must match the size of the
-- container's content area.
procedure Draw_Children( this : access Container;
bmp : not null A_Bitmap );
-- Returns the child widget (or self) containing the given coordinates
-- relative to the widget's viewport, and the widget coordinates that
-- 'x','y' map to ('wx','wy') within the found widget's content area.
procedure Find_Widget( this : access Container;
x, y : Integer;
wx, wy : out Integer;
found : out A_Widget );
-- Calls Handle_Ancestor_Hidden on each of the children after handling
-- Handle_Ancestor_Hidden for self.
procedure Handle_Ancestor_Hidden( this : access Container );
-- Calls Handle_Ancestor_Unhidden on each of the children after handling
-- Handle_Ancestor_Unhidden for self.
procedure Handle_Ancestor_Unhidden( this : access Container );
-- Invokes Handle_Resize on each of the children after resizing self.
procedure Handle_Resize( this : access Container );
-- Calls Pack on each of the children after packing self.
procedure Pack( this : access Container );
-- Sets the zoom level of the container. If zooming in, the child widgets
-- will appear proportionately larger in size. Their zoom levels remain
-- independently controlled, as expected.
procedure Set_Zoom( this : access Container; zoom : Float );
end Widgets.Containers;