File indexing completed on 2024-05-12 17:10:52

0001 /*
0002  * Legacy theme engine
0003  *
0004  * legacy.c
0005  *
0006  * Copyright (C) 2006 Quinn Storm <livinglatexkali@gmail.com>
0007  *
0008  * This program is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU General Public License
0010  * as published by the Free Software Foundation; either version 2
0011  * of the License, or (at your option) any later version.
0012  *
0013  * This program is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016  * GNU General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0021  *
0022  */
0023 
0024 //legacy engine
0025 #include <emerald.h>
0026 #include <engine.h>
0027 #include "legacy_engine.h"
0028 
0029 #define SECT "legacy_settings"
0030 
0031 /*
0032  * settings structs
0033  */
0034 typedef struct _private_fs
0035 {
0036     alpha_color inner;
0037     alpha_color outer;
0038     alpha_color title_inner;
0039     alpha_color title_outer;
0040     alpha_color window_halo;
0041     alpha_color window_highlight;
0042     alpha_color window_shadow;
0043     alpha_color separator_line;
0044     alpha_color contents_highlight;
0045     alpha_color contents_shadow;
0046     alpha_color contents_halo;
0047 } private_fs;
0048 
0049 typedef struct _private_ws
0050 {
0051     gboolean round_top_left;
0052     gboolean round_top_right;
0053     gboolean round_bottom_left;
0054     gboolean round_bottom_right;
0055     double  corner_radius;
0056 } private_ws;
0057 
0058 void get_meta_info (EngineMetaInfo * emi)
0059 {
0060     emi->version = g_strdup("0.1");
0061     emi->description = g_strdup(_("Based on original gnome-window-decorator"));
0062     emi->last_compat = g_strdup("0.0"); // old themes still compatible
0063     emi->icon = gdk_pixbuf_new_from_inline(-1, my_pixbuf, TRUE, NULL);
0064 }
0065 
0066 void engine_draw_frame (decor_t * d, cairo_t * cr)
0067 {
0068     double        x1, y1, x2, y2, h;
0069     int       top;
0070     frame_settings * fs = d->fs;
0071     private_fs * pfs = fs->engine_fs;
0072     window_settings * ws = fs->ws;
0073     private_ws * pws = ws->engine_ws;
0074     gdouble pleft;
0075     gdouble ptop;
0076     gdouble pwidth;
0077     gdouble pheight;
0078     top = ws->win_extents.top + ws->titlebar_height;
0079 
0080     x1 = ws->left_space - ws->win_extents.left;
0081     y1 = ws->top_space - ws->win_extents.top;
0082     x2 = d->width - ws->right_space + ws->win_extents.right;
0083     y2 = d->height - ws->bottom_space + ws->win_extents.bottom;
0084     pleft   = x1 + ws->win_extents.left - 0.5;
0085     ptop    = y1 + top - 0.5;
0086     pwidth  = x2 - x1 - ws->win_extents.left - ws->win_extents.right + 1;
0087     pheight = y2 - y1 - top-ws->win_extents.bottom + 1;
0088 
0089     h = d->height - ws->top_space - ws->titlebar_height - ws->bottom_space;
0090 
0091     int corners = 
0092         ((pws->round_top_left)     ? CORNER_TOPLEFT     : 0) |
0093         ((pws->round_top_right)    ? CORNER_TOPRIGHT    : 0) |
0094         ((pws->round_bottom_left)  ? CORNER_BOTTOMLEFT  : 0) |
0095         ((pws->round_bottom_right) ? CORNER_BOTTOMRIGHT : 0);
0096     
0097     // maximize work-a-round
0098     if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
0099                 WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
0100         corners = 0;
0101    
0102     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
0103     cairo_set_line_width (cr, 1.0);
0104 
0105     fill_rounded_rectangle (cr,
0106             x1 + 0.5,
0107             y1 + 0.5,
0108             ws->win_extents.left - 0.5,
0109             top - 0.5,
0110             CORNER_TOPLEFT & corners,
0111             &pfs->title_inner, &pfs->title_outer,
0112             SHADE_TOP | SHADE_LEFT, ws,
0113             pws->corner_radius);
0114 
0115     fill_rounded_rectangle (cr,
0116             x1 + ws->win_extents.left,
0117             y1 + 0.5,
0118             x2 - x1 - ws->win_extents.left -
0119             ws->win_extents.right,
0120             top - 0.5,
0121             0,
0122             &pfs->title_inner, &pfs->title_outer,
0123             SHADE_TOP, ws,
0124             pws->corner_radius);
0125 
0126     fill_rounded_rectangle (cr,
0127             x2 - ws->win_extents.right,
0128             y1 + 0.5,
0129             ws->win_extents.right - 0.5,
0130             top - 0.5,
0131             CORNER_TOPRIGHT & corners,
0132             &pfs->title_inner, &pfs->title_outer,
0133             SHADE_TOP | SHADE_RIGHT, ws,
0134             pws->corner_radius);
0135 
0136     fill_rounded_rectangle (cr,
0137             x1 + 0.5,
0138             y1 + top,
0139             ws->win_extents.left - 0.5,
0140             h,
0141             0,
0142             &pfs->inner, &pfs->outer,
0143             SHADE_LEFT, ws,
0144             pws->corner_radius);
0145 
0146     fill_rounded_rectangle (cr,
0147             x2 - ws->win_extents.right,
0148             y1 + top,
0149             ws->win_extents.right - 0.5,
0150             h,
0151             0,
0152             &pfs->inner, &pfs->outer,
0153             SHADE_RIGHT, ws,
0154             pws->corner_radius);
0155 
0156 
0157     fill_rounded_rectangle (cr,
0158             x1 + 0.5,
0159             y2 - ws->win_extents.bottom,
0160             ws->win_extents.left - 0.5,
0161             ws->win_extents.bottom - 0.5,
0162             CORNER_BOTTOMLEFT & corners,
0163             &pfs->inner, &pfs->outer,
0164             SHADE_BOTTOM | SHADE_LEFT, ws,
0165             pws->corner_radius);
0166 
0167     fill_rounded_rectangle (cr,
0168             x1 + ws->win_extents.left,
0169             y2 - ws->win_extents.bottom,
0170             x2 - x1 - ws->win_extents.left -
0171             ws->win_extents.right,
0172             ws->win_extents.bottom - 0.5,
0173             0,
0174             &pfs->inner, &pfs->outer,
0175             SHADE_BOTTOM, ws,
0176             pws->corner_radius);
0177 
0178     fill_rounded_rectangle (cr,
0179             x2 - ws->win_extents.right,
0180             y2 - ws->win_extents.bottom,
0181             ws->win_extents.right - 0.5,
0182             ws->win_extents.bottom - 0.5,
0183             CORNER_BOTTOMRIGHT & corners,
0184             &pfs->inner, &pfs->outer,
0185             SHADE_BOTTOM | SHADE_RIGHT, ws,
0186             pws->corner_radius);
0187 
0188     // ======= NEW LAYER =======
0189     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
0190    
0191     // titlebar separator line
0192     cairo_set_source_alpha_color(cr, &pfs->separator_line);
0193     cairo_move_to (cr, x1 + 0.5, y1 + top - 0.5);
0194     cairo_rel_line_to (cr, x2 - x1 - 1.0, 0.0);
0195     cairo_stroke (cr);
0196 
0197 
0198     // do not draw outside the decoration area
0199     rounded_rectangle (cr,
0200             x1 + 0.5, y1 + 0.5,
0201             x2 - x1 - 1.0, y2 - y1 - 1.0,
0202             (CORNER_TOPLEFT | CORNER_TOPRIGHT |
0203              CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) & corners,
0204             ws, pws->corner_radius);
0205     cairo_clip (cr);
0206 
0207     cairo_translate (cr, 1.0, 1.0);
0208 
0209     // highlight
0210     rounded_rectangle (cr,
0211             x1 + 0.5, y1 + 0.5,
0212             x2 - x1 - 1.0, y2 - y1 - 1.0,
0213             (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
0214              CORNER_BOTTOMRIGHT) & corners, ws,
0215             pws->corner_radius);
0216 
0217     cairo_set_source_alpha_color (cr, &pfs->window_highlight);
0218     cairo_stroke (cr);
0219 
0220     cairo_translate (cr, -2.0, -2.0);
0221 
0222 
0223     // shadow
0224     rounded_rectangle (cr,
0225             x1 + 0.5, y1 + 0.5,
0226             x2 - x1 - 1.0, y2 - y1 - 1.0,
0227             (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
0228              CORNER_BOTTOMRIGHT) & corners, ws,
0229             pws->corner_radius);
0230 
0231     cairo_set_source_alpha_color (cr, &pfs->window_shadow);
0232     cairo_stroke (cr);
0233 
0234     cairo_translate (cr, 1.0, 1.0);
0235 
0236     cairo_reset_clip (cr);
0237     
0238     // halo
0239     rounded_rectangle (cr,
0240             x1 + 0.5, y1 + 0.5,
0241             x2 - x1 - 1.0, y2 - y1 - 1.0,
0242             (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
0243              CORNER_BOTTOMRIGHT) & corners, ws,
0244             pws->corner_radius);
0245 
0246     cairo_set_source_alpha_color (cr, &pfs->window_halo);
0247     cairo_stroke (cr);
0248 
0249     // inner border
0250     //TODO - make this a bit more pixel-perfect...but it works for now
0251 
0252     cairo_set_line_width (cr, 1.0);
0253 
0254     cairo_move_to (cr, pleft + pwidth + 1.5, ptop - 1);
0255     cairo_rel_line_to (cr, -pwidth - 2.5, 0);
0256     cairo_rel_line_to (cr, 0, pheight + 2.5);
0257     cairo_set_source_alpha_color (cr, &pfs->contents_shadow);
0258     cairo_stroke (cr);
0259 
0260     cairo_move_to (cr, pleft + pwidth + 1, ptop - 1.5);
0261     cairo_rel_line_to (cr, 0, pheight + 2.5);
0262     cairo_rel_line_to (cr, -pwidth - 2.5, 0);
0263     cairo_set_source_alpha_color (cr, &pfs->contents_highlight);
0264     cairo_stroke (cr);
0265 
0266     cairo_move_to (cr, pleft, ptop);
0267     cairo_rel_line_to (cr, pwidth, 0);
0268     cairo_rel_line_to (cr, 0, pheight);
0269     cairo_rel_line_to (cr, -pwidth, 0);
0270     cairo_rel_line_to (cr, 0, -pheight);
0271     cairo_set_source_alpha_color (cr, &pfs->contents_halo);
0272     cairo_stroke(cr);
0273 }
0274 
0275 void load_engine_settings(GKeyFile * f, window_settings * ws)
0276 {
0277     private_ws * pws = ws->engine_ws;
0278 
0279     // parse color settings
0280     PFACS(outer);
0281     PFACS(inner);
0282     PFACS(title_outer);
0283     PFACS(title_inner);
0284     PFACS(window_halo);
0285     PFACS(window_highlight);
0286     PFACS(window_shadow);
0287     PFACS(separator_line);
0288     PFACS(contents_shadow);
0289     PFACS(contents_highlight);
0290     PFACS(contents_halo);
0291 
0292     // parse border settings
0293     load_bool_setting(f, &pws->round_top_left, "round_top_left", SECT);
0294     load_bool_setting(f, &pws->round_top_right, "round_top_right", SECT);
0295     load_bool_setting(f, &pws->round_bottom_left, "round_bottom_left", SECT);
0296     load_bool_setting(f, &pws->round_bottom_right, "round_bottom_right", SECT);
0297     load_float_setting(f, &pws->corner_radius, "radius", SECT);
0298 
0299 }
0300 
0301 void init_engine(window_settings * ws)
0302 {
0303     private_fs * pfs;
0304     private_ws * pws;
0305 
0306     // private window settings
0307     pws = malloc(sizeof(private_ws));
0308     ws->engine_ws = pws;
0309     bzero(pws,sizeof(private_ws));
0310     pws->round_top_left = TRUE;
0311     pws->round_top_right = TRUE;
0312     pws->round_bottom_left = TRUE;
0313     pws->round_bottom_right = TRUE;
0314     pws->corner_radius = 5.0;
0315 
0316     // private frame settings for active frames
0317     pfs = malloc(sizeof(private_fs));
0318     ws->fs_act->engine_fs = pfs;
0319     bzero(pfs,sizeof(private_fs));
0320     ACOLOR(inner, 0.8, 0.8, 0.8, 0.5);
0321     ACOLOR(outer, 0.8, 0.8, 0.8, 0.5);
0322     ACOLOR(title_inner, 0.8, 0.8, 0.8, 0.8);
0323     ACOLOR(title_outer, 0.8, 0.8, 0.8, 0.8);
0324     ACOLOR(window_highlight, 1.0, 1.0, 1.0, 0.8);
0325     ACOLOR(window_shadow, 0.6, 0.6, 0.6, 0.8);
0326     ACOLOR(window_halo, 0.8, 0.8, 0.8, 0.8);
0327     ACOLOR(separator_line, 0.0, 0.0, 0.0, 0.0);
0328     ACOLOR(contents_highlight, 1.0, 1.0, 1.0, 0.8);
0329     ACOLOR(contents_shadow, 0.6, 0.6, 0.6, 0.8);
0330     ACOLOR(contents_halo, 0.8, 0.8, 0.8, 0.8);
0331 
0332     // private frame settings for inactive frames
0333     pfs = malloc(sizeof(private_fs));
0334     bzero(pfs, sizeof(private_fs));
0335     ws->fs_inact->engine_fs = pfs;
0336     ACOLOR(inner, 0.8, 0.8, 0.8, 0.3);
0337     ACOLOR(outer, 0.8, 0.8, 0.8, 0.3);
0338     ACOLOR(title_inner, 0.8, 0.8, 0.8, 0.6);
0339     ACOLOR(title_outer, 0.8, 0.8, 0.8, 0.6);
0340     ACOLOR(window_highlight, 1.0, 1.0, 1.0, 0.7);
0341     ACOLOR(window_shadow, 0.6, 0.6, 0.6, 0.7);
0342     ACOLOR(window_halo, 0.8, 0.8, 0.8, 0.7);
0343     ACOLOR(separator_line, 0.0, 0.0, 0.0, 0.0);
0344     ACOLOR(contents_highlight, 1.0, 1.0, 1.0, 0.8);
0345     ACOLOR(contents_shadow, 0.6, 0.6, 0.6, 0.8);
0346     ACOLOR(contents_halo, 0.8, 0.8, 0.8, 0.8);
0347 }
0348 
0349 void fini_engine(window_settings * ws)
0350 {
0351     free(ws->fs_act->engine_fs);
0352     free(ws->fs_inact->engine_fs);
0353 }
0354 #if 0
0355 void layout_corners_frame(GtkWidget * vbox)
0356 {
0357     GtkWidget * hbox;
0358     GtkWidget * junk;
0359 
0360     junk = gtk_check_button_new_with_label(_("Round Top Left Corner"));
0361     gtk_box_pack_startC(vbox, junk, FALSE, FALSE, 0);
0362     register_setting(junk, ST_BOOL, SECT, "round_top_left");
0363 
0364     junk = gtk_check_button_new_with_label(_("Round Top Right Corner"));
0365     gtk_box_pack_startC(vbox, junk, FALSE, FALSE, 0);
0366     register_setting(junk, ST_BOOL, SECT, "round_top_right");
0367 
0368     junk = gtk_check_button_new_with_label(_("Round Bottom Left Corner"));
0369     gtk_box_pack_startC(vbox, junk, FALSE, FALSE, 0);
0370     register_setting(junk, ST_BOOL, SECT, "round_bottom_left");
0371 
0372     junk = gtk_check_button_new_with_label(_("Round Bottom Right Corner"));
0373     gtk_box_pack_startC(vbox, junk, FALSE, FALSE, 0);
0374     register_setting(junk, ST_BOOL, SECT, "round_bottom_right");
0375 
0376     hbox = gtk_hbox_new(FALSE, 2);
0377     gtk_box_pack_startC(vbox, hbox, FALSE, FALSE, 0);
0378     
0379     gtk_box_pack_startC(hbox, gtk_label_new(_("Rounding Radius")), FALSE, FALSE, 0);
0380 
0381     junk = scaler_new(0, 20, 0.5);
0382     gtk_box_pack_startC(hbox, junk, TRUE, TRUE, 0);
0383     register_setting(junk, ST_FLOAT, SECT, "radius");
0384 }
0385 
0386 void my_engine_settings(GtkWidget * hbox, gboolean active)
0387 {
0388     GtkWidget * vbox;
0389     GtkWidget * scroller;
0390     vbox = gtk_vbox_new(FALSE, 2);
0391     gtk_box_pack_startC(hbox, vbox, TRUE, TRUE, 0);
0392     gtk_box_pack_startC(vbox, gtk_label_new(active?"Active Window":"Inactive Window"), FALSE, FALSE, 0);
0393     gtk_box_pack_startC(vbox, gtk_hseparator_new(), FALSE, FALSE, 0);
0394     scroller = gtk_scrolled_window_new(NULL, NULL);
0395     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
0396             GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
0397     gtk_box_pack_startC(vbox, scroller, TRUE, TRUE, 0);
0398     
0399     table_new(3, FALSE, FALSE);
0400 
0401     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroller), GTK_WIDGET(get_current_table()));
0402     
0403     make_labels(_("Colors"));
0404     table_append_separator();
0405     ACAV(_("Outer Frame Blend"), "outer", SECT);
0406     ACAV(_("Inner Frame Blend"), "inner", SECT);
0407     table_append_separator();
0408     ACAV(_("Outer Titlebar Blend"), "title_outer", SECT);
0409     ACAV(_("Inner Titlebar Blend"), "title_inner", SECT);
0410     table_append_separator();
0411     ACAV(_("Titlebar Separator"), "separator_line", SECT);
0412     table_append_separator();
0413     ACAV(_("Frame Outline"), "window_halo", SECT);
0414     ACAV(_("Frame Highlight"), "window_highlight", SECT);
0415     ACAV(_("Frame Shadow"), "window_shadow", SECT);
0416     table_append_separator();
0417     ACAV(_("Contents Outline"), "contents_halo", SECT);
0418     ACAV(_("Contents Highlight"), "contents_highlight", SECT);
0419     ACAV(_("Contents Shadow"), "contents_shadow", SECT);
0420 }
0421 
0422 void layout_engine_colors(GtkWidget * vbox)
0423 {
0424     GtkWidget * hbox;
0425     hbox = gtk_hbox_new(FALSE, 2);
0426     gtk_box_pack_startC(vbox, hbox, TRUE, TRUE, 0);
0427     my_engine_settings(hbox, TRUE);
0428     gtk_box_pack_startC(hbox, gtk_vseparator_new(), FALSE, FALSE, 0);
0429     my_engine_settings(hbox, FALSE);
0430 }
0431 
0432 void layout_engine_settings(GtkWidget * vbox)
0433 {
0434     GtkWidget * note;
0435     note = gtk_notebook_new();
0436     gtk_box_pack_startC(vbox, note, TRUE, TRUE, 0);
0437     layout_engine_colors(build_notebook_page(_("Colors"), note));
0438     layout_corners_frame(build_notebook_page(_("Frame"), note));
0439 }
0440 #endif