File indexing completed on 2024-04-21 05:46:52
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 <stdarg.h> 0024 #include "common.h" 0025 0026 // DO NOT unconditionally include QT/GTK headers here 0027 0028 void 0029 qtcSetupGradient(Gradient *grad, EGradientBorder border, int numStops, ...) 0030 { 0031 va_list ap; 0032 int i; 0033 0034 grad->border = border; 0035 #ifndef QTC_UTILS_QT 0036 grad->numStops = numStops; 0037 grad->stops = qtcNew(GradientStop, numStops); 0038 #endif 0039 va_start(ap, numStops); 0040 for (i = 0;i < numStops;++i) { 0041 double pos = va_arg(ap, double); 0042 double val = va_arg(ap, double); 0043 #ifdef QTC_UTILS_QT 0044 grad->stops.insert(GradientStop(pos, val)); 0045 #else 0046 grad->stops[i].pos = pos; 0047 grad->stops[i].val = val; 0048 grad->stops[i].alpha = 1.0; 0049 #endif 0050 } 0051 va_end(ap); 0052 } 0053 0054 const Gradient* 0055 qtcGetGradient(EAppearance app, const Options *opts) 0056 { 0057 if (IS_CUSTOM(app)) { 0058 #ifdef QTC_UTILS_QT 0059 auto grad = opts->customGradient.find(app); 0060 0061 if (grad != opts->customGradient.end()) { 0062 return &grad->second; 0063 } 0064 #else 0065 Gradient *grad = opts->customGradient[app - APPEARANCE_CUSTOM1]; 0066 0067 if (grad) { 0068 return grad; 0069 } 0070 #endif 0071 app = APPEARANCE_RAISED; 0072 } 0073 0074 static Gradient stdGradients[NUM_STD_APP]; 0075 static bool init = false; 0076 0077 if (!init) { 0078 qtcSetupGradient(&stdGradients[APPEARANCE_FLAT - APPEARANCE_FLAT], 0079 GB_3D, 2, 0.0, 1.0, 1.0, 1.0); 0080 qtcSetupGradient(&stdGradients[APPEARANCE_RAISED - APPEARANCE_FLAT], 0081 GB_3D_FULL, 2, 0.0, 1.0, 1.0, 1.0); 0082 qtcSetupGradient(&stdGradients[APPEARANCE_DULL_GLASS - 0083 APPEARANCE_FLAT], GB_LIGHT, 4, 0.0, 0084 1.05, 0.499, 0.984, 0.5, 0.928, 0085 1.0, 1.0); 0086 qtcSetupGradient(&stdGradients[APPEARANCE_SHINY_GLASS - 0087 APPEARANCE_FLAT], GB_LIGHT, 4, 0.0, 0088 1.2, 0.499, 0.984, 0.5, 0.9, 0089 1.0, 1.06); 0090 qtcSetupGradient(&stdGradients[APPEARANCE_AGUA - APPEARANCE_FLAT], 0091 GB_SHINE, 2, 0.0, 0.6, 1.0, 1.1); 0092 qtcSetupGradient(&stdGradients[APPEARANCE_SOFT_GRADIENT - 0093 APPEARANCE_FLAT], GB_3D, 2, 0.0, 0094 1.04, 1.0, 0.98); 0095 qtcSetupGradient( 0096 &stdGradients[APPEARANCE_GRADIENT - APPEARANCE_FLAT], GB_3D, 2, 0097 0.0, 1.1, 1.0, 0.94); 0098 qtcSetupGradient(&stdGradients[APPEARANCE_HARSH_GRADIENT - 0099 APPEARANCE_FLAT], GB_3D, 2, 0.0, 1.3, 0100 1.0, 0.925); 0101 qtcSetupGradient( 0102 &stdGradients[APPEARANCE_INVERTED - APPEARANCE_FLAT], GB_3D, 2, 0103 0.0, 0.93, 1.0, 1.04); 0104 qtcSetupGradient(&stdGradients[APPEARANCE_DARK_INVERTED - 0105 APPEARANCE_FLAT], GB_NONE, 3, 0.0, 0106 0.8, 0.7, 0.95, 1.0, 1.0); 0107 qtcSetupGradient(&stdGradients[APPEARANCE_SPLIT_GRADIENT - 0108 APPEARANCE_FLAT], GB_3D, 4, 0.0, 0109 1.06, 0.499, 1.004, 0.5, 0.986, 0110 1.0, 0.92); 0111 qtcSetupGradient( 0112 &stdGradients[APPEARANCE_BEVELLED - APPEARANCE_FLAT], GB_3D, 4, 0113 0.0, 1.05, 0.1, 1.02, 0.9, 0.985, 1.0, 0.94); 0114 qtcSetupGradient(&stdGradients[APPEARANCE_LV_BEVELLED - 0115 APPEARANCE_FLAT], GB_3D, 3, 0.0, 0116 1.00, 0.85, 1.0, 1.0, 0.90); 0117 qtcSetupGradient( 0118 &stdGradients[APPEARANCE_AGUA_MOD - APPEARANCE_FLAT], GB_NONE, 0119 3, 0.0, 1.5, 0.49, 0.85, 1.0, 1.3); 0120 qtcSetupGradient( 0121 &stdGradients[APPEARANCE_LV_AGUA - APPEARANCE_FLAT], GB_NONE, 4, 0122 0.0, 0.98, 0.35, 0.95, 0.4, 0.93, 1.0, 1.15); 0123 init = true; 0124 } 0125 0126 return &stdGradients[app - APPEARANCE_FLAT]; 0127 } 0128 0129 EAppearance 0130 #ifdef QTC_UTILS_QT 0131 qtcWidgetApp(EWidget w, const Options *opts, bool active) 0132 #else 0133 qtcWidgetApp(EWidget w, const Options *opts) 0134 #endif 0135 { 0136 switch (w) { 0137 case WIDGET_SB_BGND: 0138 return opts->sbarBgndAppearance; 0139 case WIDGET_LISTVIEW_HEADER: 0140 return opts->lvAppearance; 0141 case WIDGET_SB_BUTTON: 0142 case WIDGET_SLIDER: 0143 case WIDGET_SB_SLIDER: 0144 return opts->sliderAppearance; 0145 case WIDGET_FILLED_SLIDER_TROUGH: 0146 return opts->sliderFill; 0147 case WIDGET_TAB_TOP: 0148 case WIDGET_TAB_BOT: 0149 return opts->tabAppearance; 0150 case WIDGET_MENU_ITEM: 0151 return opts->menuitemAppearance; 0152 case WIDGET_PROGRESSBAR: 0153 #ifndef QTC_UTILS_QT 0154 case WIDGET_ENTRY_PROGRESSBAR: 0155 #endif 0156 return opts->progressAppearance; 0157 case WIDGET_PBAR_TROUGH: 0158 return opts->progressGrooveAppearance; 0159 case WIDGET_SELECTION: 0160 return opts->selectionAppearance; 0161 #ifdef QTC_UTILS_QT 0162 case WIDGET_DOCK_WIDGET_TITLE: 0163 return opts->dwtAppearance; 0164 case WIDGET_MDI_WINDOW: 0165 case WIDGET_MDI_WINDOW_TITLE: 0166 return (active ? opts->titlebarAppearance : 0167 opts->inactiveTitlebarAppearance); 0168 case WIDGET_MDI_WINDOW_BUTTON: 0169 return opts->titlebarButtonAppearance; 0170 case WIDGET_DIAL: 0171 return qtcIsFlat(opts->appearance) ? APPEARANCE_RAISED : 0172 APPEARANCE_SOFT_GRADIENT; 0173 #endif 0174 case WIDGET_TROUGH: 0175 case WIDGET_SLIDER_TROUGH: 0176 return opts->grooveAppearance; 0177 #ifndef QTC_UTILS_QT 0178 case WIDGET_SPIN_UP: 0179 case WIDGET_SPIN_DOWN: 0180 #endif 0181 case WIDGET_SPIN: 0182 return MODIFY_AGUA(opts->appearance); 0183 case WIDGET_TOOLBAR_BUTTON: 0184 return (APPEARANCE_NONE == opts->tbarBtnAppearance ? 0185 opts->appearance : opts->tbarBtnAppearance); 0186 default: 0187 break; 0188 } 0189 return opts->appearance; 0190 } 0191 0192 #define CAN_EXTRA_ROUND(MOD) \ 0193 (QtCurve::isExtraRoundWidget(widget) && \ 0194 (IS_SLIDER(widget) || WIDGET_TROUGH == widget || \ 0195 (((w > (MIN_ROUND_EXTRA_SIZE(widget) + MOD)) || \ 0196 (WIDGET_NO_ETCH_BTN == widget || WIDGET_MENU_BUTTON == widget)) && \ 0197 (h > (MIN_ROUND_EXTRA_SIZE(widget) + MOD))))) 0198 #define CAN_FULL_ROUND(MOD) \ 0199 (w > (MIN_ROUND_FULL_SIZE + MOD) && h > (MIN_ROUND_FULL_SIZE + MOD)) 0200 0201 // **NOTE** MUST KEEP IN SYNC WITH getRadius/RADIUS_ETCH !!! 0202 ERound 0203 qtcGetWidgetRound(const Options *opts, int w, int h, EWidget widget) 0204 { 0205 ERound r = opts->round; 0206 0207 if ((QtCurve::oneOf(widget, WIDGET_PBAR_TROUGH, WIDGET_PROGRESSBAR) && 0208 (opts->square & SQUARE_PROGRESS)) || 0209 (widget == WIDGET_ENTRY && (opts->square & SQUARE_ENTRY)) || 0210 (widget == WIDGET_SCROLLVIEW && (opts->square & SQUARE_SCROLLVIEW))) { 0211 return ROUND_NONE; 0212 } 0213 0214 if (QtCurve::oneOf(widget, WIDGET_CHECKBOX, WIDGET_FOCUS) && 0215 r != ROUND_NONE) { 0216 r = ROUND_SLIGHT; 0217 } 0218 0219 #ifdef QTC_UTILS_QT 0220 if ((widget == WIDGET_MDI_WINDOW_BUTTON && 0221 (opts->titlebarButtons & TITLEBAR_BUTTON_ROUND)) || 0222 QtCurve::oneOf(widget, WIDGET_RADIO_BUTTON, WIDGET_DIAL)) { 0223 return ROUND_MAX; 0224 } 0225 #endif 0226 #ifndef QTC_UTILS_QT 0227 if (widget == WIDGET_RADIO_BUTTON) { 0228 return ROUND_MAX; 0229 } 0230 #endif 0231 if (QtCurve::oneOf(opts->sliderStyle, SLIDER_ROUND, SLIDER_ROUND_ROTATED, 0232 SLIDER_CIRCULAR) && widget == WIDGET_SLIDER) { 0233 return ROUND_MAX; 0234 } 0235 switch (r) { 0236 case ROUND_MAX: 0237 if (IS_SLIDER(widget) || widget == WIDGET_TROUGH || 0238 (w > (MIN_ROUND_MAX_WIDTH + 2) && h > (MIN_ROUND_MAX_HEIGHT + 2) && 0239 QtCurve::isMaxRoundWidget(widget))) { 0240 return ROUND_MAX; 0241 } 0242 QTC_FALLTHROUGH(); 0243 case ROUND_EXTRA: 0244 if (CAN_EXTRA_ROUND(2)) { 0245 return ROUND_EXTRA; 0246 } 0247 QTC_FALLTHROUGH(); 0248 case ROUND_FULL: 0249 if (CAN_FULL_ROUND(2)) { 0250 return ROUND_FULL; 0251 } 0252 QTC_FALLTHROUGH(); 0253 case ROUND_SLIGHT: 0254 return ROUND_SLIGHT; 0255 case ROUND_NONE: 0256 return ROUND_NONE; 0257 } 0258 return ROUND_NONE; 0259 } 0260 0261 double 0262 qtcGetRadius(const Options *opts, int w, int h, EWidget widget, ERadius rad) 0263 { 0264 ERound r = opts->round; 0265 0266 if (QtCurve::oneOf(widget, WIDGET_CHECKBOX, WIDGET_FOCUS) && 0267 ROUND_NONE != r) { 0268 r = ROUND_SLIGHT; 0269 } 0270 0271 if ((QtCurve::oneOf(widget, WIDGET_PBAR_TROUGH, WIDGET_PROGRESSBAR) && 0272 (opts->square & SQUARE_PROGRESS)) || 0273 (widget == WIDGET_ENTRY && (opts->square & SQUARE_ENTRY)) || 0274 (widget == WIDGET_SCROLLVIEW && (opts->square & SQUARE_SCROLLVIEW))) { 0275 return 0.0; 0276 } 0277 0278 #ifdef QTC_UTILS_QT 0279 if ((widget == WIDGET_MDI_WINDOW_BUTTON && 0280 (opts->titlebarButtons & TITLEBAR_BUTTON_ROUND)) || 0281 QtCurve::oneOf(widget, WIDGET_RADIO_BUTTON, WIDGET_DIAL)) { 0282 return (w > h ? h : w) / 2.0; 0283 } 0284 #endif 0285 #ifndef QTC_UTILS_QT 0286 if (widget == WIDGET_RADIO_BUTTON) { 0287 return (w > h ? h : w) / 2.0; 0288 } 0289 #endif 0290 0291 if (QtCurve::oneOf(opts->sliderStyle, SLIDER_ROUND, SLIDER_ROUND_ROTATED, 0292 SLIDER_CIRCULAR) && widget == WIDGET_SLIDER) { 0293 return (w > h ? h : w) / 2.0; 0294 } 0295 0296 if (rad == RADIUS_EXTERNAL && !opts->fillProgress && 0297 (widget == WIDGET_PROGRESSBAR 0298 #ifndef QTC_UTILS_QT 0299 || widget == WIDGET_ENTRY_PROGRESSBAR 0300 #endif 0301 )) { 0302 rad = RADIUS_INTERNAL; 0303 } 0304 0305 switch (rad) { 0306 case RADIUS_SELECTION: 0307 switch (r) { 0308 case ROUND_MAX: 0309 case ROUND_EXTRA: 0310 if (/* (WIDGET_RUBBER_BAND==widget && w>14 && h>14) || */ 0311 (w > 48 && h > 48)) { 0312 return 6.0; 0313 } 0314 QTC_FALLTHROUGH(); 0315 case ROUND_FULL: 0316 /* if( /\*(WIDGET_RUBBER_BAND==widget && w>11 && h>11) || *\/ */ 0317 /* (w>48 && h>48)) */ 0318 /* return 3.0; */ 0319 if (w > MIN_ROUND_FULL_SIZE && h > MIN_ROUND_FULL_SIZE) { 0320 return 3.0; 0321 } 0322 QTC_FALLTHROUGH(); 0323 case ROUND_SLIGHT: 0324 return 2.0; 0325 case ROUND_NONE: 0326 return 0; 0327 } 0328 QTC_FALLTHROUGH(); 0329 case RADIUS_INTERNAL: 0330 switch (r) { 0331 case ROUND_MAX: 0332 if (IS_SLIDER(widget) || WIDGET_TROUGH == widget) { 0333 double r = ((w > h ? h : w) - 0334 (WIDGET_SLIDER == widget ? 1 : 0)) / 2.0; 0335 return r > MAX_RADIUS_INTERNAL ? MAX_RADIUS_INTERNAL : r; 0336 } 0337 if (w > (MIN_ROUND_MAX_WIDTH - 2) && 0338 h > (MIN_ROUND_MAX_HEIGHT - 2) && 0339 QtCurve::isMaxRoundWidget(widget)) { 0340 double r = ((w > h ? h : w) - 2.0) / 2.0; 0341 return r > 9.5 ? 9.5 : r; 0342 } 0343 QTC_FALLTHROUGH(); 0344 case ROUND_EXTRA: 0345 if (CAN_EXTRA_ROUND(-2)) { 0346 return EXTRA_INNER_RADIUS; 0347 } 0348 QTC_FALLTHROUGH(); 0349 case ROUND_FULL: 0350 if (CAN_FULL_ROUND(-2)) { 0351 return FULL_INNER_RADIUS; 0352 } 0353 QTC_FALLTHROUGH(); 0354 case ROUND_SLIGHT: 0355 return SLIGHT_INNER_RADIUS; 0356 case ROUND_NONE: 0357 return 0; 0358 } 0359 QTC_FALLTHROUGH(); 0360 case RADIUS_EXTERNAL: 0361 switch (r) { 0362 case ROUND_MAX: 0363 if (IS_SLIDER(widget) || WIDGET_TROUGH == widget) { 0364 double r = ((w > h ? h : w) - 0365 (WIDGET_SLIDER == widget ? 1 : 0)) / 2.0; 0366 return r > MAX_RADIUS_EXTERNAL ? MAX_RADIUS_EXTERNAL : r; 0367 } 0368 if (w > MIN_ROUND_MAX_WIDTH && h > MIN_ROUND_MAX_HEIGHT && 0369 QtCurve::isMaxRoundWidget(widget)) { 0370 double r = ((w > h ? h : w) - 2.0) / 2.0; 0371 return r > 10.5 ? 10.5 : r; 0372 } 0373 QTC_FALLTHROUGH(); 0374 case ROUND_EXTRA: 0375 if (CAN_EXTRA_ROUND(0)) { 0376 return EXTRA_OUTER_RADIUS; 0377 } 0378 QTC_FALLTHROUGH(); 0379 case ROUND_FULL: 0380 if (CAN_FULL_ROUND(0)) { 0381 return FULL_OUTER_RADIUS; 0382 } 0383 QTC_FALLTHROUGH(); 0384 case ROUND_SLIGHT: 0385 return SLIGHT_OUTER_RADIUS; 0386 case ROUND_NONE: 0387 return 0; 0388 } 0389 QTC_FALLTHROUGH(); 0390 case RADIUS_ETCH: 0391 // **NOTE** MUST KEEP IN SYNC WITH getWidgetRound !!! 0392 switch (r) { 0393 case ROUND_MAX: 0394 if (IS_SLIDER(widget) || WIDGET_TROUGH == widget) { 0395 double r = ((w > h ? h : w) - 0396 (WIDGET_SLIDER == widget ? 1 : 0)) / 2.0; 0397 return r > MAX_RADIUS_EXTERNAL ? MAX_RADIUS_EXTERNAL : r; 0398 } 0399 if (w > (MIN_ROUND_MAX_WIDTH + 2) && 0400 h > (MIN_ROUND_MAX_HEIGHT + 2) && 0401 QtCurve::isMaxRoundWidget(widget)) { 0402 double r = ((w > h ? h : w) - 2.0) / 2.0; 0403 return r > 11.5 ? 11.5 : r; 0404 } 0405 QTC_FALLTHROUGH(); 0406 case ROUND_EXTRA: 0407 if (CAN_FULL_ROUND(2)) { 0408 return EXTRA_ETCH_RADIUS; 0409 } 0410 QTC_FALLTHROUGH(); 0411 case ROUND_FULL: 0412 if (w > (MIN_ROUND_FULL_SIZE + 2) && 0413 h > (MIN_ROUND_FULL_SIZE + 2)) { 0414 return FULL_ETCH_RADIUS; 0415 } 0416 QTC_FALLTHROUGH(); 0417 case ROUND_SLIGHT: 0418 return SLIGHT_ETCH_RADIUS; 0419 case ROUND_NONE: 0420 return 0; 0421 } 0422 QTC_FALLTHROUGH(); 0423 default: 0424 // (empty case required for the fall-through declaration above) 0425 break; 0426 } 0427 return 0; 0428 }