-----------------------------------------------------------------------
-- GtkAda - Ada95 binding for Gtk+/Gnome --
-- --
-- Copyright (C) 2003-2010, AdaCore --
-- --
-- This library is free software; you can redistribute it and/or --
-- modify it under the terms of the GNU General Public --
-- License as published by the Free Software Foundation; either --
-- version 2 of the License, or (at your option) any later version. --
-- --
-- This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public --
-- License along with this library; if not, write to the --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330, --
-- Boston, MA 02111-1307, USA. --
-- --
-- --
-- --
-- --
-- --
-- --
-- --
-----------------------------------------------------------------------
--
-- This widget implements a multi-paned widget, similar to the standard
-- Gtk_Paned widget, but which can contain several children side to side.
-- This widget can mix vertical and horizontal splits
--
-- Layout containers
-- create_splittable.adb
with Glib; use Glib;
with Gdk.Cursor;
with Gdk.GC;
with Gtk.Enums;
with Gtk.Fixed;
with Gtk.Widget;
package Gtkada.Multi_Paned is
type Gtkada_Multi_Paned_Record is new Gtk.Fixed.Gtk_Fixed_Record
with private;
type Gtkada_Multi_Paned is access all Gtkada_Multi_Paned_Record'Class;
Handle_Width : constant := 6;
-- Width, in pixels, of the resizing handles.
-- ??? Should be read from theme with
-- gtk_widget_style_get (gtk_paned, "handle_size", &handle_size, NULL)
type Pane is private;
-- An area of the window, which can is splitted either horizontally or
-- vertically. It can contain one or several children, next to each other,
-- or on top of one another.
Root_Pane : constant Pane;
-- The root pane. If you split this one, the newly added window will be
-- next to all other windows. For instance, if you split vertically with
-- the main_pane the following window, you will get:
-- +-----+------+ +-----+------+
-- | 1 | | | 1 | |
-- +-----+ 3 | => +-----+ 3 |
-- | 2 | | | 2 | |
-- +-----+------+ +-----+------+
-- | 4 |
-- +------------+
procedure Gtk_New (Win : out Gtkada_Multi_Paned);
procedure Initialize (Win : access Gtkada_Multi_Paned_Record'Class);
-- Create a new paned window.
procedure Set_Opaque_Resizing
(Win : access Gtkada_Multi_Paned_Record; Opaque : Boolean);
-- Whether resizing of the widgets should be opaque or not. The default
-- is not to do opaque resizing for efficiency reasons
procedure Add_Child
(Win : access Gtkada_Multi_Paned_Record;
New_Child : access Gtk.Widget.Gtk_Widget_Record'Class;
Orientation : Gtk.Enums.Gtk_Orientation :=
Gtk.Enums.Orientation_Horizontal;
Fixed_Size : Boolean := False;
Width, Height : Glib.Gint := -1;
After : Boolean := True);
-- Add new child, splitting as needed.
-- This should be used when there is no child yet
-- The window is splitted in two by default. However, if Width and Height
-- are specified (or left to -1 for automatic computation), the window is
-- splitted so that amount of screen space is left to the widget
-- (leaving some minimum amount of space to other children as needed).
-- If Fixed_Size is true, then the size of the dock will not change when
-- Win is resized. Otherwise, it will keep its relative size (x% of the
-- total size of Win). This Fixed_Size setting will be reset to False
-- as soon as the user has resized a pane with the mouse.
procedure Split
(Win : access Gtkada_Multi_Paned_Record;
Ref_Widget : access Gtk.Widget.Gtk_Widget_Record'Class;
New_Child : access Gtk.Widget.Gtk_Widget_Record'Class;
Orientation : Gtk.Enums.Gtk_Orientation;
Fixed_Size : Boolean := False;
Width, Height : Glib.Gint := -1;
After : Boolean := True);
-- Split the pane containing Ref_Widget, and add New_Child
-- in the new pane (on the right or at the bottom if After is True, on the
-- left or at the top if After is False).
procedure Set_Size
(Win : access Gtkada_Multi_Paned_Record;
Widget : access Gtk.Widget.Gtk_Widget_Record'Class;
Width, Height : Glib.Gint := -1;
Fixed_Size : Boolean := False);
-- Force a specific size for Widget
function Splitted_Area
(Win : access Gtkada_Multi_Paned_Record;
Ref_Widget : access Gtk.Widget.Gtk_Widget_Record'Class;
Orientation : Gtk.Enums.Gtk_Orientation;
After : Boolean := True) return Gtk.Widget.Gtk_Widget;
-- Return the widget in the splitted area next to Ref_Widget if any exist.
-- Orientation and After define which splitted area we are looking at.
-- null is returned if there are no such splitted area.
function Get_Pane
(Win : access Gtkada_Multi_Paned_Record;
Widget : access Gtk.Widget.Gtk_Widget_Record'Class) return Pane;
function Get_Pane (Current_Pane : Pane) return Pane;
-- Return the pane that contains the widget. See comment for Split below.
procedure Split
(Win : access Gtkada_Multi_Paned_Record;
Ref_Pane : Pane;
New_Child : access Gtk.Widget.Gtk_Widget_Record'Class;
Orientation : Gtk.Enums.Gtk_Orientation;
Fixed_Size : Boolean := False;
Width, Height : Glib.Gint := -1;
After : Boolean := True);
-- Split Ref_Pane to display New_Child to one of its sides.
-- See the comments for Root_Pane above.
-- The examples below assume that you are using one of the two split
-- procedures, either with a Ref_Pane or a Ref_Widget. In the former case,
-- the pane is obtained with a call to Get_Pane(Ref_Widget).
-- As you will see, the results are different (although they might appear
-- similar sometimes on this simple example.
-- In all these examples, we split either vertically or horizontally, and
-- add a new widget "4".
--
-- Given the following setup:
-- +---+---+
-- | 1 | |
-- +---+ 3 |
-- | 2 | |
-- +---+---+
--
-- Ref_Pane = Get_Pane ("1") Ref_Widget = "1"
-- Split vertically
-- After=True After=False After=True After=False
-- +---+---+ +---+---+ +---+---+ +---+---+
-- | 1 | 3 | | 4 | 3 | | 1 | 3 | | 4 | 3 |
-- +---+ | +---+ | +---+ | +---+ |
-- | 2 | | | 1 | | | 4 | | | 1 | |
-- +---+ | +---+ | +---+ | +---+ |
-- | 4 | | | 2 | | | 2 | | | 2 | |
-- +---+---+ +---+---+ +---+---+ +---+---+
--
-- Split horizontally
-- After=True After=False After=True After=False
-- +---+---+---+ +---+---+---+ +---+---+---+ +---+---+---+
-- | 1 | 4 | 3 | | 4 | 1 | 3 | | 1 | 4 | 3 | | 4 | 1 | 3 |
-- +---+ | | | +---+ | +---+---+ | +---+---+ |
-- | 2 | | | | | 2 | | | 2 | | | 2 | |
-- +---+---+---+ +---+---+---+ +-------+---+ +-------+---+
--
--
-- Ref_Pane = Get_Pane ("3") Ref_Widget = "3"
-- Split vertically
-- After=True After=False After=True After=False
-- +---+---+ +-------+ +---+---+ +---+---+
-- | 1 | 3 | | 4 | | 1 | 3 | | 1 | 4 |
-- +---+ | +---+---+ +---+---+ +---+---+
-- | 2 | | | 1 | 3 | | 2 | 4 | | 2 | 3 |
-- +---+---+ +---+ | +---+---+ +---+---+
-- | 4 | | 2 | |
-- +-------+ +---+---+
--
-- Split horizontally
-- After=True After=False After=True After=False
-- +---+---+---+ +---+---+---+ +---+---+---+ +---+---+---+
-- | 1 | 3 | 4 | | 4 | 1 | 3 | | 1 | 3 | 4 | | 1 | 4 | 3 |
-- +---+ | | | +---+ | +---+ | | +---+ | |
-- | 2 | | | | | 2 | | | 2 | | | | 2 | | |
-- +---+---+---+ +---+---+---+ +---+---+---+ +---+---+---+
procedure Freeze (Win : access Gtkada_Multi_Paned_Record);
-- Freeze the window, ie when a child is inserted, no computation of its
-- size is done, and will not generate immediate resizing.
-- You only need to call this procedure when restoring Win to a previously
-- state saved, and never if you are using the GtkAda.MDI which takes care
-- of it on its own.
procedure Thaw (Win : access Gtkada_Multi_Paned_Record);
-- Opposite of Freeze. You should call Size_Allocate on Win afterward to
-- force a recomputation of the size
---------------
-- Iterators --
---------------
type Child_Iterator is private;
function Start
(Win : access Gtkada_Multi_Paned_Record) return Child_Iterator;
-- Return an iterator to the first child of the window. This also returns
-- children which are not widget, but are used to organize the window into
-- horizontal and vertical panes
function At_End (Iter : Child_Iterator) return Boolean;
-- True if there is no more child to be returned
procedure Next (Iter : in out Child_Iterator);
-- Move to the next child of Iterator
function Get_Widget (Iter : Child_Iterator) return Gtk.Widget.Gtk_Widget;
-- Return the widget embedded in the current child. This returns null if
-- the current child is only used as a pane separator (horizontal or
-- vertical). You mustn't remove the widget from the paned widget, or the
-- iterator becomes invalid.
function Get_Orientation
(Iter : Child_Iterator) return Gtk.Enums.Gtk_Orientation;
-- Return the orientation of the current child. This is only relevant if
-- the child doesn't contain a widget (and therefore Get_Widget has
-- returned null).
function Get_Depth (Iter : Child_Iterator) return Natural;
-- Return the depth of the current child (0 means the child is at the
-- toplevel, 1 that this is a child directly underneath,...).
-- This can be used to detect when the Iter has finished traversing one
-- of the panes.
procedure Get_Size
(Iter : Child_Iterator;
Width, Height : out Gint;
Parent_Width, Parent_Height : out Gint;
Parent_Orientation : out Gtk.Enums.Gtk_Orientation);
-- Return the size of the current element (pane or widget), as well as the
-- parent's pane (the resizable area that contains notebooks or other
-- panes). The parent size is the total size devoted to its children,
-- omitting the size occupied by resize handles.
procedure Dump (Split : access Gtkada_Multi_Paned_Record'Class);
-- Dump the configuration of Split to stdout. This is only intended for
-- testing purposes. If you want to save and restore this configuration,
-- you should look at Gtkada.MDI instead, which contains all the
-- subprograms needed to handle desktops.
private
type Child_Description;
type Child_Description_Access is access Child_Description;
type Pane is new Child_Description_Access;
Root_Pane : constant Pane := null;
type Child_Iterator is record
Current : Child_Description_Access;
Depth : Natural := 0;
end record;
type Gtkada_Multi_Paned_Record is new Gtk.Fixed.Gtk_Fixed_Record with record
Frozen : Boolean := False;
Children : Child_Description_Access;
GC : Gdk.GC.Gdk_GC;
Initial_Pos : Gint;
Selected : Child_Description_Access;
Selected_Pos : Gtk.Widget.Gtk_Allocation;
Cursor_Double_H_Arrow : Gdk.Cursor.Gdk_Cursor;
Cursor_Double_V_Arrow : Gdk.Cursor.Gdk_Cursor;
Opaque_Resizing : Boolean := False;
end record;
end Gtkada.Multi_Paned;