------------------------------------------------------------------------------
-- GtkAda - Ada95 binding for Gtk+/Gnome --
-- --
-- Copyright (C) 2011-2014, AdaCore --
-- --
-- This library is free software; you can redistribute it and/or modify it --
-- under terms of the GNU General Public License as published by the Free --
-- Software Foundation; either version 3, 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 MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
------------------------------------------------------------------------------
-- <description>
-- Utility functions that mimic Gtk.Style drawing methods, but using Cairo
-- instead of Gdk. This allow smooth transition to Gtk3 that will get rid
-- of those Gdk drawing methods and only use Cairo.
-- </description>
-- <group>Configuration and Themes</group>
with Glib;
with Cairo;
with Pango.Layout;
with Gdk.Color;
with Gdk.Device;
with Gdk.Pixbuf;
with Gdk.RGBA;
with Gdk.Types;
with Gtk.Enums;
with Gtk.Style_Provider;
with Gtk.Widget;
package Gtkada.Style is
--------------------
-- Color handling --
--------------------
subtype Cairo_Color_Val is Glib.Gdouble range 0.0 .. 1.0;
-- In cairo, the color components are expressed as percents.
subtype Cairo_Color is Gdk.RGBA.Gdk_RGBA;
type HSV_Color is record
H, S, V, A : Glib.Gdouble;
end record;
-- Used when manipulating Cairo color. The HSV color space is useful when
-- wanting to shade a color (change it's value), (de)saturate it, or modify
-- its hue.
type HSLA_Color is record
Hue : Glib.Gdouble;
Saturation : Glib.Gdouble;
Lightness : Glib.Gdouble;
Alpha : Glib.Gdouble;
end record;
-- The Hue is the colour's position on the colour wheel, expressed in
-- degrees from 0° to 359°, representing the 360° of the wheel; 0°
-- being red, 180° being red's opposite colour cyan, and so on.
-- The mapping is: 0.0 => 0°
-- 1.0 => 360°
--
-- Saturation is the intensity of the colour, how dull or bright it is.
-- The lower the saturation, the duller (greyer) the colour looks. This is
-- expressed as a percentage, 100% being full saturation, the brightest,
-- and 0% being no saturation, grey.
--
-- Lightness is how light the colour is. Slightly different to saturation.
-- The more white in the colour the higher its Lightness value, the more
-- black, the lower its Lightness. So 100% Lightness turns the colour
-- white, 0% Lightness turns the colour black, and the "pure" colour
-- would be 50% Lightness.
function To_HSLA (Color : Gdk.RGBA.Gdk_RGBA) return HSLA_Color;
function To_RGBA (Color : HSLA_Color) return Gdk.RGBA.Gdk_RGBA;
function To_HSV (Color : Cairo_Color) return HSV_Color;
function To_Cairo (Color : Cairo_Color) return Gdk.RGBA.Gdk_RGBA;
function To_Cairo (HSV : HSV_Color) return Cairo_Color;
function To_Cairo (Color : Gdk.Color.Gdk_Color) return Cairo_Color;
-- Translations between one color definition to another
procedure Set_Source_Color
(Cr : Cairo.Cairo_Context; Color : Cairo_Color);
function To_Hex (Color : Gdk.RGBA.Gdk_RGBA) return String;
-- Return a hexadecimal approximate representation of the color, of the
-- form "#rrggbb". This loses the alpha chanel.
-- The output is suitable for use in a markup (see Gtk.Label.Set_Markup
-- for instance)
function Complementary
(Color : Gdk.RGBA.Gdk_RGBA) return Gdk.RGBA.Gdk_RGBA;
-- Return the complementary color
----------------------------------
-- Changing lightness of colors --
----------------------------------
subtype Percent is Glib.Gdouble range 0.0 .. 1.0;
function Shade
(Color : Gdk.Color.Gdk_Color;
Value : Percent) return Cairo_Color;
function Shade
(Color : Cairo_Color;
Value : Percent) return Cairo_Color;
-- Modifies the lightning of the color by the specified value.
--
-- Value is a modifier: 0.0 means the color is unchanged, 0.1 means the
-- color is modified by 10%, and so on.
function Lighten
(Color : Gdk.RGBA.Gdk_RGBA;
Amount : Percent) return Gdk.RGBA.Gdk_RGBA;
-- Return a lighter version of the color
--
-- Amount is a modifier: 0.0 means the color is unchanged, 0.1 means the
-- color is modified by 10%, and so on.
function Shade_Or_Lighten
(Color : Gdk.RGBA.Gdk_RGBA;
Amount : Percent := 0.4) return Gdk.RGBA.Gdk_RGBA;
-- Return a lighter or darker version of Color, depending on whether color
-- is rather dark or rather light.
--
-- Amount is a modifier: 0.0 means the color is unchanged, 0.1 means the
-- color is modified by 10%, and so on.
-----------------------------
-- Extra path manipulation --
-----------------------------
procedure Rounded_Rectangle
(Cr : Cairo.Cairo_Context;
X, Y, W, H : Glib.Gdouble;
Radius : Glib.Gdouble);
-- Draws a rounded rectangle at coordinate X, Y with W and H size.
-- If Radius > 0, then the corner will be rounded.
-------------------------
-- Drawing subprograms --
-------------------------
procedure Draw_Shadow
(Cr : Cairo.Cairo_Context;
Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class;
Shadow_Type : Gtk.Enums.Gtk_Shadow_Type;
X, Y, Width, Height : Glib.Gint;
Corner_Radius : Glib.Gdouble := 0.0);
-- Draws a Frame of size Width x Height at position (X, Y) and (X2, Y2)
-- using the specified color.
-- Corner_Radius allows you to draw a rounded frame if set to a value > 0.
--
-- Additional drawing styles can be specified by using Cairo.Set_Line_XXXX
-- on the Cairo_Context before calling this procedure.
procedure Draw_Rectangle
(Cr : Cairo.Cairo_Context;
Color : Cairo_Color;
Filled : Boolean;
X, Y, Width, Height : Glib.Gint;
Corner_Radius : Glib.Gdouble := 0.0);
procedure Draw_Rectangle
(Cr : Cairo.Cairo_Context;
Color : Gdk.Color.Gdk_Color;
Filled : Boolean;
X, Y, Width, Height : Glib.Gint;
Corner_Radius : Glib.Gdouble := 0.0);
-- Draws a rectangle of size Width x Height at position (X, Y) and (X2, Y2)
-- using the specified color.
-- Corner_Radius allows you to draw a rounded rectangle if set to a
-- value > 0.0
--
-- Additional drawing styles can be specified by using Cairo.Set_Line_XXXX
-- on the Cairo_Context before calling this procedure.
procedure Draw_Line
(Cr : Cairo.Cairo_Context;
Color : Cairo_Color;
X1, Y1, X2, Y2 : Glib.Gint);
procedure Draw_Line
(Cr : Cairo.Cairo_Context;
Color : Gdk.Color.Gdk_Color;
X1, Y1, X2, Y2 : Glib.Gint);
-- Draws a line between (X1, Y1) and (X2, Y2) using the specified color.
--
-- Additional drawing styles can be specified by using Cairo.Set_Line_XXXX
-- on the Cairo_Context before calling this procedure.
procedure Draw_Layout
(Cr : Cairo.Cairo_Context;
Color : Cairo_Color;
X, Y : Glib.Gint;
Layout : Pango.Layout.Pango_Layout);
procedure Draw_Layout
(Cr : Cairo.Cairo_Context;
Color : Gdk.Color.Gdk_Color;
X, Y : Glib.Gint;
Layout : Pango.Layout.Pango_Layout);
-- Draws the Pango layout at position (X, Y) using Color.
procedure Draw_Pixbuf
(Cr : Cairo.Cairo_Context;
Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf;
X, Y : Glib.Gint);
-- Draws a pixbuf at coordinate X, Y
--
-- Note that Gdk_Pixmap or Gdk_Bitmap are not supported, as those
-- are server-side images, so depend on a surface attached to a screen.
-- As a result, those would not be drawn on a non-screen surface (such as
-- an internal Image_Surface).
---------
-- CSS --
---------
procedure Load_Css_File
(Path : String;
Error : access procedure (Str : String) := null;
Priority : Gtk.Style_Provider.Priority);
procedure Load_Css_String
(Data : String;
Error : access procedure (Str : String) := null;
Priority : Gtk.Style_Provider.Priority);
-- Load CSS file and register it as a default CSS provider for the whole
-- application.
-- In case of error, the procedure Error is called if defined.
------------------------
-- Cairo manipulation --
------------------------
function Snapshot
(Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class)
return Cairo.Cairo_Surface;
-- Create a snapshot of the widget.
-- This allocates a new surface and draws the widget on it. The surface
-- needs to be destroyed when you are done with it using Surface_Destroy.
-- The snapshot can be drawn on another surface using
-- Set_Source_Surface (Cr, the_snapshot, 0.0, 0.0);
-- Set_Operator (Cr, Cairo_Operator_Source);
-- Rectangle (Cr, ....);
-- Cairo.Fill (Cr);
-- The 0.0 values might need to be adjusted if your widget does not have
-- its own window. In this case, you should use:
-- Get_Allocation (Widget, Alloc);
-- -- and replace 0.0 with Gdouble (Alloc.X)
procedure Draw_Overlay
(Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class;
Overlay : in out Cairo.Cairo_Surface;
Do_Draw : not null access procedure
(Context : Cairo.Cairo_Context;
Draw : Boolean));
-- Create an overlay on top of widget on which you can draw.
-- This overlay is created if it doesn't exist (so Overlay must be
-- initialied to Null_Surface initially). It is displayed on top of the
-- toplevel window that contains Widget, and will be fully visible until
-- some of the children of that toplevel window get a "draw" event. At that
-- point, the children will partially override the overlay. This is not a
-- problem in practice if the overlay is displayed while performing
-- operations like a drag-and-drop.
-- Do_Draw is the callback used to do the actual drawing or erasing of the
-- overlay (depending on whether Draw is True or False). The context passed
-- in argument has been properly translated and clipped so that (0, 0) are
-- the coordinates of the top-left corner of widget.
--
-- When Draw is False, the procedure should display a filled rectangle. The
-- context has already been set up so that filling will in fact redraw what
-- was previously hidden. This is more efficient that having Draw_Overlay
-- systematically fill the whole area.
procedure Delete_Overlay
(Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class;
Overlay : in out Cairo.Cairo_Surface);
-- Delete the overlay created by Draw_Overlay, and force a refresh of the
-- toplevel window.
procedure Get_Offset
(Window : not null access Gtk.Widget.Gtk_Widget_Record'Class;
Parent : not null access Gtk.Widget.Gtk_Widget_Record'Class;
X, Y : out Glib.Gint);
-- Get the position of Window within parent's window (not that this is not
-- necessarily the same as the position within Parent if the latter does
-- not have a window).
-------------
-- Devices --
-------------
function Get_First_Device
(Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class;
Source : Gdk.Types.Gdk_Input_Source) return Gdk.Device.Gdk_Device;
-- Return the first device that matches the given source.
-- This can be used to simulate keyboard events (using Source_Keyboard)
-- or mouse events (Source_Mouse) for instance.
-- The returned value (if not null) must be Ref-ed before being assigned
-- to an event for instance.
end Gtkada.Style;