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

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