File indexing completed on 2024-04-28 09:42:16
0001 /***************************************************************************** 0002 * Copyright 2003 - 2010 Craig Drummond <craig.p.drummond@gmail.com> * 0003 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU Lesser General Public License as * 0007 * published by the Free Software Foundation; either version 2.1 of the * 0008 * License, or (at your option) version 3, or any later version accepted * 0009 * by the membership of KDE e.V. (or its successor approved by the * 0010 * membership of KDE e.V.), which shall act as a proxy defined in * 0011 * Section 6 of version 3 of the license. * 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 GNU * 0016 * Lesser General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU Lesser General Public * 0019 * License along with this library. If not, * 0020 * see <http://www.gnu.org/licenses/>. * 0021 *****************************************************************************/ 0022 0023 #include "helpers.h" 0024 0025 #include <qtcurve-utils/gtkprops.h> 0026 #include <qtcurve-utils/x11blur.h> 0027 #include <qtcurve-utils/color.h> 0028 #include <qtcurve-utils/log.h> 0029 #include <qtcurve-utils/strs.h> 0030 0031 #include "qt_settings.h" 0032 #include <gdk/gdkx.h> 0033 0034 namespace QtCurve { 0035 0036 void 0037 debugDisplayWidget(GtkWidget *widget, int level) 0038 { 0039 if (Log::level() > LogLevel::Debug) 0040 return; 0041 if (level < 0 || !widget) { 0042 printf("\n"); 0043 return; 0044 } 0045 const char *widget_name = gtk_widget_get_name(widget); 0046 qtcDebug("%s(%s)[%p] ", gTypeName(widget), 0047 widget_name ? widget_name : "NULL", widget); 0048 debugDisplayWidget(gtk_widget_get_parent(widget), level - 1); 0049 } 0050 0051 bool 0052 haveAlternateListViewCol() 0053 { 0054 return (qtSettings.colors[PAL_ACTIVE][COLOR_LV].red != 0 || 0055 qtSettings.colors[PAL_ACTIVE][COLOR_LV].green != 0 || 0056 qtSettings.colors[PAL_ACTIVE][COLOR_LV].blue != 0); 0057 } 0058 0059 GdkColor* 0060 menuColors(bool active) 0061 { 0062 return (SHADE_WINDOW_BORDER == opts.shadeMenubars ? 0063 qtcPalette.wborder[active ? 1 : 0] : 0064 SHADE_NONE == opts.shadeMenubars || 0065 (opts.shadeMenubarOnlyWhenActive && !active) ? 0066 qtcPalette.background : qtcPalette.menubar); 0067 } 0068 0069 EBorder 0070 shadowToBorder(GtkShadowType shadow) 0071 { 0072 switch (shadow) { 0073 default: 0074 case GTK_SHADOW_NONE: 0075 return BORDER_FLAT; 0076 case GTK_SHADOW_IN: 0077 case GTK_SHADOW_ETCHED_IN: 0078 return BORDER_SUNKEN; 0079 case GTK_SHADOW_OUT: 0080 case GTK_SHADOW_ETCHED_OUT: 0081 return BORDER_RAISED; 0082 } 0083 } 0084 0085 bool 0086 useButtonColor(const char *detail) 0087 { 0088 return (detail && 0089 (oneOf(detail, "optionmenu", "button", "buttondefault", 0090 "togglebuttondefault", "togglebutton", "hscale", "vscale", 0091 "spinbutton", "spinbutton_up", "spinbutton_down", "slider", 0092 "qtc-slider", "stepper") || 0093 (detail[0] && Str::startsWith(detail + 1, "scrollbar")))); 0094 } 0095 0096 void 0097 shadeColors(const GdkColor *base, GdkColor *vals) 0098 { 0099 bool useCustom = USE_CUSTOM_SHADES(opts); 0100 double hl = TO_FACTOR(opts.highlightFactor); 0101 0102 for (int i = 0;i < QTC_NUM_STD_SHADES;i++) { 0103 qtcShade(base, &vals[i], useCustom ? opts.customShades[i] : 0104 qtcShadeGetIntern(opts.contrast, i, opts.darkerBorders, 0105 opts.shading), opts.shading); 0106 } 0107 qtcShade(base, &vals[SHADE_ORIG_HIGHLIGHT], hl, opts.shading); 0108 qtcShade(&vals[4], &vals[SHADE_4_HIGHLIGHT], hl, opts.shading); 0109 qtcShade(&vals[2], &vals[SHADE_2_HIGHLIGHT], hl, opts.shading); 0110 vals[ORIGINAL_SHADE] = *base; 0111 } 0112 0113 bool 0114 isSortColumn(GtkWidget *button) 0115 { 0116 GtkWidget *parent = nullptr; 0117 if (button && (parent = gtk_widget_get_parent(button)) && 0118 GTK_IS_TREE_VIEW(parent)) { 0119 #if GTK_CHECK_VERSION(2, 90, 0) 0120 GtkWidget *box = (GTK_IS_BUTTON(button) ? 0121 gtk_bin_get_child(GTK_BIN(button)) : nullptr); 0122 0123 if (box && GTK_IS_BOX(box)) { 0124 GList *children = gtk_container_get_children(GTK_CONTAINER(box)); 0125 bool found = false; 0126 for (GList *child = children;child && !found; 0127 child = g_list_next(child)) { 0128 if (GTK_IS_ARROW(child->data)) { 0129 int val; 0130 g_object_get(child->data, "arrow-type", &val, nullptr); 0131 if (GTK_ARROW_NONE != val) { 0132 found = true; 0133 } 0134 } 0135 } 0136 if (children) { 0137 g_list_free(children); 0138 } 0139 return found; 0140 } 0141 #else 0142 GtkWidget *sort = nullptr; 0143 GList *columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(parent)); 0144 for (GList *column = columns;column && !sort && sort != button; 0145 column = g_list_next(column)) { 0146 if (GTK_IS_TREE_VIEW_COLUMN(column->data)) { 0147 GtkTreeViewColumn *c = GTK_TREE_VIEW_COLUMN(column->data); 0148 if (gtk_tree_view_column_get_sort_indicator(c)) { 0149 sort = c->button; 0150 } 0151 } 0152 } 0153 0154 if (columns) { 0155 g_list_free(columns); 0156 } 0157 return sort == button; 0158 #endif 0159 } 0160 return false; 0161 }; 0162 0163 GdkColor* 0164 getCellCol(GdkColor *std, const char *detail) 0165 { 0166 if (!qtSettings.shadeSortedList || !strstr(detail, "_sorted")) 0167 return std; 0168 0169 static GdkColor shaded; 0170 shaded = *std; 0171 0172 if (isBlack(shaded)) { 0173 shaded.red = shaded.green = shaded.blue = 55 << 8; 0174 } else { 0175 double r = shaded.red / 65535.0; 0176 double g = shaded.green / 65535.0; 0177 double b = shaded.blue / 65535.0; 0178 double h, s, v; 0179 0180 qtcRgbToHsv(r, g, b, &h, &s, &v); 0181 0182 if (v > 175.0 / 255.0) { 0183 v *= 100.0 / 104.0; 0184 } else { 0185 v *= 120.0 / 100.0; 0186 } 0187 0188 if (v > 1.0) { 0189 s = qtcMax(0, s - (v - 1.0)); 0190 v = 1.0; 0191 } 0192 0193 qtcHsvToRgb(&r, &g, &b, h, s, v); 0194 shaded.red = r * 65535.0; 0195 shaded.green = g * 65535.0; 0196 shaded.blue = b * 65535.0; 0197 } 0198 return &shaded; 0199 } 0200 0201 bool 0202 reverseLayout(GtkWidget *widget) 0203 { 0204 if (widget) { 0205 return gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL; 0206 } 0207 return false; 0208 } 0209 0210 bool 0211 isOnToolbar(GtkWidget *widget, bool *horiz, int level) 0212 { 0213 if (widget) { 0214 if (GTK_IS_TOOLBAR(widget)) { 0215 qtcAssign(horiz, Widget::isHorizontal(widget)); 0216 return true; 0217 } else if (level < 4) { 0218 return isOnToolbar(gtk_widget_get_parent(widget), horiz, level + 1); 0219 } 0220 } 0221 return false; 0222 } 0223 0224 bool 0225 isOnHandlebox(GtkWidget *widget, bool *horiz, int level) 0226 { 0227 if (widget) { 0228 if (GTK_IS_HANDLE_BOX(widget)) { 0229 qtcAssign(horiz, oneOf(gtk_handle_box_get_handle_position( 0230 GTK_HANDLE_BOX(widget)), 0231 GTK_POS_LEFT, GTK_POS_RIGHT)); 0232 return true; 0233 } else if (level < 4) { 0234 return isOnHandlebox(gtk_widget_get_parent(widget), horiz, 0235 level + 1); 0236 } 0237 } 0238 return false; 0239 } 0240 0241 bool 0242 isButtonOnToolbar(GtkWidget *widget, bool *horiz) 0243 { 0244 GtkWidget *parent = nullptr; 0245 if (widget && (parent = gtk_widget_get_parent(widget)) && 0246 GTK_IS_BUTTON(widget)) { 0247 return isOnToolbar(parent, horiz, 0); 0248 } 0249 return false; 0250 } 0251 0252 bool 0253 isButtonOnHandlebox(GtkWidget *widget, bool *horiz) 0254 { 0255 GtkWidget *parent = nullptr; 0256 if (widget && (parent = gtk_widget_get_parent(widget)) && 0257 GTK_IS_BUTTON(widget)) { 0258 return isOnHandlebox(parent, horiz, 0); 0259 } 0260 return false; 0261 } 0262 0263 bool 0264 isOnStatusBar(GtkWidget *widget, int level) 0265 { 0266 GtkWidget *parent = gtk_widget_get_parent(widget); 0267 if (parent) { 0268 if (GTK_IS_STATUSBAR(parent)) { 0269 return true; 0270 } else if (level < 4) { 0271 return isOnStatusBar(parent, level + 1); 0272 } 0273 } 0274 return false; 0275 } 0276 0277 bool 0278 isList(GtkWidget *widget) 0279 { 0280 return widget && (GTK_IS_TREE_VIEW(widget) || 0281 #if !GTK_CHECK_VERSION(2, 90, 0) 0282 GTK_IS_CLIST(widget) || GTK_IS_LIST(widget) || 0283 #ifdef GTK_ENABLE_BROKEN 0284 GTK_IS_TREE(widget) || 0285 #endif 0286 GTK_IS_CTREE(widget) || 0287 #endif 0288 oneOf(gTypeName(widget), "GtkSCTree")); 0289 } 0290 0291 bool 0292 isListViewHeader(GtkWidget *widget) 0293 { 0294 GtkWidget *parent = nullptr; 0295 return widget && GTK_IS_BUTTON(widget) && (parent=gtk_widget_get_parent(widget)) && 0296 (isList(parent) || 0297 (GTK_APP_GIMP == qtSettings.app && GTK_IS_BOX(parent) && 0298 (parent=gtk_widget_get_parent(parent)) && 0299 GTK_IS_EVENT_BOX(parent) && 0300 (parent=gtk_widget_get_parent(parent)) && 0301 oneOf(gTypeName(parent), "GimpThumbBox"))); 0302 } 0303 0304 bool 0305 isEvolutionListViewHeader(GtkWidget *widget, const char *detail) 0306 { 0307 GtkWidget *parent = nullptr; 0308 return ((qtSettings.app == GTK_APP_EVOLUTION) && widget && 0309 oneOf(detail, "button") && 0310 oneOf(gTypeName(widget), "ECanvas") && 0311 (parent = gtk_widget_get_parent(widget)) && 0312 (parent = gtk_widget_get_parent(parent)) && 0313 GTK_IS_SCROLLED_WINDOW(parent)); 0314 } 0315 0316 bool isOnListViewHeader(GtkWidget *w, int level) 0317 { 0318 if (w) { 0319 if (isListViewHeader(w)) { 0320 return true; 0321 } else if (level < 4) { 0322 return isOnListViewHeader(gtk_widget_get_parent(w), level + 1); 0323 } 0324 } 0325 return false; 0326 } 0327 0328 bool 0329 isPathButton(GtkWidget *widget) 0330 { 0331 return (widget && GTK_IS_BUTTON(widget) && 0332 oneOf(gTypeName(gtk_widget_get_parent(widget)), "GtkPathBar")); 0333 } 0334 0335 // static gboolean isTabButton(GtkWidget *widget) 0336 // { 0337 // return widget && GTK_IS_BUTTON(widget) && gtk_widget_get_parent(widget) && 0338 // (GTK_IS_NOTEBOOK(gtk_widget_get_parent(widget)) || 0339 // (gtk_widget_get_parent(widget)->parent && GTK_IS_BOX(gtk_widget_get_parent(widget)) && GTK_IS_NOTEBOOK(gtk_widget_get_parent(widget)->parent))); 0340 // } 0341 0342 GtkWidget* 0343 getComboEntry(GtkWidget *widget) 0344 { 0345 GList *children = gtk_container_get_children(GTK_CONTAINER(widget)); 0346 GtkWidget *rv = nullptr; 0347 for (GList *child = children;child && !rv;child = child->next) { 0348 GtkWidget *boxChild = (GtkWidget *)child->data; 0349 if (GTK_IS_ENTRY(boxChild)) { 0350 rv = (GtkWidget*)boxChild; 0351 } 0352 } 0353 if (children) { 0354 g_list_free(children); 0355 } 0356 return rv; 0357 } 0358 0359 GtkWidget* 0360 getComboButton(GtkWidget *widget) 0361 { 0362 GList *children = gtk_container_get_children(GTK_CONTAINER(widget)); 0363 GtkWidget *rv = nullptr; 0364 for (GList *child = children;child && !rv;child = child->next) { 0365 GtkWidget *boxChild = (GtkWidget*)child->data; 0366 if (GTK_IS_BUTTON(boxChild)) { 0367 rv = (GtkWidget*)boxChild; 0368 } 0369 } 0370 if (children) { 0371 g_list_free(children); 0372 } 0373 return rv; 0374 } 0375 0376 bool isSideBarBtn(GtkWidget *widget) 0377 { 0378 return widget && oneOf(gTypeName(gtk_widget_get_parent(widget)), 0379 "GdlDockBar", "GdlSwitcher"); 0380 } 0381 0382 bool isComboBoxButton(GtkWidget *widget) 0383 { 0384 GtkWidget *parent = nullptr; 0385 return widget && GTK_IS_BUTTON(widget) && (parent=gtk_widget_get_parent(widget)) && 0386 (QTC_COMBO_ENTRY(parent) || QTC_IS_COMBO(parent)); 0387 } 0388 0389 bool isComboBox(GtkWidget *widget) 0390 { 0391 GtkWidget *parent=nullptr; 0392 return widget && GTK_IS_BUTTON(widget) && (parent=gtk_widget_get_parent(widget)) && 0393 !QTC_COMBO_ENTRY(parent) && (GTK_IS_COMBO_BOX(parent) || QTC_IS_COMBO(parent)); 0394 } 0395 0396 bool isComboBoxEntry(GtkWidget *widget) 0397 { 0398 GtkWidget *parent=nullptr; 0399 return widget && GTK_IS_ENTRY(widget) && (parent=gtk_widget_get_parent(widget)) && 0400 (QTC_COMBO_ENTRY(parent) || QTC_IS_COMBO(parent)); 0401 } 0402 0403 bool isComboBoxEntryButton(GtkWidget *widget) 0404 { 0405 GtkWidget *parent=nullptr; 0406 return widget && (parent=gtk_widget_get_parent(widget)) && GTK_IS_TOGGLE_BUTTON(widget) && QTC_COMBO_ENTRY(parent); 0407 } 0408 0409 /* 0410 static gboolean isSwtComboBoxEntry(GtkWidget *widget) 0411 { 0412 return GTK_APP_JAVA_SWT == qtSettings.app && 0413 isComboBoxEntry(widget) && 0414 gtk_widget_get_parent(widget)->parent && 0 == strcmp(g_type_name(G_OBJECT_TYPE(gtk_widget_get_parent(widget)->parent)), "SwtFixed"); 0415 } 0416 */ 0417 0418 bool isGimpCombo(GtkWidget *widget) 0419 { 0420 return (qtSettings.app == GTK_APP_GIMP && widget && 0421 GTK_IS_TOGGLE_BUTTON(widget) && 0422 oneOf(gTypeName(gtk_widget_get_parent(widget)), 0423 "GimpEnumComboBox")); 0424 } 0425 0426 bool 0427 isOnComboEntry(GtkWidget *w, int level) 0428 { 0429 if (w) { 0430 if (QTC_COMBO_ENTRY(w)) { 0431 return true; 0432 } else if (level < 4) { 0433 return isOnComboEntry(gtk_widget_get_parent(w), level + 1); 0434 } 0435 } 0436 return false; 0437 } 0438 0439 bool 0440 isOnComboBox(GtkWidget *w, int level) 0441 { 0442 if (w) { 0443 if (GTK_IS_COMBO_BOX(w)) { 0444 return true; 0445 } else if (level < 4) { 0446 return isOnComboBox(gtk_widget_get_parent(w), level + 1); 0447 } 0448 } 0449 return false; 0450 } 0451 0452 bool 0453 isOnCombo(GtkWidget *w, int level) 0454 { 0455 if (w) { 0456 if (QTC_IS_COMBO(w)) { 0457 return true; 0458 } else if (level < 4) { 0459 return isOnCombo(gtk_widget_get_parent(w), level + 1); 0460 } 0461 } 0462 return false; 0463 } 0464 0465 #if !GTK_CHECK_VERSION(2, 90, 0) 0466 bool isOnOptionMenu(GtkWidget *w, int level) 0467 { 0468 if (w) { 0469 if (GTK_IS_OPTION_MENU(w)) { 0470 return true; 0471 } else if (level < 4) { 0472 return isOnOptionMenu(gtk_widget_get_parent(w), level + 1); 0473 } 0474 } 0475 return false; 0476 } 0477 0478 bool isActiveOptionMenu(GtkWidget *widget) 0479 { 0480 if (GTK_IS_OPTION_MENU(widget)) { 0481 GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(widget)); 0482 if(menu && gtk_widget_get_visible(menu) && 0483 gtk_widget_get_realized(menu)) { 0484 return true; 0485 } 0486 } 0487 return false; 0488 } 0489 #endif 0490 0491 bool isOnMenuItem(GtkWidget *w, int level) 0492 { 0493 if(w) 0494 { 0495 if(GTK_IS_MENU_ITEM(w)) 0496 return true; 0497 else if(level<4) 0498 return isOnMenuItem(gtk_widget_get_parent(w), ++level); 0499 } 0500 return false; 0501 } 0502 0503 bool isSpinButton(GtkWidget *widget) 0504 { 0505 return widget && GTK_IS_SPIN_BUTTON(widget); 0506 } 0507 0508 bool isStatusBarFrame(GtkWidget *widget) 0509 { 0510 GtkWidget *parent=nullptr; 0511 return widget && (parent=gtk_widget_get_parent(widget)) && GTK_IS_FRAME(widget) && 0512 (GTK_IS_STATUSBAR(parent) || ((parent=gtk_widget_get_parent(parent)) && GTK_IS_STATUSBAR(parent))); 0513 } 0514 0515 GtkMenuBar * isMenubar(GtkWidget *w, int level) 0516 { 0517 if(w) 0518 { 0519 if(GTK_IS_MENU_BAR(w)) 0520 return (GtkMenuBar*)w; 0521 else if(level<3) 0522 return isMenubar(gtk_widget_get_parent(w), level++); 0523 } 0524 0525 return nullptr; 0526 } 0527 0528 bool isMenuitem(GtkWidget *w, int level) 0529 { 0530 if(w) 0531 { 0532 if(GTK_IS_MENU_ITEM(w)) 0533 return true; 0534 else if(level<3) 0535 return isMenuitem(gtk_widget_get_parent(w), level++); 0536 } 0537 0538 return false; 0539 } 0540 0541 bool isMenuWindow(GtkWidget *w) 0542 { 0543 GtkWidget *def = gtk_window_get_default_widget(GTK_WINDOW(w)); 0544 0545 return def && GTK_IS_MENU(def); 0546 } 0547 0548 bool isInGroupBox(GtkWidget *w, int level) 0549 { 0550 if(w) 0551 { 0552 if(IS_GROUP_BOX(w)) 0553 return true; 0554 else if(level<5) 0555 return isInGroupBox(gtk_widget_get_parent(w), level++); 0556 } 0557 0558 return false; 0559 } 0560 0561 bool isOnButton(GtkWidget *w, int level, bool *def) 0562 { 0563 if (w) { 0564 if ((GTK_IS_BUTTON(w) || GTK_IS_OPTION_MENU(w)) && 0565 (!(GTK_IS_RADIO_BUTTON(w) || GTK_IS_CHECK_BUTTON(w)))) { 0566 if (def) { 0567 *def = gtk_widget_has_default(w); 0568 } 0569 return true; 0570 } else if (level < 3) { 0571 return isOnButton(gtk_widget_get_parent(w), level++, def); 0572 } 0573 } 0574 return false; 0575 } 0576 0577 static GtkRequisition defaultOptionIndicatorSize = {6, 13}; 0578 static GtkBorder defaultOptionIndicatorSpacing = {7, 5, 1, 1}; 0579 0580 void 0581 optionMenuGetProps(GtkWidget *widget, GtkRequisition *indicator_size, 0582 GtkBorder *indicator_spacing) 0583 { 0584 GtkRequisition *tmp_size = nullptr; 0585 GtkBorder *tmp_spacing = nullptr; 0586 0587 if (widget) 0588 gtk_widget_style_get(widget, "indicator_size", &tmp_size, 0589 "indicator_spacing", &tmp_spacing, 0590 nullptr); 0591 *indicator_size= tmp_size ? *tmp_size : defaultOptionIndicatorSize; 0592 *indicator_spacing = (tmp_spacing ? *tmp_spacing : 0593 defaultOptionIndicatorSpacing); 0594 0595 if (tmp_size) { 0596 gtk_requisition_free(tmp_size); 0597 } 0598 if (tmp_spacing) { 0599 gtk_border_free(tmp_spacing); 0600 } 0601 } 0602 0603 EStepper 0604 getStepper(GtkWidget *widget, int x, int y, int width, int height) 0605 { 0606 if (widget && GTK_IS_RANGE(widget)) { 0607 const QtcRect stepper = {x, y, width, height}; 0608 GtkOrientation orientation = Widget::getOrientation(widget); 0609 QtcRect alloc = Widget::getAllocation(widget); 0610 QtcRect check_rectangle = {alloc.x, alloc.y, 0611 stepper.width, stepper.height}; 0612 0613 if (alloc.x == -1 && alloc.y == -1) { 0614 return STEPPER_NONE; 0615 } 0616 if (Rect::intersect(&stepper, &check_rectangle, nullptr)) { 0617 return STEPPER_A; 0618 } 0619 0620 if (orientation == GTK_ORIENTATION_HORIZONTAL) { 0621 check_rectangle.x = alloc.x + stepper.width; 0622 } else { 0623 check_rectangle.y = alloc.y + stepper.height; 0624 } 0625 if (Rect::intersect(&stepper, &check_rectangle, nullptr)) { 0626 return STEPPER_B; 0627 } 0628 0629 if (orientation == GTK_ORIENTATION_HORIZONTAL) { 0630 check_rectangle.x = alloc.x + alloc.width - stepper.width * 2; 0631 } else { 0632 check_rectangle.y = alloc.y + alloc.height - stepper.height * 2; 0633 } 0634 if (Rect::intersect(&stepper, &check_rectangle, nullptr)) { 0635 return STEPPER_C; 0636 } 0637 0638 if (orientation == GTK_ORIENTATION_HORIZONTAL) { 0639 check_rectangle.x = alloc.x + alloc.width - stepper.width; 0640 } else { 0641 check_rectangle.y = alloc.y + alloc.height - stepper.height; 0642 } 0643 if (Rect::intersect(&stepper, &check_rectangle, nullptr)) { 0644 return STEPPER_D; 0645 } 0646 } 0647 return STEPPER_NONE; 0648 } 0649 0650 #if GTK_CHECK_VERSION(2, 90, 0) 0651 void gdk_drawable_get_size(GdkWindow *window, int *width, int *height) 0652 { 0653 *width = gdk_window_get_width(window); 0654 *height = gdk_window_get_height(window); 0655 } 0656 0657 void sanitizeSizeReal(GtkWidget *widget, int *width, int *height) 0658 { 0659 if (*width == -1 || *height == -1) { 0660 GdkWindow *window = gtk_widget_get_window(widget); 0661 if (window) { 0662 if (*width == -1) { 0663 *width = gdk_window_get_width(window); 0664 } 0665 if (*height == -1) { 0666 *height = gdk_window_get_height(window); 0667 } 0668 } 0669 } 0670 } 0671 #else 0672 void sanitizeSize(GdkWindow *window, int *width, int *height) 0673 { 0674 if (*width == -1 && *height == -1) { 0675 gdk_window_get_size(window, width, height); 0676 } else if (*width == -1) { 0677 gdk_window_get_size(window, width, nullptr); 0678 } else if (*height == -1) { 0679 gdk_window_get_size(window, nullptr, height); 0680 } 0681 } 0682 #endif 0683 0684 int 0685 getFill(GtkStateType state, bool set, bool darker) 0686 { 0687 if (state == GTK_STATE_INSENSITIVE) { 0688 return darker ? 2 : ORIGINAL_SHADE; 0689 } else if (state == GTK_STATE_PRELIGHT) { 0690 if (set) { 0691 return darker ? 3 : SHADE_4_HIGHLIGHT; 0692 } else { 0693 return darker ? SHADE_2_HIGHLIGHT : SHADE_ORIG_HIGHLIGHT; 0694 } 0695 } else if (set || state == GTK_STATE_ACTIVE) { 0696 return darker ? 5 : 4; 0697 } else { 0698 return darker ? 2 : ORIGINAL_SHADE; 0699 } 0700 } 0701 0702 bool 0703 isSbarDetail(const char *detail) 0704 { 0705 return (detail && detail[0] && (oneOf(detail, "stepper") || 0706 Str::startsWith(detail + 1, "scrollbar"))); 0707 } 0708 0709 ECornerBits 0710 getRound(const char *detail, GtkWidget *widget, bool rev) 0711 { 0712 if (detail) { 0713 if (oneOf(detail, "slider")) { 0714 #ifndef SIMPLE_SCROLLBARS 0715 if (!(opts.square & SQUARE_SB_SLIDER) && 0716 (opts.scrollbarType == SCROLLBAR_NONE || 0717 opts.flatSbarButtons)) { 0718 return ROUNDED_ALL; 0719 } 0720 #endif 0721 return ROUNDED_NONE; 0722 } else if (oneOf(detail, "qtc-slider")) { 0723 return opts.square&SQUARE_SLIDER && (SLIDER_PLAIN == opts.sliderStyle || SLIDER_PLAIN_ROTATED == opts.sliderStyle) 0724 ? ROUNDED_NONE : ROUNDED_ALL; 0725 } else if (oneOf(detail, "splitter", "optionmenu", "togglebutton", 0726 "hscale", "vscale")) { 0727 return ROUNDED_ALL; 0728 } else if (oneOf(detail, "spinbutton_up")) 0729 return rev ? ROUNDED_TOPLEFT : ROUNDED_TOPRIGHT; 0730 else if(oneOf(detail, "spinbutton_down")) 0731 return rev ? ROUNDED_BOTTOMLEFT : ROUNDED_BOTTOMRIGHT; 0732 else if (isSbarDetail(detail)) { 0733 // Requires `GtkRange::stepper-position-details = 1` 0734 if (Str::endsWith(detail, "_start")) { 0735 return detail[0] == 'h' ? ROUNDED_LEFT : ROUNDED_TOP; 0736 } else if (Str::endsWith(detail, "_end")) { 0737 return detail[0] == 'v' ? ROUNDED_BOTTOM : ROUNDED_RIGHT; 0738 } 0739 return ROUNDED_NONE; 0740 } else if (oneOf(detail, "button")) { 0741 if(isListViewHeader(widget)) 0742 return ROUNDED_NONE; 0743 else if(isComboBoxButton(widget)) 0744 return rev ? ROUNDED_LEFT : ROUNDED_RIGHT; 0745 else 0746 return ROUNDED_ALL; 0747 } 0748 } 0749 0750 return ROUNDED_NONE; 0751 } 0752 0753 bool 0754 isHorizontalProgressbar(GtkWidget *widget) 0755 { 0756 if (!widget || isMozilla() || !GTK_IS_PROGRESS_BAR(widget)) 0757 return true; 0758 #if GTK_CHECK_VERSION(2, 90, 0) 0759 return Widget::isHorizontal(widget); 0760 #else 0761 switch (GTK_PROGRESS_BAR(widget)->orientation) { 0762 default: 0763 case GTK_PROGRESS_LEFT_TO_RIGHT: 0764 case GTK_PROGRESS_RIGHT_TO_LEFT: 0765 return true; 0766 case GTK_PROGRESS_BOTTOM_TO_TOP: 0767 case GTK_PROGRESS_TOP_TO_BOTTOM: 0768 return false; 0769 } 0770 #endif 0771 } 0772 0773 bool 0774 isComboBoxPopupWindow(GtkWidget *widget, int level) 0775 { 0776 if (widget) { 0777 if (GTK_IS_WINDOW(widget) && oneOf(gtk_widget_get_name(widget), 0778 "gtk-combobox-popup-window")) { 0779 return true; 0780 } else if (level < 4) { 0781 return isComboBoxPopupWindow(gtk_widget_get_parent(widget), 0782 level + 1); 0783 } 0784 } 0785 return false; 0786 } 0787 0788 bool isComboBoxList(GtkWidget *widget) 0789 { 0790 GtkWidget *parent=nullptr; 0791 return widget && (parent=gtk_widget_get_parent(widget)) && /*GTK_IS_FRAME(widget) && */isComboBoxPopupWindow(parent, 0); 0792 } 0793 0794 bool 0795 isComboPopupWindow(GtkWidget *widget, int level) 0796 { 0797 if (widget) { 0798 if (GTK_IS_WINDOW(widget) && oneOf(gtk_widget_get_name(widget), 0799 "gtk-combo-popup-window")) { 0800 return true; 0801 } else if (level < 4) { 0802 return isComboPopupWindow(gtk_widget_get_parent(widget), level + 1); 0803 } 0804 } 0805 return false; 0806 } 0807 0808 bool isComboList(GtkWidget *widget) 0809 { 0810 return widget && isComboPopupWindow(gtk_widget_get_parent(widget), 0); 0811 } 0812 0813 bool 0814 isComboMenu(GtkWidget *widget) 0815 { 0816 if (widget && gtk_widget_get_name(widget) && GTK_IS_MENU(widget) && 0817 oneOf(gtk_widget_get_name(widget), "gtk-combobox-popup-menu")) { 0818 return true; 0819 } else { 0820 GtkWidget *top = gtk_widget_get_toplevel(widget); 0821 GtkWidget *topChild = top ? gtk_bin_get_child(GTK_BIN(top)) : nullptr; 0822 GtkWidget *transChild = nullptr; 0823 GtkWindow *trans = nullptr; 0824 0825 return (topChild && 0826 (isComboBoxPopupWindow(topChild, 0) || 0827 (GTK_IS_WINDOW(top) && 0828 (trans = gtk_window_get_transient_for(GTK_WINDOW(top))) && 0829 (transChild = gtk_bin_get_child(GTK_BIN(trans))) && 0830 isComboMenu(transChild)))); 0831 } 0832 } 0833 0834 bool isComboFrame(GtkWidget *widget) 0835 { 0836 GtkWidget *parent=nullptr; 0837 return !QTC_COMBO_ENTRY(widget) && GTK_IS_FRAME(widget) && (parent=gtk_widget_get_parent(widget)) && GTK_IS_COMBO_BOX(parent); 0838 } 0839 0840 bool isFixedWidget(GtkWidget *widget) 0841 { 0842 GtkWidget *parent = nullptr; 0843 return (widget && (parent = gtk_widget_get_parent(widget)) && 0844 GTK_IS_FIXED(parent) && 0845 (parent = gtk_widget_get_parent(parent)) && GTK_IS_WINDOW(parent)); 0846 } 0847 0848 bool isGimpDockable(GtkWidget *widget) 0849 { 0850 if (qtSettings.app == GTK_APP_GIMP) { 0851 for (GtkWidget *wid = widget;wid;wid = gtk_widget_get_parent(wid)) { 0852 if (oneOf(gTypeName(wid), "GimpDockable", "GimpToolbox")) { 0853 return true; 0854 } 0855 } 0856 } 0857 return false; 0858 } 0859 0860 GdkColor* 0861 getParentBgCol(GtkWidget *widget) 0862 { 0863 if (GTK_IS_SCROLLBAR(widget)) { 0864 widget = gtk_widget_get_parent(widget); 0865 } 0866 if (widget) { 0867 widget = gtk_widget_get_parent(widget); 0868 while (widget && GTK_IS_BOX(widget)) { 0869 widget = gtk_widget_get_parent(widget); 0870 } 0871 } 0872 0873 GtkStyle *style = widget ? gtk_widget_get_style(widget) : nullptr; 0874 return style ? &style->bg[gtk_widget_get_state(widget)] : nullptr; 0875 } 0876 0877 int 0878 getOpacity(GtkWidget *widget) 0879 { 0880 if (opts.bgndOpacity == opts.dlgOpacity) 0881 return opts.bgndOpacity; 0882 0883 if (opts.bgndOpacity != 100 || opts.dlgOpacity != 100) { 0884 if (!widget) { 0885 return opts.bgndOpacity; 0886 } else { 0887 GtkWidget *top = gtk_widget_get_toplevel(widget); 0888 return (top && GTK_IS_DIALOG(top) ? opts.dlgOpacity : 0889 opts.bgndOpacity); 0890 } 0891 } 0892 return 100; 0893 } 0894 0895 void setLowerEtchCol(cairo_t *cr, GtkWidget *widget) 0896 { 0897 if(USE_CUSTOM_ALPHAS(opts)) 0898 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, opts.customAlphas[ALPHA_ETCH_LIGHT]); 0899 else if(qtcIsFlatBgnd(opts.bgndAppearance) && (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint"))) 0900 { 0901 GdkColor *parentBg=getParentBgCol(widget); 0902 0903 if (parentBg) { 0904 GdkColor col; 0905 qtcShade(parentBg, &col, 1.06, opts.shading); 0906 Cairo::setColor(cr, &col); 0907 } else { 0908 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.1); // 0.25); 0909 } 0910 } else { 0911 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.1); // 0.4); 0912 } 0913 } 0914 0915 GdkColor 0916 shadeColor(const GdkColor *orig, double mod) 0917 { 0918 if (!qtcEqual(mod, 0.0)) { 0919 GdkColor modified; 0920 qtcShade(orig, &modified, mod, opts.shading); 0921 return modified; 0922 } 0923 return *orig; 0924 } 0925 0926 gboolean 0927 windowEvent(GtkWidget*, GdkEvent *event, void *user_data) 0928 { 0929 if (GDK_FOCUS_CHANGE == event->type) 0930 gtk_widget_queue_draw((GtkWidget*)user_data); 0931 return false; 0932 } 0933 0934 void 0935 adjustToolbarButtons(GtkWidget *widget, int *x, int *y, int *width, 0936 int *height, ECornerBits *round, bool horiz) 0937 { 0938 GtkToolbar *toolbar = nullptr; 0939 GtkToolItem *toolitem = nullptr; 0940 GtkWidget *w = widget; 0941 0942 for (int i = 0;i < 5 && w && (!toolbar || !toolitem);++i) { 0943 if (GTK_IS_TOOLBAR(w)) { 0944 toolbar = GTK_TOOLBAR(w); 0945 } else if (GTK_IS_TOOL_ITEM(w)) { 0946 toolitem = GTK_TOOL_ITEM(w); 0947 } 0948 w = gtk_widget_get_parent(w); 0949 } 0950 0951 if (toolbar && toolitem) { 0952 int num = gtk_toolbar_get_n_items(toolbar); 0953 if (num > 1) { 0954 int index = gtk_toolbar_get_item_index(toolbar, toolitem); 0955 GtkToolItem *prev = 0956 (index ? gtk_toolbar_get_nth_item(toolbar, index - 1) : nullptr); 0957 GtkToolItem *next = 0958 (index < num - 1 ? 0959 gtk_toolbar_get_nth_item(toolbar, index + 1) : nullptr); 0960 GtkWidget *parent = nullptr; 0961 bool roundLeft = !prev || !GTK_IS_TOOL_BUTTON(prev); 0962 bool roundRight = !next || !GTK_IS_TOOL_BUTTON(next); 0963 bool isMenuButton = 0964 (widget && GTK_IS_BUTTON(widget) && 0965 (parent = gtk_widget_get_parent(widget)) && 0966 GTK_IS_BOX(parent) && 0967 (parent = gtk_widget_get_parent(parent)) && 0968 GTK_IS_MENU_TOOL_BUTTON(parent)); 0969 bool isArrowButton = isMenuButton && GTK_IS_TOGGLE_BUTTON(widget); 0970 int *pos = horiz ? x : y; 0971 int *size = horiz ? width : height; 0972 0973 if (isArrowButton) { 0974 *pos -= 4; 0975 if (roundLeft && roundRight) { 0976 *round = horiz ? ROUNDED_RIGHT : ROUNDED_BOTTOM; 0977 *size += 4; 0978 } else if (roundLeft) { 0979 *round = ROUNDED_NONE; 0980 *size += 8; 0981 } else if (roundRight) { 0982 *round = horiz ? ROUNDED_RIGHT : ROUNDED_BOTTOM; 0983 *size += 4; 0984 } else { 0985 *round = ROUNDED_NONE; 0986 *size += 8; 0987 } 0988 } else if (isMenuButton) { 0989 if (roundLeft && roundRight) { 0990 *round = horiz ? ROUNDED_LEFT : ROUNDED_TOP; 0991 *size += 4; 0992 } else if (roundLeft) { 0993 *round = horiz ? ROUNDED_LEFT : ROUNDED_TOP; 0994 *size += 4; 0995 } else if(roundRight) { 0996 *round = ROUNDED_NONE; 0997 *pos -= 4; 0998 *size += 8; 0999 } else { 1000 *round = ROUNDED_NONE; 1001 *pos -= 4; 1002 *size += 8; 1003 } 1004 } else if (roundLeft && roundRight) { 1005 } else if (roundLeft) { 1006 *round = horiz ? ROUNDED_LEFT : ROUNDED_TOP; 1007 *size += 4; 1008 } else if (roundRight) { 1009 *round = horiz ? ROUNDED_RIGHT : ROUNDED_BOTTOM; 1010 *pos -= 4; 1011 *size += 4; 1012 } else { 1013 *round = ROUNDED_NONE; 1014 *pos -= 4; 1015 *size += 8; 1016 } 1017 } 1018 } 1019 } 1020 1021 void 1022 getEntryParentBgCol(GtkWidget *widget, GdkColor *color) 1023 { 1024 GtkWidget *parent = nullptr; 1025 GtkStyle *style = nullptr; 1026 1027 if (!widget) { 1028 color->red = color->green = color->blue = 65535; 1029 return; 1030 } 1031 parent = gtk_widget_get_parent(widget); 1032 while (parent && !gtk_widget_get_has_window(parent)) { 1033 GtkStyle *style = nullptr; 1034 if (opts.tabBgnd && GTK_IS_NOTEBOOK(parent) && 1035 (style = gtk_widget_get_style(parent))) { 1036 qtcShade(&style->bg[GTK_STATE_NORMAL], color, 1037 TO_FACTOR(opts.tabBgnd), opts.shading); 1038 return; 1039 } 1040 parent = gtk_widget_get_parent(parent); 1041 } 1042 if (!parent) { 1043 parent = widget; 1044 } 1045 if ((style = gtk_widget_get_style(parent))) { 1046 *color = style->bg[gtk_widget_get_state(parent)]; 1047 } 1048 } 1049 1050 bool 1051 compositingActive(GtkWidget *widget) 1052 { 1053 GdkScreen *screen = (widget ? gtk_widget_get_screen(widget) : 1054 gdk_screen_get_default()); 1055 return screen && gdk_screen_is_composited(screen); 1056 } 1057 1058 bool 1059 isRgbaWidget(GtkWidget *widget) 1060 { 1061 if (widget) { 1062 GdkVisual *visual = gtk_widget_get_visual(widget); 1063 return gdk_visual_get_depth(visual) == 32; 1064 } 1065 return false; 1066 } 1067 1068 void 1069 enableBlurBehind(GtkWidget *w, bool enable) 1070 { 1071 GtkWindow *topLevel = GTK_WINDOW(gtk_widget_get_toplevel(w)); 1072 if (topLevel) { 1073 GtkWidgetProps props(w); 1074 int oldValue = props->blurBehind; 1075 if (oldValue == 0 || (enable && oldValue != 1) || 1076 (!enable && oldValue != 2)) { 1077 props->blurBehind = enable ? 1 : 2; 1078 xcb_window_t wid = 1079 GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(topLevel))); 1080 qtcX11BlurTrigger(wid, enable, 0, nullptr); 1081 } 1082 } 1083 } 1084 1085 void 1086 getTopLevelSize(GdkWindow *window, int *w, int *h) 1087 { 1088 if (!(window && GDK_IS_WINDOW(window))) { 1089 qtcAssign(w, -1); 1090 qtcAssign(h, -1); 1091 } else { 1092 GdkWindow *topLevel = gdk_window_get_toplevel(window); 1093 if (topLevel) { 1094 gdk_drawable_get_size(topLevel, w, h); 1095 } else { 1096 gdk_drawable_get_size(window, w, h); 1097 } 1098 } 1099 } 1100 1101 void 1102 getTopLevelOrigin(GdkWindow *window, int *x, int *y) 1103 { 1104 qtcAssign(x, 0); 1105 qtcAssign(y, 0); 1106 if (window) { 1107 while(window && GDK_IS_WINDOW(window) && 1108 gdk_window_get_window_type(window) != GDK_WINDOW_TOPLEVEL && 1109 gdk_window_get_window_type(window) != GDK_WINDOW_TEMP) { 1110 int xloc; 1111 int yloc; 1112 gdk_window_get_position(window, &xloc, &yloc); 1113 qtcAssign(x, *x + xloc); 1114 qtcAssign(y, *y + yloc); 1115 window = gdk_window_get_parent(window); 1116 } 1117 } 1118 } 1119 1120 bool 1121 mapToTopLevel(GdkWindow *window, GtkWidget *widget, 1122 int *x, int *y, int *w, int *h) 1123 { 1124 // always initialize arguments (to invalid values) 1125 qtcAssign(x, 0); 1126 qtcAssign(y, 0); 1127 int _w; 1128 int _h; 1129 w = qtcDefault(w, &_w); 1130 h = qtcDefault(h, &_h); 1131 *w = -1; 1132 *h = -1; 1133 if (!(window && GDK_IS_WINDOW(window))) { 1134 if (widget) { 1135 int xlocal; 1136 int ylocal; 1137 // this is an alternative way to get widget position with respect to 1138 // top level window and top level window size. This is used in case 1139 // the GdkWindow passed as argument is actually a 'non window' 1140 // drawable 1141 window = gtk_widget_get_parent_window(widget); 1142 getTopLevelSize(window, w, h); 1143 if (gtk_widget_translate_coordinates( 1144 widget, gtk_widget_get_toplevel(widget), 0, 0, 1145 &xlocal, &ylocal)) { 1146 qtcAssign(x, xlocal); 1147 qtcAssign(y, ylocal); 1148 return *w > 0 && *h > 0; 1149 } 1150 } 1151 } else { 1152 // get window size and height 1153 getTopLevelSize(window, w, h); 1154 getTopLevelOrigin(window, x, y); 1155 return *w > 0 && *h > 0; 1156 } 1157 return false; 1158 } 1159 1160 bool 1161 treeViewCellHasChildren(GtkTreeView *treeView, GtkTreePath *path) 1162 { 1163 // check treeview and path 1164 if (treeView && path) { 1165 GtkTreeModel *model = gtk_tree_view_get_model(treeView); 1166 if (model) { 1167 GtkTreeIter iter; 1168 if (gtk_tree_model_get_iter(model, &iter, path)) { 1169 return gtk_tree_model_iter_has_child(model, &iter); 1170 } 1171 } 1172 } 1173 return false; 1174 } 1175 1176 bool 1177 treeViewCellIsLast(GtkTreeView *treeView, GtkTreePath *path) 1178 { 1179 // check treeview and path 1180 if (treeView && path) { 1181 GtkTreeModel *model = gtk_tree_view_get_model(treeView); 1182 if (model) { 1183 GtkTreeIter iter; 1184 if (gtk_tree_model_get_iter(model, &iter, path)) { 1185 return !gtk_tree_model_iter_next(model, &iter); 1186 } 1187 } 1188 } 1189 return false; 1190 } 1191 1192 GtkTreePath* 1193 treeViewPathParent(GtkTreeView*, GtkTreePath *path) 1194 { 1195 if (path) { 1196 GtkTreePath *parent = gtk_tree_path_copy(path); 1197 if (gtk_tree_path_up(parent)) { 1198 return parent; 1199 } else { 1200 gtk_tree_path_free(parent); 1201 } 1202 } 1203 return nullptr; 1204 } 1205 1206 void 1207 generateColors() 1208 { 1209 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW], 1210 qtcPalette.background); 1211 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_BUTTON], 1212 qtcPalette.button[PAL_ACTIVE]); 1213 shadeColors(&qtSettings.colors[PAL_DISABLED][COLOR_BUTTON], 1214 qtcPalette.button[PAL_DISABLED]); 1215 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED], 1216 qtcPalette.highlight); 1217 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_FOCUS], 1218 qtcPalette.focus); 1219 switch (opts.shadeMenubars) { 1220 case SHADE_WINDOW_BORDER: 1221 qtcPalette.wborder[0] = qtcNew(GdkColor, TOTAL_SHADES + 1); 1222 qtcPalette.wborder[1] = qtcNew(GdkColor, TOTAL_SHADES + 1); 1223 shadeColors(&qtSettings.colors[PAL_INACTIVE][COLOR_WINDOW_BORDER], 1224 qtcPalette.wborder[0]); 1225 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER], 1226 qtcPalette.wborder[1]); 1227 break; 1228 case SHADE_NONE: 1229 memcpy(qtcPalette.menubar, qtcPalette.background, 1230 sizeof(GdkColor) * (TOTAL_SHADES + 1)); 1231 break; 1232 case SHADE_BLEND_SELECTED: { 1233 GdkColor mid = midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1234 &qtcPalette.background[ORIGINAL_SHADE]); 1235 shadeColors(&mid, qtcPalette.menubar); 1236 break; 1237 } 1238 case SHADE_SELECTED: { 1239 GdkColor color; 1240 if (IS_GLASS(opts.appearance)) { 1241 qtcShade(&qtcPalette.highlight[ORIGINAL_SHADE], &color, 1242 MENUBAR_GLASS_SELECTED_DARK_FACTOR, opts.shading); 1243 } else { 1244 color = qtcPalette.highlight[ORIGINAL_SHADE]; 1245 } 1246 shadeColors(&color, qtcPalette.menubar); 1247 break; 1248 } 1249 case SHADE_CUSTOM: 1250 shadeColors(&opts.customMenubarsColor, qtcPalette.menubar); 1251 break; 1252 case SHADE_DARKEN: { 1253 GdkColor color; 1254 qtcShade(&qtcPalette.background[ORIGINAL_SHADE], &color, 1255 MENUBAR_DARK_FACTOR, opts.shading); 1256 shadeColors(&color, qtcPalette.menubar); 1257 break; 1258 } 1259 } 1260 switch (opts.shadeSliders) { 1261 case SHADE_SELECTED: 1262 qtcPalette.slider = qtcPalette.highlight; 1263 break; 1264 case SHADE_CUSTOM: 1265 qtcPalette.slider = qtcNew(GdkColor, TOTAL_SHADES + 1); 1266 shadeColors(&opts.customSlidersColor, qtcPalette.slider); 1267 break; 1268 case SHADE_BLEND_SELECTED: { 1269 GdkColor mid = midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1270 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE]); 1271 qtcPalette.slider = qtcNew(GdkColor, TOTAL_SHADES + 1); 1272 shadeColors(&mid, qtcPalette.slider); 1273 } 1274 default: 1275 break; 1276 } 1277 qtcPalette.combobtn = nullptr; 1278 switch (opts.comboBtn) { 1279 case SHADE_SELECTED: 1280 qtcPalette.combobtn = qtcPalette.highlight; 1281 break; 1282 case SHADE_CUSTOM: 1283 if (opts.shadeSliders == SHADE_CUSTOM && 1284 EQUAL_COLOR(opts.customSlidersColor, opts.customComboBtnColor)) { 1285 qtcPalette.combobtn = qtcPalette.slider; 1286 } else { 1287 qtcPalette.combobtn = qtcNew(GdkColor, TOTAL_SHADES + 1); 1288 shadeColors(&opts.customComboBtnColor, qtcPalette.combobtn); 1289 } 1290 break; 1291 case SHADE_BLEND_SELECTED: 1292 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1293 qtcPalette.combobtn = qtcPalette.slider; 1294 } else { 1295 GdkColor mid = 1296 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1297 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE]); 1298 qtcPalette.combobtn = qtcNew(GdkColor, TOTAL_SHADES + 1); 1299 shadeColors(&mid, qtcPalette.combobtn); 1300 } 1301 default: 1302 break; 1303 } 1304 qtcPalette.sortedlv = nullptr; 1305 switch (opts.sortedLv) { 1306 case SHADE_DARKEN: { 1307 GdkColor color; 1308 qtcPalette.sortedlv = qtcNew(GdkColor, TOTAL_SHADES + 1); 1309 qtcShade(opts.lvButton ? 1310 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE] : 1311 &qtcPalette.background[ORIGINAL_SHADE], 1312 &color, LV_HEADER_DARK_FACTOR, opts.shading); 1313 shadeColors(&color, qtcPalette.sortedlv); 1314 break; 1315 } 1316 case SHADE_SELECTED: 1317 qtcPalette.sortedlv = qtcPalette.highlight; 1318 break; 1319 case SHADE_CUSTOM: 1320 if (opts.shadeSliders == SHADE_CUSTOM && 1321 EQUAL_COLOR(opts.customSlidersColor, opts.customSortedLvColor)) { 1322 qtcPalette.sortedlv = qtcPalette.slider; 1323 } else if (opts.comboBtn == SHADE_CUSTOM && 1324 EQUAL_COLOR(opts.customComboBtnColor, 1325 opts.customSortedLvColor)) { 1326 qtcPalette.sortedlv = qtcPalette.combobtn; 1327 } else { 1328 qtcPalette.sortedlv = qtcNew(GdkColor, TOTAL_SHADES + 1); 1329 shadeColors(&opts.customSortedLvColor, qtcPalette.sortedlv); 1330 } 1331 break; 1332 case SHADE_BLEND_SELECTED: 1333 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1334 qtcPalette.sortedlv = qtcPalette.slider; 1335 } else if (opts.comboBtn == SHADE_BLEND_SELECTED) { 1336 qtcPalette.sortedlv=qtcPalette.combobtn; 1337 } else { 1338 GdkColor mid = 1339 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], opts.lvButton ? 1340 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE] : 1341 &qtcPalette.background[ORIGINAL_SHADE]); 1342 qtcPalette.sortedlv = qtcNew(GdkColor, TOTAL_SHADES + 1); 1343 shadeColors(&mid, qtcPalette.sortedlv); 1344 } 1345 default: 1346 break; 1347 } 1348 switch (opts.defBtnIndicator) { 1349 case IND_TINT: { 1350 GdkColor col = tint(&qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE], 1351 &qtcPalette.highlight[ORIGINAL_SHADE], 1352 DEF_BNT_TINT); 1353 qtcPalette.defbtn = qtcNew(GdkColor, TOTAL_SHADES + 1); 1354 shadeColors(&col, qtcPalette.defbtn); 1355 break; 1356 } 1357 case IND_GLOW: 1358 case IND_SELECTED: 1359 qtcPalette.defbtn = qtcPalette.highlight; 1360 break; 1361 default: 1362 break; 1363 case IND_COLORED: 1364 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1365 qtcPalette.defbtn = qtcPalette.slider; 1366 } else { 1367 GdkColor mid = 1368 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1369 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE]); 1370 qtcPalette.defbtn = qtcNew(GdkColor, TOTAL_SHADES + 1); 1371 shadeColors(&mid, qtcPalette.defbtn); 1372 } 1373 } 1374 1375 if (opts.coloredMouseOver) { 1376 qtcPalette.mouseover = qtcNew(GdkColor, TOTAL_SHADES + 1); 1377 shadeColors(&qtSettings.colors[PAL_ACTIVE][COLOR_HOVER], 1378 qtcPalette.mouseover); 1379 } 1380 1381 switch (opts.shadeCheckRadio) { 1382 default: 1383 qtcPalette.check_radio = 1384 &qtSettings.colors[PAL_ACTIVE][opts.crButton ? 1385 COLOR_BUTTON_TEXT : COLOR_TEXT]; 1386 break; 1387 case SHADE_BLEND_SELECTED: 1388 case SHADE_SELECTED: 1389 qtcPalette.check_radio = &qtSettings.colors[PAL_ACTIVE][COLOR_SELECTED]; 1390 break; 1391 case SHADE_CUSTOM: 1392 qtcPalette.check_radio = &opts.customCheckRadioColor; 1393 } 1394 1395 { 1396 GdkColor color; 1397 GdkColor *cols = (opts.shadePopupMenu ? menuColors(true) : 1398 qtcPalette.background); 1399 if (opts.lighterPopupMenuBgnd) { 1400 qtcShade(&cols[ORIGINAL_SHADE], &color, 1401 TO_FACTOR(opts.lighterPopupMenuBgnd), opts.shading); 1402 } else { 1403 color = cols[ORIGINAL_SHADE]; 1404 } 1405 shadeColors(&color, qtcPalette.menu); 1406 } 1407 1408 /* Tear off menu items dont seem to draw they're background, and the 1409 * default background is drawn :-( Fix/hack this by making that 1410 * background the correct color */ 1411 if (opts.lighterPopupMenuBgnd || opts.shadePopupMenu) { 1412 static const char *format="style \"" RC_SETTING "Mnu\" { " 1413 "bg[NORMAL]=\"#%02X%02X%02X\" " 1414 "fg[NORMAL]=\"#%02X%02X%02X\" " 1415 "text[INSENSITIVE]=\"#%02X%02X%02X\" " 1416 "} class \"GtkMenu\" style \"" RC_SETTING "Mnu\" " 1417 "widget_class \"*Menu.*Label\" style \"" RC_SETTING "Mnu\"" 1418 " style \"" RC_SETTING "CView\" = \"" RC_SETTING "Mnu\" { text[NORMAL]=\"#%02X%02X%02X\" } " 1419 " widget_class \"*<GtkMenuItem>*<GtkCellView>\" style \"" RC_SETTING "CView\""; 1420 char *str = (char*)malloc(strlen(format) + 24 + 1); 1421 1422 if (str) { 1423 GdkColor *col = &qtcPalette.menu[ORIGINAL_SHADE]; 1424 GdkColor text = opts.shadePopupMenu ? SHADE_WINDOW_BORDER == opts.shadeMenubars 1425 ? qtSettings.colors[PAL_ACTIVE][COLOR_WINDOW_BORDER_TEXT] 1426 : opts.customMenuTextColor 1427 ? opts.customMenuNormTextColor 1428 : SHADE_BLEND_SELECTED == opts.shadeMenubars || SHADE_SELECTED == opts.shadeMenubars || 1429 (SHADE_CUSTOM == opts.shadeMenubars && TOO_DARK(qtcPalette.menubar[ORIGINAL_SHADE])) 1430 ? qtSettings.colors[PAL_ACTIVE][COLOR_TEXT_SELECTED] 1431 : qtSettings.colors[PAL_ACTIVE][COLOR_TEXT] 1432 : qtSettings.colors[PAL_ACTIVE][COLOR_TEXT], 1433 mid=opts.shadePopupMenu ? midColor(col, &text) : qtSettings.colors[PAL_DISABLED][COLOR_TEXT]; 1434 sprintf(str, format, toQtColor(col->red), toQtColor(col->green), toQtColor(col->blue), 1435 toQtColor(text.red), toQtColor(text.green), toQtColor(text.blue), 1436 toQtColor(mid.red), toQtColor(mid.green), toQtColor(mid.blue), 1437 toQtColor(text.red), toQtColor(text.green), toQtColor(text.blue)); 1438 gtk_rc_parse_string(str); 1439 free(str); 1440 } 1441 } 1442 1443 switch (opts.menuStripe) { 1444 default: 1445 case SHADE_NONE: 1446 opts.customMenuStripeColor = qtcPalette.background[ORIGINAL_SHADE]; 1447 break; 1448 case SHADE_DARKEN: 1449 opts.customMenuStripeColor = 1450 (opts.lighterPopupMenuBgnd || opts.shadePopupMenu ? 1451 qtcPalette.menu[ORIGINAL_SHADE] : 1452 qtcPalette.background[MENU_STRIPE_SHADE]); 1453 break; 1454 case SHADE_CUSTOM: 1455 break; 1456 case SHADE_BLEND_SELECTED: 1457 opts.customMenuStripeColor = 1458 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1459 opts.lighterPopupMenuBgnd || opts.shadePopupMenu ? 1460 &qtcPalette.menu[ORIGINAL_SHADE] : 1461 &qtcPalette.background[ORIGINAL_SHADE]); 1462 break; 1463 case SHADE_SELECTED: 1464 opts.customMenuStripeColor = qtcPalette.highlight[MENU_STRIPE_SHADE]; 1465 } 1466 1467 qtcPalette.selectedcr = nullptr; 1468 switch (opts.crColor) { 1469 case SHADE_DARKEN: { 1470 GdkColor color; 1471 qtcPalette.selectedcr = qtcNew(GdkColor, TOTAL_SHADES + 1); 1472 qtcShade(&qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE], &color, 1473 LV_HEADER_DARK_FACTOR, opts.shading); 1474 shadeColors(&color, qtcPalette.selectedcr); 1475 break; 1476 } 1477 default: 1478 case SHADE_NONE: 1479 qtcPalette.selectedcr = qtcPalette.button[PAL_ACTIVE]; 1480 break; 1481 case SHADE_SELECTED: 1482 qtcPalette.selectedcr = qtcPalette.highlight; 1483 break; 1484 case SHADE_CUSTOM: 1485 if (opts.shadeSliders == SHADE_CUSTOM && 1486 EQUAL_COLOR(opts.customSlidersColor, opts.customCrBgndColor)) { 1487 qtcPalette.selectedcr = qtcPalette.slider; 1488 } else if (opts.comboBtn == SHADE_CUSTOM && 1489 EQUAL_COLOR(opts.customComboBtnColor, 1490 opts.customCrBgndColor)) { 1491 qtcPalette.selectedcr = qtcPalette.combobtn; 1492 } else if (opts.sortedLv == SHADE_CUSTOM && 1493 EQUAL_COLOR(opts.customSortedLvColor, 1494 opts.customCrBgndColor)) { 1495 qtcPalette.selectedcr = qtcPalette.sortedlv; 1496 } else { 1497 qtcPalette.selectedcr = qtcNew(GdkColor, TOTAL_SHADES + 1); 1498 shadeColors(&opts.customCrBgndColor, qtcPalette.selectedcr); 1499 } 1500 break; 1501 case SHADE_BLEND_SELECTED: 1502 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1503 qtcPalette.selectedcr = qtcPalette.slider; 1504 } else if (opts.comboBtn == SHADE_BLEND_SELECTED) { 1505 qtcPalette.selectedcr = qtcPalette.combobtn; 1506 } else if (opts.sortedLv == SHADE_BLEND_SELECTED) { 1507 qtcPalette.selectedcr = qtcPalette.sortedlv; 1508 } else { 1509 GdkColor mid = 1510 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1511 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE]); 1512 qtcPalette.selectedcr = qtcNew(GdkColor, TOTAL_SHADES + 1); 1513 shadeColors(&mid, qtcPalette.selectedcr); 1514 } 1515 } 1516 1517 qtcPalette.sidebar = nullptr; 1518 if (!opts.stdSidebarButtons) { 1519 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1520 qtcPalette.sidebar = qtcPalette.slider; 1521 } else if (opts.defBtnIndicator == IND_COLORED) { 1522 qtcPalette.sidebar = qtcPalette.defbtn; 1523 } else { 1524 GdkColor mid = 1525 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1526 &qtcPalette.button[PAL_ACTIVE][ORIGINAL_SHADE]); 1527 qtcPalette.sidebar = qtcNew(GdkColor, TOTAL_SHADES + 1); 1528 shadeColors(&mid, qtcPalette.sidebar); 1529 } 1530 } 1531 1532 qtcPalette.progress = nullptr; 1533 switch (opts.progressColor) { 1534 case SHADE_NONE: 1535 qtcPalette.progress = qtcPalette.background; 1536 default: 1537 /* Not set! */ 1538 break; 1539 case SHADE_CUSTOM: 1540 if (opts.shadeSliders == SHADE_CUSTOM && 1541 EQUAL_COLOR(opts.customSlidersColor, opts.customProgressColor)) { 1542 qtcPalette.progress = qtcPalette.slider; 1543 } else if (opts.comboBtn == SHADE_CUSTOM && 1544 EQUAL_COLOR(opts.customComboBtnColor, 1545 opts.customProgressColor)) { 1546 qtcPalette.progress = qtcPalette.combobtn; 1547 } else if (opts.sortedLv == SHADE_CUSTOM && 1548 EQUAL_COLOR(opts.customSortedLvColor, 1549 opts.customProgressColor)) { 1550 qtcPalette.progress = qtcPalette.sortedlv; 1551 } else if (opts.crColor == SHADE_CUSTOM && 1552 EQUAL_COLOR(opts.customCrBgndColor, 1553 opts.customProgressColor)) { 1554 qtcPalette.progress = qtcPalette.selectedcr; 1555 } else { 1556 qtcPalette.progress = qtcNew(GdkColor, TOTAL_SHADES + 1); 1557 shadeColors(&opts.customProgressColor, qtcPalette.progress); 1558 } 1559 break; 1560 case SHADE_BLEND_SELECTED: 1561 if (opts.shadeSliders == SHADE_BLEND_SELECTED) { 1562 qtcPalette.progress = qtcPalette.slider; 1563 } else if (opts.comboBtn == SHADE_BLEND_SELECTED) { 1564 qtcPalette.progress = qtcPalette.combobtn; 1565 } else if (opts.sortedLv == SHADE_BLEND_SELECTED) { 1566 qtcPalette.progress = qtcPalette.sortedlv; 1567 } else if (opts.crColor == SHADE_BLEND_SELECTED) { 1568 qtcPalette.progress = qtcPalette.selectedcr; 1569 } else { 1570 GdkColor mid = 1571 midColor(&qtcPalette.highlight[ORIGINAL_SHADE], 1572 &qtcPalette.background[ORIGINAL_SHADE]); 1573 qtcPalette.progress = qtcNew(GdkColor, TOTAL_SHADES + 1); 1574 shadeColors(&mid, qtcPalette.progress); 1575 } 1576 } 1577 } 1578 1579 GdkColor* 1580 getCheckRadioCol(GtkStyle *style, GtkStateType state, bool mnu) 1581 { 1582 return (!qtSettings.qt4 && mnu ? &style->text[state] : 1583 state == GTK_STATE_INSENSITIVE ? 1584 &qtSettings.colors[PAL_DISABLED][opts.crButton ? COLOR_BUTTON_TEXT : 1585 COLOR_TEXT] : 1586 qtcPalette.check_radio); 1587 } 1588 1589 bool 1590 objectIsA(const GObject *object, const char *type_name) 1591 { 1592 if (object) { 1593 GType tmp = g_type_from_name(type_name); 1594 if (tmp) { 1595 return g_type_check_instance_is_a((GTypeInstance*)object, tmp); 1596 } 1597 } 1598 return false; 1599 } 1600 1601 }