1. ------------------------------------------------------------------------------ 
  2. --                  GtkAda - Ada95 binding for Gtk+/Gnome                   -- 
  3. --                                                                          -- 
  4. --                     Copyright (C) 2011-2014, AdaCore                     -- 
  5. --                                                                          -- 
  6. -- This library is free software;  you can redistribute it and/or modify it -- 
  7. -- under terms of the  GNU General Public License  as published by the Free -- 
  8. -- Software  Foundation;  either version 3,  or (at your  option) any later -- 
  9. -- version. This library is distributed in the hope that it will be useful, -- 
  10. -- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- -- 
  11. -- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            -- 
  12. --                                                                          -- 
  13. -- As a special exception under Section 7 of GPL version 3, you are granted -- 
  14. -- additional permissions described in the GCC Runtime Library Exception,   -- 
  15. -- version 3.1, as published by the Free Software Foundation.               -- 
  16. --                                                                          -- 
  17. -- You should have received a copy of the GNU General Public License and    -- 
  18. -- a copy of the GCC Runtime Library Exception along with this program;     -- 
  19. -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    -- 
  20. -- <http://www.gnu.org/licenses/>.                                          -- 
  21. --                                                                          -- 
  22. ------------------------------------------------------------------------------ 
  23.  
  24. --  <description> 
  25. --  Utility functions that mimic Gtk.Style drawing methods, but using Cairo 
  26. --  instead of Gdk. This allow smooth transition to Gtk3 that will get rid 
  27. --  of those Gdk drawing methods and only use Cairo. 
  28. --  </description> 
  29. --  <group>Configuration and Themes</group> 
  30.  
  31. with Glib; 
  32. with Cairo; 
  33. with Pango.Layout; 
  34. with Gdk.Color; 
  35. with Gdk.Device; 
  36. with Gdk.Pixbuf; 
  37. with Gdk.RGBA; 
  38. with Gdk.Types; 
  39. with Gtk.Enums; 
  40. with Gtk.Style_Provider; 
  41. with Gtk.Widget; 
  42.  
  43. package Gtkada.Style is 
  44.  
  45.    -------------------- 
  46.    -- Color handling -- 
  47.    -------------------- 
  48.  
  49.    subtype Cairo_Color_Val is Glib.Gdouble range 0.0 .. 1.0; 
  50.    --  In cairo, the color components are expressed as percents. 
  51.  
  52.    subtype Cairo_Color is Gdk.RGBA.Gdk_RGBA; 
  53.  
  54.    type HSV_Color is record 
  55.       H, S, V, A : Glib.Gdouble; 
  56.    end record; 
  57.    --  Used when manipulating Cairo color. The HSV color space is useful when 
  58.    --  wanting to shade a color (change it's value), (de)saturate it, or modify 
  59.    --  its hue. 
  60.  
  61.    type HSLA_Color is record 
  62.       Hue        : Glib.Gdouble; 
  63.       Saturation : Glib.Gdouble; 
  64.       Lightness  : Glib.Gdouble; 
  65.       Alpha      : Glib.Gdouble; 
  66.    end record; 
  67.    --  The Hue is the colour's position on the colour wheel, expressed in 
  68.    --  degrees from 0° to 359°, representing the 360° of the wheel; 0° 
  69.    --  being red, 180° being red's opposite colour cyan, and so on. 
  70.    --  The mapping is:    0.0 => 0° 
  71.    --                     1.0 => 360° 
  72.    -- 
  73.    --  Saturation is the intensity of the colour, how dull or bright it is. 
  74.    --  The lower the saturation, the duller (greyer) the colour looks. This is 
  75.    --  expressed as a percentage, 100% being full saturation, the brightest, 
  76.    --  and 0% being no saturation, grey. 
  77.    -- 
  78.    --  Lightness is how light the colour is. Slightly different to saturation. 
  79.    --  The more white in the colour the higher its Lightness value, the more 
  80.    --  black, the lower its Lightness. So 100% Lightness turns the colour 
  81.    --  white, 0% Lightness turns the colour black, and the "pure" colour 
  82.    --  would be 50% Lightness. 
  83.  
  84.    function To_HSLA (Color : Gdk.RGBA.Gdk_RGBA) return HSLA_Color; 
  85.    function To_RGBA (Color : HSLA_Color) return Gdk.RGBA.Gdk_RGBA; 
  86.    function To_HSV (Color   : Cairo_Color) return HSV_Color; 
  87.    function To_Cairo (Color : Cairo_Color) return Gdk.RGBA.Gdk_RGBA; 
  88.    function To_Cairo (HSV : HSV_Color) return Cairo_Color; 
  89.    function To_Cairo (Color : Gdk.Color.Gdk_Color) return Cairo_Color; 
  90.    --  Translations between one color definition to another 
  91.  
  92.    procedure Set_Source_Color 
  93.      (Cr : Cairo.Cairo_Context; Color : Cairo_Color); 
  94.  
  95.    function To_Hex (Color : Gdk.RGBA.Gdk_RGBA) return String; 
  96.    --  Return a hexadecimal approximate representation of the color, of the 
  97.    --  form "#rrggbb". This loses the alpha chanel. 
  98.    --  The output is suitable for use in a markup (see Gtk.Label.Set_Markup 
  99.    --  for instance) 
  100.  
  101.    function Complementary 
  102.      (Color : Gdk.RGBA.Gdk_RGBA) return Gdk.RGBA.Gdk_RGBA; 
  103.    --  Return the complementary color 
  104.  
  105.    ---------------------------------- 
  106.    -- Changing lightness of colors -- 
  107.    ---------------------------------- 
  108.  
  109.    subtype Percent is Glib.Gdouble range 0.0 .. 1.0; 
  110.  
  111.    function Shade 
  112.      (Color : Gdk.Color.Gdk_Color; 
  113.       Value : Percent) return Cairo_Color; 
  114.    function Shade 
  115.      (Color : Cairo_Color; 
  116.       Value : Percent) return Cairo_Color; 
  117.    --  Modifies the lightning of the color by the specified value. 
  118.    -- 
  119.    --  Value is a modifier: 0.0 means the color is unchanged, 0.1 means the 
  120.    --  color is modified by 10%, and so on. 
  121.  
  122.    function Lighten 
  123.      (Color  : Gdk.RGBA.Gdk_RGBA; 
  124.       Amount : Percent) return Gdk.RGBA.Gdk_RGBA; 
  125.    --  Return a lighter version of the color 
  126.    -- 
  127.    --  Amount is a modifier: 0.0 means the color is unchanged, 0.1 means the 
  128.    --  color is modified by 10%, and so on. 
  129.  
  130.    function Shade_Or_Lighten 
  131.      (Color  : Gdk.RGBA.Gdk_RGBA; 
  132.       Amount : Percent := 0.4) return Gdk.RGBA.Gdk_RGBA; 
  133.    --  Return a lighter or darker version of Color, depending on whether color 
  134.    --  is rather dark or rather light. 
  135.    -- 
  136.    --  Amount is a modifier: 0.0 means the color is unchanged, 0.1 means the 
  137.    --  color is modified by 10%, and so on. 
  138.  
  139.    ----------------------------- 
  140.    -- Extra path manipulation -- 
  141.    ----------------------------- 
  142.  
  143.    procedure Rounded_Rectangle 
  144.      (Cr         : Cairo.Cairo_Context; 
  145.       X, Y, W, H : Glib.Gdouble; 
  146.       Radius     : Glib.Gdouble); 
  147.    --  Draws a rounded rectangle at coordinate X, Y with W and H size. 
  148.    --  If Radius > 0, then the corner will be rounded. 
  149.  
  150.    ------------------------- 
  151.    -- Drawing subprograms -- 
  152.    ------------------------- 
  153.  
  154.    procedure Draw_Shadow 
  155.      (Cr                  : Cairo.Cairo_Context; 
  156.       Widget              : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  157.       Shadow_Type         : Gtk.Enums.Gtk_Shadow_Type; 
  158.       X, Y, Width, Height : Glib.Gint; 
  159.       Corner_Radius       : Glib.Gdouble := 0.0); 
  160.    --  Draws a Frame of size Width x Height at position (X, Y) and (X2, Y2) 
  161.    --  using the specified color. 
  162.    --  Corner_Radius allows you to draw a rounded frame if set to a value > 0. 
  163.    -- 
  164.    --  Additional drawing styles can be specified by using Cairo.Set_Line_XXXX 
  165.    --  on the Cairo_Context before calling this procedure. 
  166.  
  167.    procedure Draw_Rectangle 
  168.      (Cr                  : Cairo.Cairo_Context; 
  169.       Color               : Cairo_Color; 
  170.       Filled              : Boolean; 
  171.       X, Y, Width, Height : Glib.Gint; 
  172.       Corner_Radius       : Glib.Gdouble := 0.0); 
  173.    procedure Draw_Rectangle 
  174.      (Cr                  : Cairo.Cairo_Context; 
  175.       Color               : Gdk.Color.Gdk_Color; 
  176.       Filled              : Boolean; 
  177.       X, Y, Width, Height : Glib.Gint; 
  178.       Corner_Radius       : Glib.Gdouble := 0.0); 
  179.    --  Draws a rectangle of size Width x Height at position (X, Y) and (X2, Y2) 
  180.    --  using the specified color. 
  181.    --  Corner_Radius allows you to draw a rounded rectangle if set to a 
  182.    --  value > 0.0 
  183.    -- 
  184.    --  Additional drawing styles can be specified by using Cairo.Set_Line_XXXX 
  185.    --  on the Cairo_Context before calling this procedure. 
  186.  
  187.    procedure Draw_Line 
  188.      (Cr             : Cairo.Cairo_Context; 
  189.       Color          : Cairo_Color; 
  190.       X1, Y1, X2, Y2 : Glib.Gint); 
  191.    procedure Draw_Line 
  192.      (Cr             : Cairo.Cairo_Context; 
  193.       Color          : Gdk.Color.Gdk_Color; 
  194.       X1, Y1, X2, Y2 : Glib.Gint); 
  195.    --  Draws a line between (X1, Y1) and (X2, Y2) using the specified color. 
  196.    -- 
  197.    --  Additional drawing styles can be specified by using Cairo.Set_Line_XXXX 
  198.    --  on the Cairo_Context before calling this procedure. 
  199.  
  200.    procedure Draw_Layout 
  201.      (Cr     : Cairo.Cairo_Context; 
  202.       Color  : Cairo_Color; 
  203.       X, Y   : Glib.Gint; 
  204.       Layout : Pango.Layout.Pango_Layout); 
  205.    procedure Draw_Layout 
  206.      (Cr     : Cairo.Cairo_Context; 
  207.       Color  : Gdk.Color.Gdk_Color; 
  208.       X, Y   : Glib.Gint; 
  209.       Layout : Pango.Layout.Pango_Layout); 
  210.    --  Draws the Pango layout at position (X, Y) using Color. 
  211.  
  212.    procedure Draw_Pixbuf 
  213.      (Cr     : Cairo.Cairo_Context; 
  214.       Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf; 
  215.       X, Y   : Glib.Gint); 
  216.    --  Draws a pixbuf at coordinate X, Y 
  217.    -- 
  218.    --  Note that Gdk_Pixmap or Gdk_Bitmap are not supported, as those 
  219.    --  are server-side images, so depend on a surface attached to a screen. 
  220.    --  As a result, those would not be drawn on a non-screen surface (such as 
  221.    --  an internal Image_Surface). 
  222.  
  223.    --------- 
  224.    -- CSS -- 
  225.    --------- 
  226.  
  227.    procedure Load_Css_File 
  228.      (Path     : String; 
  229.       Error    : access procedure (Str : String) := null; 
  230.       Priority : Gtk.Style_Provider.Priority); 
  231.    procedure Load_Css_String 
  232.      (Data     : String; 
  233.       Error    : access procedure (Str : String) := null; 
  234.       Priority : Gtk.Style_Provider.Priority); 
  235.    --  Load CSS file and register it as a default CSS provider for the whole 
  236.    --  application. 
  237.    --  In case of error, the procedure Error is called if defined. 
  238.  
  239.    ------------------------ 
  240.    -- Cairo manipulation -- 
  241.    ------------------------ 
  242.  
  243.    function Snapshot 
  244.      (Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class) 
  245.       return Cairo.Cairo_Surface; 
  246.    --  Create a snapshot of the widget. 
  247.    --  This allocates a new surface and draws the widget on it. The surface 
  248.    --  needs to be destroyed when you are done with it using Surface_Destroy. 
  249.    --  The snapshot can be drawn on another surface using 
  250.    --      Set_Source_Surface (Cr, the_snapshot, 0.0, 0.0); 
  251.    --      Set_Operator (Cr, Cairo_Operator_Source); 
  252.    --      Rectangle (Cr, ....); 
  253.    --      Cairo.Fill (Cr); 
  254.    --  The 0.0 values might need to be adjusted if your widget does not have 
  255.    --  its own window. In this case, you should use: 
  256.    --      Get_Allocation (Widget, Alloc); 
  257.    --      --  and replace 0.0 with Gdouble (Alloc.X) 
  258.  
  259.    procedure Draw_Overlay 
  260.      (Widget  : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  261.       Overlay : in out Cairo.Cairo_Surface; 
  262.       Do_Draw : not null access procedure 
  263.         (Context : Cairo.Cairo_Context; 
  264.          Draw    : Boolean)); 
  265.    --  Create an overlay on top of widget on which you can draw. 
  266.    --  This overlay is created if it doesn't exist (so Overlay must be 
  267.    --  initialied to Null_Surface initially). It is displayed on top of the 
  268.    --  toplevel window that contains Widget, and will be fully visible until 
  269.    --  some of the children of that toplevel window get a "draw" event. At that 
  270.    --  point, the children will partially override the overlay. This is not a 
  271.    --  problem in practice if the overlay is displayed while performing 
  272.    --  operations like a drag-and-drop. 
  273.    --  Do_Draw is the callback used to do the actual drawing or erasing of the 
  274.    --  overlay (depending on whether Draw is True or False). The context passed 
  275.    --  in argument has been properly translated and clipped so that (0, 0) are 
  276.    --  the coordinates of the top-left corner of widget. 
  277.    -- 
  278.    --  When Draw is False, the procedure should display a filled rectangle. The 
  279.    --  context has already been set up so that filling will in fact redraw what 
  280.    --  was previously hidden. This is more efficient that having Draw_Overlay 
  281.    --  systematically fill the whole area. 
  282.  
  283.    procedure Delete_Overlay 
  284.      (Widget  : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  285.       Overlay : in out Cairo.Cairo_Surface); 
  286.    --  Delete the overlay created by Draw_Overlay, and force a refresh of the 
  287.    --  toplevel window. 
  288.  
  289.    procedure Get_Offset 
  290.      (Window : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  291.       Parent : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  292.       X, Y   : out Glib.Gint); 
  293.    --  Get the position of Window within parent's window (not that this is not 
  294.    --  necessarily the same as the position within Parent if the latter does 
  295.    --  not have a window). 
  296.  
  297.    ------------- 
  298.    -- Devices -- 
  299.    ------------- 
  300.  
  301.    function Get_First_Device 
  302.      (Widget : not null access Gtk.Widget.Gtk_Widget_Record'Class; 
  303.       Source : Gdk.Types.Gdk_Input_Source) return Gdk.Device.Gdk_Device; 
  304.    --  Return the first device that matches the given source. 
  305.    --  This can be used to simulate keyboard events (using Source_Keyboard) 
  306.    --  or mouse events (Source_Mouse) for instance. 
  307.    --  The returned value (if not null) must be Ref-ed before being assigned 
  308.    --  to an event for instance. 
  309.  
  310. end Gtkada.Style;