Advertisement
Guest User

Untitled

a guest
May 28th, 2017
547
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 30.06 KB | None | 0 0
  1. /*
  2.  *  Copyright (C) 2009 Michal Hruby <michal.mhr@gmail.com>
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
  17.  *
  18.  *  Author : Alberto Aldegheri <albyrock87+dev@gmail.com>
  19.  *  Thanks to: Matt <sharkbaitbobby@gmail.com>
  20.  *             for the code section to analyze separators
  21.  *
  22.  */
  23.  
  24. #include "config.h"
  25.  
  26. #include <gdk/gdk.h>
  27. #include <libawn/awn-cairo-utils.h>
  28. #include <math.h>
  29.  
  30. #include "awn-applet-manager.h"
  31. #include "awn-background-lucido.h"
  32. #include "awn-separator.h"
  33.  
  34. G_DEFINE_TYPE (AwnBackgroundLucido, awn_background_lucido, AWN_TYPE_BACKGROUND)
  35.  
  36. #define AWN_BACKGROUND_LUCIDO_GET_PRIVATE(obj) ( \
  37.     G_TYPE_INSTANCE_GET_PRIVATE (obj, AWN_TYPE_BACKGROUND_LUCIDO, \
  38.                                  AwnBackgroundLucidoPrivate))
  39.  
  40. struct _AwnBackgroundLucidoPrivate
  41. {
  42.   /* stores the last position of 'special applets' */
  43.   GArray *pos;
  44.   gfloat expw;
  45.   gint expn;
  46.   gint expp;
  47.   gfloat last_pad;
  48.   guint tid;
  49.   gboolean last_exp;
  50.   gboolean needs_animation;
  51. };
  52.  
  53. #define ANIM_TIMEOUT 50
  54.  
  55. #define TRANSFORM_RADIUS(x) sqrt(x/50.)*50.
  56.  
  57. #define IS_SPECIAL(x) AWN_IS_SEPARATOR(x)
  58.  
  59. static gboolean
  60. awn_background_lucido_redraw (AwnBackgroundLucido *bg)
  61. {
  62.   g_return_val_if_fail (AWN_IS_BACKGROUND_LUCIDO (bg), FALSE);
  63.  
  64.   if (AWN_BACKGROUND_LUCIDO_GET_PRIVATE (bg)->needs_animation)
  65.   {
  66.     fprintf (stderr, "drw\n");
  67.     awn_background_invalidate (AWN_BACKGROUND (bg));
  68.     gtk_widget_queue_draw (GTK_WIDGET (AWN_BACKGROUND (bg)->panel));
  69.     return TRUE;
  70.   }
  71.   else
  72.   {
  73.     AWN_BACKGROUND_LUCIDO_GET_PRIVATE (bg)->tid = 0;
  74.     return FALSE;
  75.   }
  76. }
  77.  
  78. static void awn_background_lucido_draw (AwnBackground  *bg,
  79.                                         cairo_t        *cr,
  80.                                         GtkPositionType  position,
  81.                                         GdkRectangle   *area);
  82.  
  83. static void awn_background_lucido_get_shape_mask (AwnBackground  *bg,
  84.                                                   cairo_t        *cr,
  85.                                                   GtkPositionType  position,
  86.                                                   GdkRectangle   *area);
  87.  
  88. static void awn_background_lucido_padding_request (AwnBackground *bg,
  89.                                                    GtkPositionType position,
  90.                                                    guint *padding_top,
  91.                                                    guint *padding_bottom,
  92.                                                    guint *padding_left,
  93.                                                    guint *padding_right);
  94.                                                    
  95. static gboolean
  96. awn_background_lucido_get_needs_redraw (AwnBackground *bg,
  97.                                         GtkPositionType position,
  98.                                         GdkRectangle *area);
  99.  
  100. static void
  101. _set_special_widget_width_and_transparent (AwnBackground *bg,
  102.                                            gint          width,
  103.                                            gboolean      transp,
  104.                                            gboolean      dispose);
  105.                                        
  106. static void
  107. awn_background_lucido_corner_radius_changed (AwnBackground *bg)
  108. {
  109.   gboolean expand = FALSE;
  110.   g_object_get (bg->panel, "expand", &expand, NULL);
  111.  
  112.   if (!expand)
  113.   {    
  114.     awn_background_emit_padding_changed (bg);
  115.   }
  116. }
  117.  
  118. static void
  119. awn_background_lucido_expand_changed (AwnBackground *bg)
  120. {
  121.   awn_background_emit_padding_changed (bg);
  122. }
  123.  
  124. static void
  125. awn_background_lucido_align_changed (AwnBackground *bg)
  126. {
  127.   awn_background_emit_padding_changed (bg);
  128. }
  129.  
  130. static void
  131. awn_background_lucido_constructed (GObject *object)
  132. {
  133.   G_OBJECT_CLASS (awn_background_lucido_parent_class)->constructed (object);
  134.  
  135.   AwnBackground *bg = AWN_BACKGROUND (object);
  136.   gpointer monitor = NULL;
  137.  
  138.   g_signal_connect_swapped (bg, "notify::corner-radius",
  139.                             G_CALLBACK (awn_background_lucido_corner_radius_changed),
  140.                             object);
  141.  
  142.   g_return_if_fail (bg->panel);
  143.  
  144.   g_signal_connect_swapped (bg->panel, "notify::expand",
  145.                             G_CALLBACK (awn_background_lucido_expand_changed),
  146.                             object);
  147.  
  148.   g_object_get (bg->panel, "monitor", &monitor, NULL);
  149.  
  150.   g_return_if_fail (monitor);
  151.  
  152.   g_signal_connect_swapped (monitor, "notify::monitor-align",
  153.                             G_CALLBACK (awn_background_lucido_align_changed),
  154.                             object);
  155. }
  156.  
  157. static gint
  158. _get_applet_manager_size (AwnBackground* bg, GtkPositionType position)
  159. {
  160.   AwnAppletManager *manager = NULL;
  161.   g_object_get (bg->panel, "applet-manager", &manager, NULL);
  162.  
  163.   switch (position)
  164.   {
  165.     case GTK_POS_BOTTOM:
  166.     case GTK_POS_TOP:
  167.       return GTK_WIDGET (manager)->allocation.width;
  168.       break;
  169.     default:
  170.       return GTK_WIDGET (manager)->allocation.height;
  171.       break;
  172.   }
  173. }
  174.  
  175. static GList*
  176. _get_applet_widgets (AwnBackground* bg)
  177. {
  178.   AwnAppletManager *manager = NULL;
  179.   g_object_get (bg->panel, "applet-manager", &manager, NULL);
  180.  
  181.   return gtk_container_get_children (GTK_CONTAINER (manager));
  182. }
  183.  
  184. static void
  185. _init_positions (AwnBackground*  bg,
  186.                  GtkPositionType position,
  187.                  gfloat          w,
  188.                  gboolean        expanded,
  189.                  gfloat          align)
  190. {
  191.   AwnBackgroundLucidoPrivate *priv;
  192.   priv = AWN_BACKGROUND_LUCIDO_GET_PRIVATE (AWN_BACKGROUND_LUCIDO (bg));
  193.  
  194.   if (priv->pos != NULL)
  195.     g_array_free (priv->pos, TRUE);
  196.  
  197.   priv->pos = g_array_new (FALSE, TRUE, sizeof (gfloat));
  198.  
  199.   GList* widgets = _get_applet_widgets (bg);
  200.   GList* i = widgets;
  201.   GtkWidget* widget = NULL;
  202.    
  203.   gfloat target_pad_left = 0.;
  204.    
  205.   if (expanded)
  206.     target_pad_left = (w - _get_applet_manager_size (bg, position)) * align;
  207.   else if (align > 0.)
  208.     target_pad_left = TRANSFORM_RADIUS (bg->corner_radius);
  209.  
  210.   //gint pos = 0;
  211.   for (; i; i = i->next)
  212.   {
  213.     widget = GTK_WIDGET (i->data);
  214.     if (IS_SPECIAL (widget))
  215.       switch (position)
  216.       {
  217.         case GTK_POS_BOTTOM:
  218.         case GTK_POS_TOP:
  219.           w = target_pad_left + widget->allocation.x;
  220.           break;
  221.         default:
  222.           w = target_pad_left + widget->allocation.y;
  223.           break;
  224.       }
  225.       //pos = floor (w);
  226.       g_array_append_val (priv->pos, w);
  227.   }
  228.  
  229.   g_list_free (widgets);
  230. }
  231.  
  232. static void
  233. _destroy_positions (AwnBackground *bg)
  234. {
  235.   AwnBackgroundLucidoPrivate *priv;
  236.   priv = AWN_BACKGROUND_LUCIDO_GET_PRIVATE (AWN_BACKGROUND_LUCIDO (bg));
  237.  
  238.   if (priv->pos != NULL)
  239.     g_array_free (priv->pos, TRUE);
  240.   priv->pos = NULL;
  241. }
  242.  
  243. static void
  244. awn_background_lucido_dispose (GObject *object)
  245. {
  246.   _set_special_widget_width_and_transparent
  247.                           (AWN_BACKGROUND (object), 10, FALSE, TRUE);
  248.   gpointer monitor = NULL;
  249.   if (AWN_BACKGROUND (object)->panel)
  250.   {
  251.     g_object_get (AWN_BACKGROUND (object)->panel, "monitor", &monitor, NULL);
  252.  
  253.     if (monitor)
  254.     {
  255.       g_signal_handlers_disconnect_by_func (monitor,
  256.           G_CALLBACK (awn_background_lucido_align_changed), object);
  257.     }
  258.   }
  259.  
  260.   g_signal_handlers_disconnect_by_func (AWN_BACKGROUND (object)->panel,
  261.         G_CALLBACK (awn_background_lucido_expand_changed), object);
  262.  
  263.   g_signal_handlers_disconnect_by_func (AWN_BACKGROUND (object),
  264.         G_CALLBACK (awn_background_lucido_corner_radius_changed), object);
  265.  
  266.  
  267.  
  268.   G_OBJECT_CLASS (awn_background_lucido_parent_class)->dispose (object);
  269. }
  270.  
  271. static void
  272. awn_background_lucido_class_init (AwnBackgroundLucidoClass *klass)
  273. {
  274.   AwnBackgroundClass *bg_class = AWN_BACKGROUND_CLASS (klass);
  275.  
  276.   GObjectClass *obj_class = G_OBJECT_CLASS (klass);
  277.   obj_class->constructed  = awn_background_lucido_constructed;
  278.   obj_class->dispose = awn_background_lucido_dispose;
  279.  
  280.   bg_class->draw = awn_background_lucido_draw;
  281.   bg_class->padding_request = awn_background_lucido_padding_request;
  282.   bg_class->get_shape_mask = awn_background_lucido_get_shape_mask;
  283.   bg_class->get_input_shape_mask = awn_background_lucido_get_shape_mask;
  284.   bg_class->get_needs_redraw = awn_background_lucido_get_needs_redraw;
  285.  
  286.   g_type_class_add_private (obj_class, sizeof (AwnBackgroundLucidoPrivate));
  287. }
  288.  
  289. static void
  290. awn_background_lucido_init (AwnBackgroundLucido *bg)
  291. {
  292.   AwnBackgroundLucidoPrivate *priv;
  293.   priv = AWN_BACKGROUND_LUCIDO_GET_PRIVATE (bg);
  294.   priv->pos = NULL;
  295.   priv->last_pad = 0.;
  296.   priv->needs_animation = TRUE;
  297.   priv->tid = g_timeout_add (ANIM_TIMEOUT, (GSourceFunc)awn_background_lucido_redraw, AWN_BACKGROUND (bg));
  298. }
  299.  
  300. AwnBackground *
  301. awn_background_lucido_new (DesktopAgnosticConfigClient *client,
  302.                            AwnPanel *panel)
  303. {
  304.   AwnBackground *bg;
  305.  
  306.   bg = g_object_new (AWN_TYPE_BACKGROUND_LUCIDO,
  307.                      "client", client,
  308.                      "panel", panel,
  309.                      NULL);
  310.   return bg;
  311. }
  312.  
  313. /*
  314.  * Drawing functions
  315.  */
  316. static void
  317. _line_from_to ( cairo_t *cr,
  318.                 gfloat *xs,
  319.                 gfloat *ys,
  320.                 gfloat xf,
  321.                 gfloat yf)
  322. {
  323.   if ( *xs==xf || *ys==yf ) /* Vertical/Horizontal line */
  324.   {
  325.     cairo_line_to (cr, xf, yf);
  326.   }
  327.   else
  328.   { /* Oblique */
  329.     gfloat xm = ( *xs + xf ) / 2.0;
  330.     cairo_curve_to (cr, xm, *ys, xm, yf, xf, yf);
  331.   }
  332.   *xs = xf;
  333.   *ys = yf;
  334. }
  335.  
  336. /**
  337.  * _create_path_lucido:
  338.  * @bg: The background pointer
  339.  * @position: The position of the bar
  340.  * @cairo_t: The cairo context
  341.  * @y: The top left coordinate of the "bar rect" - default = 0
  342.  * @w: The width of the bar
  343.  * @h: The height of the bar
  344.  * @d: The width of each curve in the path
  345.  * @dc: The width of the external curves in non-expanded&auto mode
  346.  * @internal: If Zero, creates the path for the stripe
  347.  * @expanded: If Zero, the bar is not expanded
  348.  * @align: the monitor align
  349.  *
  350.  * This function creates paths on which the bar will be drawn.
  351.  * In atuo-stripe, it searchs for separators applet, each separator
  352.  * equals to one curve.
  353.  * If the first widget is an separator, start from bottom-left,
  354.  * otherwise start from top-left
  355.  */
  356.  
  357. static void
  358. _create_path_lucido ( AwnBackground*  bg,
  359.                       GtkPositionType position,
  360.                       cairo_t*        cr,
  361.                       gfloat          x,
  362.                       gfloat          y,
  363.                       gfloat          w,
  364.                       gfloat          h,
  365.                       gfloat          d,
  366.                       gfloat          dc,
  367.                       gboolean        internal,
  368.                       gboolean        expanded,
  369.                       gfloat          align,
  370.                       gboolean        update_state)
  371. {
  372.   AwnBackgroundLucidoPrivate *priv;
  373.   priv = AWN_BACKGROUND_LUCIDO_GET_PRIVATE (AWN_BACKGROUND_LUCIDO (bg));
  374.  
  375.   if (priv->pos == NULL)
  376.     _init_positions (bg, position, w, expanded, align);
  377.  
  378.   cairo_new_path (cr);
  379.  
  380.   gfloat targetx = x;
  381.   gfloat lx = x;
  382.   gfloat ly = y;
  383.   gfloat y3 = y + h;
  384.   gfloat y2 = y3 - 5.;
  385.   gfloat target_pad_left = 0.;
  386.   gfloat pad_diff = 0.;
  387.   gint j = 0;
  388.  
  389.   /* Get list of widgets */
  390.   GList *widgets = _get_applet_widgets (bg);
  391.   GList *i = widgets;
  392.   GtkWidget *widget = NULL;
  393.   gboolean first_widget_is_special = FALSE;
  394.   if (i && IS_SPECIAL (i->data))
  395.     first_widget_is_special = TRUE;
  396.  
  397.   /* We start from left */
  398.   ly = y3;
  399.   cairo_move_to (cr, lx, ly);
  400.  
  401.   gboolean na = FALSE;
  402.   if (update_state)
  403.   {
  404.     if (!priv->last_exp && expanded)
  405.       na = TRUE;
  406.     priv->last_exp = expanded;
  407.   }
  408.  
  409.   if (expanded)
  410.   {
  411.     target_pad_left = lx + (w - _get_applet_manager_size (bg, position)) * align;
  412.     pad_diff = priv->last_pad - target_pad_left;
  413.     if (update_state)
  414.     {
  415.       fprintf (stderr, "%.1f diff \n",pad_diff);
  416.       priv->last_pad = target_pad_left;
  417.     }
  418.     if (first_widget_is_special)
  419.     {
  420.       /* start from bottom */
  421.       if (internal)
  422.       {
  423.         cairo_new_path (cr);
  424.         ly = y;
  425.         cairo_move_to (cr, lx, ly);
  426.       }
  427.  
  428.       _line_from_to (cr, &lx, &ly, lx, y2);
  429.       /* jump first special widget */
  430.       i = i->next;
  431.       ++j;
  432.     }
  433.     else
  434.     {
  435.       /* start from top */
  436.       if (internal)
  437.       {
  438.         cairo_new_path (cr);
  439.         ly = y;
  440.         cairo_move_to (cr, lx, ly);
  441.       }
  442.  
  443.       _line_from_to (cr, &lx, &ly, lx, y);
  444.     }
  445.   }
  446.   else
  447.   {
  448.     if (align == 0.)
  449.     {
  450.       if (first_widget_is_special)
  451.       {
  452.         /* start from bottom */
  453.         if (internal)
  454.         {
  455.           cairo_new_path (cr);
  456.           ly = y;
  457.           cairo_move_to (cr, lx, ly);
  458.         }
  459.         _line_from_to (cr, &lx, &ly, lx, y2);
  460.         /* jump first special widget */
  461.         i = i->next;
  462.         ++j;
  463.       }
  464.       else
  465.       {
  466.         if (internal)
  467.         {
  468.           cairo_new_path (cr);
  469.           ly = y;
  470.           cairo_move_to (cr, lx, ly);
  471.         }
  472.         else
  473.           /* start from top */
  474.           _line_from_to (cr, &lx, &ly, lx, y);
  475.       }
  476.     }
  477.     else
  478.     {
  479.       target_pad_left = lx + dc;
  480.       pad_diff = priv->last_pad - target_pad_left;
  481.       if (update_state)
  482.         priv->last_pad = target_pad_left;
  483.       if (first_widget_is_special)
  484.       {
  485.         /* start from bottom */
  486.         if (internal)
  487.         {
  488.           cairo_new_path (cr);
  489.           lx = lx + dc;
  490.           ly = y;
  491.           cairo_move_to (cr, lx, ly);
  492.           _line_from_to (cr, &lx, &ly, targetx, y3);
  493.           _line_from_to (cr, &lx, &ly, lx + dc, y2);
  494.         }
  495.         else
  496.         {
  497.           _line_from_to (cr, &lx, &ly, lx + dc, y2);
  498.           /* jump first special widget */
  499.         }
  500.         i = i->next;
  501.         ++j;
  502.       }
  503.       else
  504.       {
  505.         /* start from top */
  506.         if (internal)
  507.         {
  508.           cairo_new_path (cr);
  509.           ly = y;
  510.           lx = lx + dc;
  511.           cairo_move_to (cr, lx, ly);
  512.         }
  513.         else
  514.           _line_from_to (cr, &lx, &ly, lx + dc, y);
  515.       }
  516.     }
  517.   }
  518.   /* "first curve" done.   */
  519.   /* now we are on y or y2 */
  520.   /* start loop on widgets */
  521.   targetx = lx;
  522.   gfloat lastx = 0.;
  523.  
  524.   for (; i; i = i->next)
  525.   {
  526.     widget = GTK_WIDGET (i->data);
  527.  
  528.     if (!IS_SPECIAL (widget))
  529.     {
  530.       /* if not special continue */
  531.       continue;
  532.     }
  533.     /* special found */
  534.     if (update_state)
  535.     {
  536.       switch (position)
  537.       {
  538.         case GTK_POS_BOTTOM:
  539.         case GTK_POS_TOP:
  540.           targetx = widget->allocation.x + target_pad_left;
  541.           break;
  542.         default:
  543.           targetx = widget->allocation.y + target_pad_left;
  544.           break;
  545.       }
  546.       lastx = g_array_index (priv->pos, gfloat, j);
  547.       if (!expanded)
  548.         lastx += pad_diff;
  549.       if (fabs (targetx - lastx) > 0.2)
  550.       {
  551.         //fprintf (stderr, "pos : %d | %.1f -> %.1f",j,lastx,targetx);
  552.         targetx = lastx + (targetx - lastx) / 4;
  553.         g_array_index (priv->pos, gfloat, j) = targetx;
  554.         //fprintf (stderr, " -> %.1f \n",targetx);
  555.         na = TRUE;
  556.       }
  557.     }
  558.     else
  559.     {
  560.       targetx = g_array_index (priv->pos, gfloat, j);
  561.       //fprintf (stderr, "pos : %d | %.1f \n",j,targetx);
  562.     }
  563.  
  564.     ++j;
  565.  
  566.     _line_from_to (cr, &lx, &ly, targetx, ly);
  567.     if (ly == y2)
  568.       _line_from_to (cr, &lx, &ly, lx + d, y);
  569.     else
  570.       _line_from_to (cr, &lx, &ly, lx + d, y2);
  571.  
  572.   }
  573.   g_list_free (widgets);
  574.  
  575.   if (update_state)
  576.     priv->needs_animation = na;
  577.  
  578.   if (expanded)
  579.   {
  580.     /* make sure that cairo close path in the right way */
  581.     _line_from_to (cr, &lx, &ly, w, ly);
  582.     if (internal)
  583.       _line_from_to (cr, &lx, &ly, lx, y);
  584.     else
  585.       _line_from_to (cr, &lx, &ly, lx, y3);
  586.   }
  587.   else
  588.   {
  589.     if (align == 1.)
  590.     {
  591.       if (internal)
  592.       {
  593.         if (ly == y2)
  594.         {
  595.           _line_from_to (cr, &lx, &ly, w, ly);
  596.           _line_from_to (cr, &lx, &ly, lx, y);
  597.         }
  598.         /* else close path */
  599.       }
  600.       else
  601.       {
  602.         _line_from_to (cr, &lx, &ly, w, ly);
  603.         _line_from_to (cr, &lx, &ly, lx, y3);
  604.       }
  605.     }
  606.     else
  607.     {
  608.       if (internal)
  609.       {
  610.         if (ly == y2)
  611.         {
  612.           _line_from_to (cr, &lx, &ly, w - dc, y2);
  613.           _line_from_to (cr, &lx, &ly, w, y3);
  614.           _line_from_to (cr, &lx, &ly, w - dc, y);
  615.         }
  616.         /* else close path */
  617.       }
  618.       else
  619.       {
  620.         _line_from_to (cr, &lx, &ly, w - dc, ly);
  621.         _line_from_to (cr, &lx, &ly, w, y3);
  622.       }
  623.     }
  624.   }
  625.   cairo_close_path (cr);
  626. }
  627.  
  628. static void
  629. draw_top_bottom_background (AwnBackground*   bg,
  630.                             GtkPositionType  position,
  631.                             cairo_t*         cr,
  632.                             gfloat           width,
  633.                             gfloat           height)
  634. {
  635.   cairo_pattern_t *pat = NULL;
  636.   cairo_pattern_t *pat_hi = NULL;
  637.  
  638.   /* Basic set-up */
  639.   cairo_set_line_width (cr, 1.0);
  640.   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
  641.  
  642.   gboolean expand = FALSE;
  643.   g_object_get (bg->panel, "expand", &expand, NULL);
  644.  
  645.   gfloat align = awn_background_get_panel_alignment (AWN_BACKGROUND (bg));
  646.  
  647.   /* Make sure the bar gets drawn on the 0.5 pixels (for sharp edges) */
  648.   cairo_translate (cr, 0.5, 0.5);
  649.   width -= 0.5;
  650.   height -= 0.5;
  651.  
  652.   if (gtk_widget_is_composited (GTK_WIDGET (bg->panel)) == FALSE)
  653.   {
  654.     goto paint_lines;
  655.   }
  656.  
  657.   /* create internal path */
  658.   _create_path_lucido (bg, position, cr, -1.0, 0., width, height,
  659.                        TRANSFORM_RADIUS (bg->corner_radius),
  660.                        TRANSFORM_RADIUS (bg->corner_radius),
  661.                        1, expand, align, TRUE);
  662.  
  663.   /* Draw internal pattern if needed */
  664.   if (bg->enable_pattern && bg->pattern)
  665.   {
  666.     /* Prepare pattern */
  667.     pat_hi = cairo_pattern_create_for_surface (bg->pattern);
  668.     cairo_pattern_set_extend (pat_hi, CAIRO_EXTEND_REPEAT);
  669.     /* Draw */
  670.     cairo_save (cr);
  671.     cairo_clip_preserve (cr);
  672.     cairo_set_source (cr, pat_hi);
  673.     cairo_paint (cr);
  674.     cairo_restore (cr);
  675.     cairo_pattern_destroy (pat_hi);
  676.   }
  677.   /* Prepare the hi-light */
  678.   pat_hi = cairo_pattern_create_linear (0, 0, 0, height);
  679.   awn_cairo_pattern_add_color_stop_color (pat_hi, 0.0, bg->g_histep_1);
  680.   awn_cairo_pattern_add_color_stop_color (pat_hi, 0.3, bg->g_histep_2);
  681.   double red, green, blue, alpha;
  682.   desktop_agnostic_color_get_cairo_color (bg->g_histep_2, &red, &green, &blue, &alpha);
  683.   cairo_pattern_add_color_stop_rgba (pat_hi, 0.4, red, green, blue, 0.);
  684.  
  685.   /* Prepare the internal background */
  686.   pat = cairo_pattern_create_linear (0, 0, 0, height);
  687.   awn_cairo_pattern_add_color_stop_color (pat, 0.0, bg->border_color);
  688.   awn_cairo_pattern_add_color_stop_color (pat, 1.0, bg->hilight_color);
  689.  
  690.   /* Draw the internal background gradient */
  691.   cairo_save (cr);
  692.   cairo_clip_preserve (cr);
  693.   cairo_set_source (cr, pat);
  694.   cairo_paint (cr);
  695.   cairo_restore (cr);
  696.   /* Draw the internal hi-light gradient */
  697.   cairo_save (cr);
  698.   cairo_clip (cr);
  699.   cairo_set_source (cr, pat_hi);
  700.   cairo_paint (cr);
  701.   cairo_restore (cr);
  702.  
  703.   /* Prepare external background gradient*/  
  704.   cairo_pattern_destroy (pat);
  705.   pat = cairo_pattern_create_linear (0, 0, 0, height);
  706.   awn_cairo_pattern_add_color_stop_color (pat, 0.0, bg->g_step_1);
  707.   awn_cairo_pattern_add_color_stop_color (pat, 1.0, bg->g_step_2);
  708.  
  709.  
  710.   /* create external path */
  711.   _create_path_lucido (bg, position, cr, -1.0, 0., width, height,
  712.                        TRANSFORM_RADIUS (bg->corner_radius),
  713.                        TRANSFORM_RADIUS (bg->corner_radius),
  714.                        0, expand, align, FALSE);
  715.                        
  716.   /* Draw the external background  */
  717.   cairo_save (cr);
  718.   cairo_clip_preserve (cr);
  719.   cairo_set_source (cr, pat);
  720.   cairo_paint (cr);
  721.   cairo_restore (cr);
  722.   cairo_pattern_destroy (pat);
  723.  
  724.   /* Draw the internal hi-light gradient */
  725.   cairo_save (cr);
  726.   cairo_clip (cr);
  727.   cairo_set_source (cr, pat_hi);
  728.   cairo_paint (cr);
  729.   cairo_restore (cr);
  730.  
  731.   cairo_pattern_destroy (pat_hi);
  732.  
  733.   return;
  734.   /* if not composited */
  735. paint_lines:
  736.  
  737.   if (expand)
  738.   {
  739.     /* Internal border */
  740.     awn_cairo_set_source_color (cr, bg->hilight_color);
  741.     cairo_rectangle (cr, 1, 1, width - 3, height + 3);
  742.     cairo_stroke (cr);
  743.  
  744.     /* External border */    
  745.     awn_cairo_set_source_color (cr, bg->border_color);
  746.     cairo_rectangle (cr, 1, 1, width - 1, height + 3);
  747.   }
  748.   else
  749.   {
  750.     awn_cairo_set_source_color (cr, bg->border_color);
  751.     _create_path_lucido (bg, position, cr, 0., 0., width, height,
  752.                          TRANSFORM_RADIUS (bg->corner_radius),
  753.                          TRANSFORM_RADIUS (bg->corner_radius),
  754.                          0, expand, align, TRUE);
  755.     cairo_stroke (cr);
  756.     awn_cairo_set_source_color (cr, bg->hilight_color);
  757.     _create_path_lucido (bg, position, cr, 1., 1., width-1., height-1.,
  758.                          TRANSFORM_RADIUS (bg->corner_radius),
  759.                          TRANSFORM_RADIUS (bg->corner_radius),
  760.                          0, expand, align, FALSE);
  761.   }
  762.   cairo_stroke (cr);
  763. }
  764.  
  765.  
  766. static
  767. void awn_background_lucido_padding_request (AwnBackground *bg,
  768.     GtkPositionType position,
  769.     guint *padding_top,
  770.     guint *padding_bottom,
  771.     guint *padding_left,
  772.     guint *padding_right)
  773. {
  774.   #define TOP_PADDING 2
  775.   gboolean expand = FALSE;
  776.   g_object_get (bg->panel, "expand", &expand, NULL);
  777.   gint side_padding = expand ? 0 : TRANSFORM_RADIUS (bg->corner_radius);
  778.   gint zero_padding = 0;
  779.  
  780.   gfloat align = awn_background_get_panel_alignment (bg);
  781.   if (awn_background_do_rtl_swap (bg))
  782.   {
  783.     if (align <= 0.0 || align >= 1.0)
  784.     {
  785.       zero_padding = side_padding;
  786.       side_padding = 0;
  787.     }
  788.   }
  789.  
  790.   switch (position)
  791.   {
  792.     case GTK_POS_TOP:
  793.       *padding_top  = 0;
  794.       *padding_bottom = TOP_PADDING;
  795.       *padding_left = align == 0.0 ? zero_padding : side_padding;
  796.       *padding_right = align == 1.0 ? zero_padding : side_padding;
  797.       break;
  798.     case GTK_POS_BOTTOM:
  799.       *padding_top  = TOP_PADDING;
  800.       *padding_bottom = 0;
  801.       *padding_left = align == 0.0 ? zero_padding : side_padding;
  802.       *padding_right = align == 1.0 ? zero_padding : side_padding;
  803.       break;
  804.     case GTK_POS_LEFT:
  805.       *padding_top  = align == 0.0 ? zero_padding : side_padding;
  806.       *padding_bottom = align == 1.0 ? zero_padding : side_padding;
  807.       *padding_left = 0;
  808.       *padding_right = TOP_PADDING;
  809.       break;
  810.     case GTK_POS_RIGHT:
  811.       *padding_top  = align == 0.0 ? zero_padding : side_padding;
  812.       *padding_bottom = align == 1.0 ? zero_padding : side_padding;
  813.       *padding_left = TOP_PADDING;
  814.       *padding_right = 0;
  815.       break;
  816.     default:
  817.       break;
  818.   }
  819. }
  820.  
  821.  
  822.  
  823. static void
  824. awn_background_lucido_draw (AwnBackground  *bg,
  825.                             cairo_t        *cr,
  826.                             GtkPositionType  position,
  827.                             GdkRectangle   *area)
  828. {
  829.   gint temp;
  830.   gint x = area->x, y = area->y;
  831.   gint width = area->width, height = area->height;
  832.   cairo_save (cr);
  833.  
  834.   switch (position)
  835.   {
  836.     case GTK_POS_RIGHT:
  837.       cairo_translate (cr, 0., y + height);
  838.       cairo_scale (cr, 1., -1.);
  839.       cairo_translate (cr, x, height);
  840.       cairo_rotate (cr, M_PI * 1.5);
  841.       temp = width;
  842.       width = height;
  843.       height = temp;
  844.       break;
  845.     case GTK_POS_LEFT:
  846.       cairo_translate (cr, x + width, y);
  847.       cairo_rotate (cr, M_PI * 0.5);
  848.       temp = width;
  849.       width = height;
  850.       height = temp;
  851.       break;
  852.     case GTK_POS_TOP:
  853.       cairo_translate (cr, x, y + height);
  854.       cairo_scale (cr, 1., -1.);
  855.       break;
  856.     default:
  857.       cairo_translate (cr, x, y);
  858.       break;
  859.   }
  860.  
  861.   draw_top_bottom_background (bg, position, cr, width, height);
  862.  
  863.   cairo_restore (cr);
  864. }
  865.  
  866. static void
  867. _set_special_widget_width_and_transparent (AwnBackground *bg,
  868.                                            gint          width,
  869.                                            gboolean      transp,
  870.                                            gboolean      dispose)
  871. {
  872.   GList *widgets = _get_applet_widgets (bg);
  873.   GList *i = widgets;
  874.   GtkWidget *widget = NULL;
  875.  
  876.   if (i && IS_SPECIAL (i->data) && !dispose)
  877.   {
  878.     widget = GTK_WIDGET (i->data);
  879.     g_object_set (G_OBJECT (widget), "separator-size", 0, NULL);
  880.     g_object_set (G_OBJECT (widget), "transparent", transp, NULL);
  881.     i = i->next;
  882.   }
  883.  
  884.   for (; i; i = i->next)
  885.   {
  886.     widget = GTK_WIDGET (i->data);
  887.     if (!IS_SPECIAL (widget))
  888.     {
  889.       /* if not special continue */
  890.       continue;
  891.     }
  892.     g_object_set (G_OBJECT (widget), "separator-size", width, NULL);
  893.     g_object_set (G_OBJECT (widget), "transparent", transp, NULL);
  894.   }
  895.  
  896.   g_list_free (widgets);
  897. }
  898.  
  899. static gboolean
  900. awn_background_lucido_get_needs_redraw (AwnBackground *bg,
  901.                                         GtkPositionType position,
  902.                                         GdkRectangle *area)
  903. {
  904.   /* Check default needs redraw */
  905.   gboolean nr = AWN_BACKGROUND_CLASS (awn_background_lucido_parent_class)->
  906.                                       get_needs_redraw (bg, position, area);
  907.   if (nr)
  908.   {
  909.     return TRUE;
  910.   }
  911.  
  912.   AwnBackgroundLucido *lbg = NULL;
  913.   lbg = AWN_BACKGROUND_LUCIDO (bg);
  914.   AwnBackgroundLucidoPrivate *priv;
  915.   priv = AWN_BACKGROUND_LUCIDO_GET_PRIVATE (lbg);
  916.  
  917.   gboolean expand = FALSE;
  918.   g_object_get (bg->panel, "expand", &expand, NULL);
  919.  
  920.   gfloat w = 0.;
  921.   switch (position)
  922.   {
  923.     case GTK_POS_BOTTOM:
  924.     case GTK_POS_TOP:
  925.       w = area->width;
  926.       break;
  927.     default:
  928.       w = area->height;
  929.       break;
  930.   }
  931.  
  932.   gfloat align = awn_background_get_panel_alignment (AWN_BACKGROUND (bg));
  933.  
  934.   GList* widgets = _get_applet_widgets (bg);
  935.   GList* i = widgets;
  936.   GtkWidget* widget = NULL;
  937.    
  938.   gfloat target_pad_left = 0.;
  939.    
  940.   if (expand)
  941.     target_pad_left = (w - _get_applet_manager_size (bg, position)) * align;
  942.   else if (align > 0.)
  943.     target_pad_left = TRANSFORM_RADIUS (bg->corner_radius);
  944.  
  945.   gint n = 0;
  946.   gint p = 0;
  947.   w = 0.;
  948.   i = widgets;
  949.   for (; i; i = i->next)
  950.   {
  951.     widget = GTK_WIDGET (i->data);
  952.     if (IS_SPECIAL (widget))
  953.     {
  954.       ++n;
  955.       p += n;
  956.       switch (position)
  957.       {
  958.         case GTK_POS_BOTTOM:
  959.         case GTK_POS_TOP:
  960.           w += (widget->allocation.x) * n;
  961.           break;
  962.         default:
  963.           w += (widget->allocation.y) * n;
  964.           break;
  965.       }
  966.     }
  967.   }
  968.   w += target_pad_left;
  969.   w += -10000. * expand;
  970.   g_list_free (widgets);
  971.   if (priv->expn != n)
  972.   {
  973.     priv->expn = n;
  974.     priv->expp = p;
  975.     priv->expw = w;
  976.     _set_special_widget_width_and_transparent
  977.                   (bg, TRANSFORM_RADIUS (bg->corner_radius), TRUE, FALSE);
  978.  
  979.     _destroy_positions (bg);
  980.     priv->needs_animation = TRUE;
  981.     if (!priv->tid)
  982.     {
  983.       priv->tid = g_timeout_add (ANIM_TIMEOUT, (GSourceFunc)awn_background_lucido_redraw, bg);
  984.     }
  985.     gtk_widget_queue_draw (GTK_WIDGET (AWN_BACKGROUND (bg)->panel));
  986.     return TRUE;
  987.   }
  988.   if (priv->expp != p)
  989.   {
  990.     priv->expp = p;
  991.     priv->expw = w;
  992.     priv->needs_animation = TRUE;
  993.     if (!priv->tid)
  994.     {
  995.       priv->tid = g_timeout_add (ANIM_TIMEOUT, (GSourceFunc)awn_background_lucido_redraw, bg);
  996.     }
  997.     return TRUE;
  998.   }
  999.   if (priv->expw != w)
  1000.   {
  1001.     fprintf (stderr, "EXPW anim %.1f | %.1f \n",priv->expw,w);
  1002.     priv->expw = w;
  1003.     priv->needs_animation = TRUE;
  1004.     if (!priv->tid)
  1005.     {
  1006.       fprintf (stderr, "anim\n");
  1007.       priv->tid = g_timeout_add (ANIM_TIMEOUT, (GSourceFunc)awn_background_lucido_redraw, bg);
  1008.       gtk_widget_queue_draw (GTK_WIDGET (AWN_BACKGROUND (bg)->panel));
  1009.     }
  1010.     return TRUE;
  1011.   }
  1012.   return FALSE;
  1013. }
  1014.  
  1015. static void
  1016. awn_background_lucido_get_shape_mask (AwnBackground   *bg,
  1017.                                       cairo_t         *cr,
  1018.                                       GtkPositionType position,
  1019.                                       GdkRectangle    *area)
  1020. {
  1021.   gint temp;
  1022.   gint x = area->x, y = area->y;
  1023.   gint width = area->width, height = area->height;
  1024.   gfloat   align = 0.5;
  1025.   gboolean expand = FALSE;
  1026.  
  1027.   cairo_save (cr);
  1028.  
  1029.   align = awn_background_get_panel_alignment (bg);
  1030.   g_object_get (bg->panel, "expand", &expand, NULL);
  1031.  
  1032.   switch (position)
  1033.   {
  1034.     case GTK_POS_RIGHT:
  1035.       cairo_translate (cr, 0., y + height);
  1036.       cairo_scale (cr, 1., -1.);
  1037.       cairo_translate (cr, x, height);
  1038.       cairo_rotate (cr, M_PI * 1.5);
  1039.       temp = width;
  1040.       width = height;
  1041.       height = temp;
  1042.       break;
  1043.     case GTK_POS_LEFT:
  1044.       cairo_translate (cr, x + width, y);
  1045.       cairo_rotate (cr, M_PI * 0.5);
  1046.       temp = width;
  1047.       width = height;
  1048.       height = temp;
  1049.       break;
  1050.     case GTK_POS_TOP:
  1051.       cairo_translate (cr, x, y + height);
  1052.       cairo_scale (cr, 1., -1.);
  1053.       break;
  1054.     default:
  1055.       cairo_translate (cr, x, y);
  1056.       break;
  1057.   }
  1058.   if (expand)
  1059.   {
  1060.     cairo_rectangle (cr, 0, 0, width, height + 2);
  1061.   }
  1062.   else
  1063.   {
  1064.     _create_path_lucido (bg, position, cr, 0, 0., width, height,
  1065.                          TRANSFORM_RADIUS (bg->corner_radius),
  1066.                          TRANSFORM_RADIUS (bg->corner_radius),
  1067.                          0, expand, align, FALSE);
  1068.     cairo_fill (cr);
  1069.     _create_path_lucido (bg, position, cr, 0, 0., width, height,
  1070.                          TRANSFORM_RADIUS (bg->corner_radius),
  1071.                          TRANSFORM_RADIUS (bg->corner_radius),
  1072.                          1, expand, align, FALSE);
  1073.  
  1074.   }
  1075.   cairo_fill (cr);
  1076.  
  1077.   cairo_restore (cr);
  1078. }
  1079. /* vim: set et ts=2 sts=2 sw=2 : */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement