File indexing completed on 2024-04-14 05:19:48
0001 #!/usr/bin/env python3 0002 import cairo 0003 import colorsys 0004 from math import pi 0005 import os 0006 import errno 0007 import sys 0008 import re 0009 import argparse 0010 0011 0012 def make_sure_path_exists(path): 0013 try: 0014 os.makedirs(path) 0015 except FileExistsError as exception: 0016 pass 0017 pass 0018 0019 0020 class ReadKdeGlobals(): 0021 def __init__(self, base_file_name): 0022 self._colors = {} 0023 self._colors = self.read_globals(base_file_name) 0024 0025 def read_globals(self, filename): 0026 with open(filename, 'r', encoding="utf-8") as _kde: 0027 for widget in ['Disabled', 'Inactive', 'Button', 'Selection', 0028 'Tooltip', 'View', 'Window', 'WM']: 0029 for line in _kde: 0030 if line.strip().split(':')[-1].strip('[]') == widget: 0031 break 0032 for line in _kde: 0033 if line == '\n': 0034 break 0035 key = '{0}{1}'.format(widget, line.strip().split('=')[0]) 0036 value = line.strip().split('=')[1] 0037 if value == '': 0038 continue 0039 self._colors[key] = value 0040 return self._colors 0041 0042 0043 class Color(object): 0044 def __init__(self, colordict, name, name2=None, amount=0): 0045 color = colordict[name] 0046 self.colordict = colordict 0047 0048 r = float(color.split(',')[0]) 0049 g = float(color.split(',')[1]) 0050 b = float(color.split(',')[2]) 0051 if name2 is not None: 0052 color2 = colordict[name2] 0053 r = r * amount + float(color2.split(',')[0]) * (1 - amount) 0054 g = g * amount + float(color2.split(',')[1]) * (1 - amount) 0055 b = b * amount + float(color2.split(',')[2]) * (1 - amount) 0056 0057 self.rgb255 = (int(r), int(g), int(b)) 0058 self.rgb = (r/255, g/255, b/255) 0059 self.html = '#%02x%02x%02x' % self.rgb255 0060 self.insensitive = self._color_effect( 0061 self._intensity_effect(self.rgb, 'Disabled'), 'Disabled') 0062 self.insensitive_alpha = self._contrast_effect(self.rgb, 'Disabled') 0063 0064 if self.colordict['InactiveEnable'] == 'false': 0065 self.inactive = self.rgb 0066 self.inactive_alpha = 1.0 0067 else: 0068 self.inactive = self._color_effect( 0069 self._intensity_effect(self.rgb, 'Inactive'), 'Inactive') 0070 self.inactive_alpha = self._contrast_effect(self.rgb, 'Inactive') 0071 self.inactive_insensitive = self._color_effect( 0072 self._intensity_effect(self.inactive, 'Disabled'), 'Disabled') 0073 self.inactive_insensitive_alpha = max( 0074 self.inactive_alpha - (1 - self.insensitive_alpha), 0) 0075 0076 def _mix(self, color, mix_color, amount): 0077 r = color[0] * amount + mix_color[0] * (1 - amount) 0078 g = color[1] * amount + mix_color[1] * (1 - amount) 0079 b = color[2] * amount + mix_color[2] * (1 - amount) 0080 return (r, g, b) 0081 0082 def _lighter(self, color, amount): 0083 h, s, v = colorsys.rgb_to_hsv(color[0], color[1], color[2]) 0084 v = min((1+amount)*v, 1) 0085 r, g, b = colorsys.hsv_to_rgb(h, s, v) 0086 return (r, g, b) 0087 0088 def _darker(self, color, amount): 0089 h, s, v = colorsys.rgb_to_hsv(color[0], color[1], color[2]) 0090 if amount == -1: 0091 v = 1 0092 else: 0093 v = min(v/(1+amount), 1) 0094 r, g, b = colorsys.hsv_to_rgb(h, s, v) 0095 return (r, g, b) 0096 0097 def _desaturate(self, color, amount): 0098 h, s, v = colorsys.rgb_to_hsv(color[0], color[1], color[2]) 0099 s = min(s * (1 - amount), 1) 0100 r, g, b = colorsys.hsv_to_rgb(h, s, v) 0101 return (r, g, b) 0102 0103 def _intensity_effect(self, color, state): 0104 effect = int(self.colordict[state + 'IntensityEffect']) 0105 amount = float(self.colordict[state + 'IntensityAmount']) 0106 if effect == 0: 0107 (r, g, b) = color 0108 elif effect == 1: 0109 if amount >= 0: 0110 (r, g, b) = self._mix((1.0, 1.0, 1.0), color, amount) 0111 else: 0112 (r, g, b) = self._mix((0.0, 0.0, 0.0), color, amount) 0113 elif effect == 2: 0114 (r, g, b) = self._darker(color, amount) 0115 elif effect == 3: 0116 (r, g, b) = self._lighter(color, amount) 0117 return (r, g, b) 0118 0119 def _color_effect(self, color, state): 0120 effect = int(self.colordict[state + 'ColorEffect']) 0121 amount = float(self.colordict[state + 'ColorAmount']) 0122 effect_color = self.colordict[state + 'Color'] 0123 effect_color = (float(effect_color.split(',')[0])/255, 0124 float(effect_color.split(',')[1])/255, 0125 float(effect_color.split(',')[2])/255) 0126 if effect == 0: 0127 (r, g, b) = color 0128 elif effect == 1: 0129 (r, g, b) = self._desaturate(color, amount) 0130 else: 0131 (r, g, b) = self._mix(effect_color, color, amount) 0132 return (r, g, b) 0133 0134 def _contrast_effect(self, color, state): 0135 effect = int(self.colordict[state + 'ContrastEffect']) 0136 amount = float(self.colordict[state + 'ContrastAmount']) 0137 if effect == 0: 0138 return 1.0 0139 else: 0140 return 1.0 - amount 0141 0142 def lighten_color(self, amount): 0143 h, s, v = colorsys.rgb_to_hsv(self.rgb[0], self.rgb[1], self.rgb[2]) 0144 v = (1+amount)*v 0145 r, g, b = colorsys.hsv_to_rgb(h, s, v) 0146 self.rgb = (r, g, b) 0147 self.rgb255 = (int(r*255), int(g*255), int(b*255)) 0148 0149 def gradient(self, state='', alpha=1.0): 0150 if state == 'active': 0151 stop1 = self._lighter(self.rgb, 0.03) 0152 stop2 = self._darker(self.rgb, 0.10) 0153 linear = cairo.LinearGradient(1, 1, 1, 19) 0154 linear.add_color_stop_rgba( 0155 0.0, stop1[0], stop1[1], stop1[2], alpha) 0156 linear.add_color_stop_rgba( 0157 1.0, stop2[0], stop2[1], stop2[2], alpha) 0158 else: 0159 stop1 = self._lighter(self.rgb, 0.01) 0160 stop2 = self._darker(self.rgb, 0.03) 0161 linear = cairo.LinearGradient(1, 1, 1, 19) 0162 linear.add_color_stop_rgba( 0163 0.0, stop1[0], stop1[1], stop1[2], alpha) 0164 linear.add_color_stop_rgba( 0165 1.0, stop2[0], stop2[1], stop2[2], alpha) 0166 return linear 0167 0168 0169 class Assets(object): 0170 def __init__(self, width, height, scl=1, rotation=0, filename='png'): 0171 self.w = width 0172 self.h = height 0173 if filename == 'png': 0174 self.surface = cairo.ImageSurface( 0175 cairo.FORMAT_ARGB32, scl*width, scl*height) 0176 else: 0177 self.surface = cairo.SVGSurface(os.path.join( 0178 assets_path, filename), scl*width, scl*height) 0179 cr = self.cr = cairo.Context(self.surface) 0180 if rotation != 0: 0181 cr.translate(scl*width/2, scl*height/2) 0182 cr.rotate(rotation*pi/2) 0183 cr.translate(-scl*width/2, -scl*height/2) 0184 cr.scale(scl, scl) 0185 0186 def background(self, color): 0187 self.cr.rectangle(0, 0, self.w, self.h) 0188 self.cr.set_source_rgb(color[0], color[1], color[2]) 0189 self.cr.fill() 0190 0191 def line(self, color, x, y, width, height): 0192 self.cr.rectangle(x, y, width, height) 0193 self.cr.set_source_rgb(color[0], color[1], color[2]) 0194 self.cr.fill() 0195 0196 def rounded_rectancle(self, color, width, height, x, y, radius, alpha=1.0, 0197 gradient=False): 0198 self.cr.new_sub_path() 0199 self.cr.arc(x + width - radius, y + radius, radius, -pi/2, 0) 0200 self.cr.arc(x + width - radius, y + height - radius, radius, 0, pi/2) 0201 self.cr.arc(x + radius, y + height - radius, radius, pi/2, pi) 0202 self.cr.arc(x + radius, y + radius, radius, pi, 3*pi/2) 0203 self.cr.close_path() 0204 if gradient: 0205 self.cr.set_source(color) 0206 elif color is None: 0207 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0208 elif color == 'shadow': 0209 self.cr.set_source_rgba(0.0, 0.0, 0.0, 0.15) 0210 else: 0211 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0212 self.cr.fill() 0213 0214 def rounded_triangle(self, color, width, height, x, y, radius, alpha=1.0): 0215 self.cr.new_sub_path() 0216 self.cr.move_to(x + width, y) 0217 self.cr.line_to(x + width, y + height - radius) 0218 self.cr.arc(x + width - radius, y + height - radius, radius, 0, pi/2) 0219 self.cr.line_to(x, y + height) 0220 self.cr.close_path() 0221 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0222 self.cr.fill() 0223 0224 def circle(self, color, x, y, radius, alpha=1.0, gradient=False): 0225 self.cr.new_sub_path() 0226 self.cr.arc(x, y, radius, 0, 2*pi) 0227 self.cr.close_path() 0228 if gradient: 0229 self.cr.set_source(color) 0230 elif color is None: 0231 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0232 elif color == 'shadow': 0233 self.cr.set_source_rgba(0.0, 0.0, 0.0, 0.15) 0234 else: 0235 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0236 self.cr.fill() 0237 0238 def half_circle(self, color, x, y, radius, alpha=1.0): 0239 self.cr.new_sub_path() 0240 self.cr.arc(x, y, radius, -pi/4, 3*pi/4) 0241 self.cr.close_path() 0242 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0243 self.cr.fill() 0244 0245 def arrow(self, color, alpha=1.0, shiftx=0, shifty=0): 0246 self.cr.new_sub_path() 0247 self.cr.move_to(shiftx + 1, shifty + 8) 0248 self.cr.line_to(shiftx + 6, shifty + 3) 0249 self.cr.line_to(shiftx + 11, shifty + 8) 0250 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0251 self.cr.set_line_width(1.0) 0252 self.cr.stroke() 0253 0254 def arrow_small(self, color, alpha=1.0): 0255 self.cr.new_sub_path() 0256 self.cr.move_to(1, 6) 0257 self.cr.line_to(4, 3) 0258 self.cr.line_to(7, 6) 0259 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0260 self.cr.set_line_width(1.0) 0261 self.cr.stroke() 0262 0263 def tab(self, color, width, height, x, y, radius, alpha=1.0): 0264 self.cr.move_to(width + x, y) 0265 self.cr.line_to(width + x, height - radius + y) 0266 self.cr.arc(width - radius + x, height - radius + y, radius, 0, pi/2) 0267 self.cr.line_to(radius + x, height + y) 0268 self.cr.arc(radius + x, height - radius + y, radius, pi/2, pi) 0269 self.cr.line_to(x, y) 0270 self.cr.close_path 0271 if color is None: 0272 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0273 else: 0274 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0275 self.cr.fill() 0276 0277 def spinbutton(self, color, width, height, x, y, radius, alpha=1.0): 0278 self.cr.move_to(width + x, y) 0279 self.cr.line_to(width + x, height - radius + y) 0280 self.cr.arc(width - radius + x, height - radius + y, radius, 0, pi/2) 0281 self.cr.line_to(x, height + y) 0282 self.cr.line_to(x, y) 0283 self.cr.close_path() 0284 if color is None: 0285 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0286 else: 0287 self.cr.set_source_rgba(color[0], color[1], color[2], alpha) 0288 self.cr.fill() 0289 0290 def notebook(self, color, width, height, x, y, radius): 0291 self.cr.move_to(x, y) 0292 self.cr.line_to(x + width - radius, y) 0293 self.cr.arc(x + width - radius, y + radius, radius, -pi/2, 0) 0294 self.cr.line_to(x + width, y + height-radius) 0295 self.cr.arc(x + width - radius, y + height - radius, radius, 0, pi/2) 0296 self.cr.line_to(x + radius, y + height) 0297 self.cr.arc(x + radius, y + height - radius, radius, pi/2, pi) 0298 self.cr.close_path() 0299 self.cr.set_source_rgb(color[0], color[1], color[2]) 0300 self.cr.fill() 0301 0302 def minimize(self, color=None): 0303 self.cr.move_to(4, 7) 0304 self.cr.line_to(9, 12) 0305 self.cr.line_to(14, 7) 0306 if color is None: 0307 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0308 else: 0309 self.cr.set_source_rgb(color[0], color[1], color[2]) 0310 self.cr.set_line_width(1.0) 0311 self.cr.stroke() 0312 0313 def maximize(self, color=None): 0314 self.cr.move_to(4, 11) 0315 self.cr.line_to(9, 6) 0316 self.cr.line_to(14, 11) 0317 if color is None: 0318 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0319 else: 0320 self.cr.set_source_rgb(color[0], color[1], color[2]) 0321 self.cr.set_line_width(1.0) 0322 self.cr.stroke() 0323 0324 def maximize_maximized(self, color=None): 0325 self.cr.move_to(4.5, 9) 0326 self.cr.line_to(9, 4.5) 0327 self.cr.line_to(13.5, 9) 0328 self.cr.line_to(9, 13.5) 0329 self.cr.close_path() 0330 if color is None: 0331 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0332 else: 0333 self.cr.set_source_rgb(color[0], color[1], color[2]) 0334 self.cr.set_line_width(1.0) 0335 self.cr.stroke() 0336 0337 def close(self, color=None): 0338 self.cr.move_to(5, 5) 0339 self.cr.line_to(13, 13) 0340 self.cr.move_to(13, 5) 0341 self.cr.line_to(5, 13) 0342 if color is None: 0343 self.cr.set_operator(cairo.OPERATOR_CLEAR) 0344 else: 0345 self.cr.set_source_rgb(color[0], color[1], color[2]) 0346 self.cr.set_line_width(1.0) 0347 self.cr.stroke() 0348 0349 def save(self, filename): 0350 self.surface.write_to_png(os.path.join(assets_path, filename)) 0351 0352 0353 def check_items(color1, color2, state, alpha=1.0): 0354 for scl in [1, 2]: 0355 if scl == 2: 0356 ending = '@2.png' 0357 else: 0358 ending = '.png' 0359 # checkboxes 0360 box = Assets(20, 20, scl) 0361 box.rounded_rectancle('shadow', 18, 18, 2, 2, 3) 0362 box.rounded_rectancle(color2, 18, 18, 1, 1, 3) 0363 box.rounded_rectancle(color1, 18, 18, 1, 1, 3, alpha=alpha) 0364 box.rounded_rectancle(color2, 16, 16, 2, 2, 2) 0365 box.save('check-unchecked' + state + ending) 0366 if state != '': 0367 box.rounded_rectancle(color1, 12, 12, 4, 4, 1, alpha=alpha) 0368 box.save('check-checked' + state + ending) 0369 box.rounded_triangle(color2, 8, 8, 6, 6, 1, alpha=alpha) 0370 box.save('check-mixed' + state + ending) 0371 0372 # radio 0373 radio = Assets(20, 20, scl) 0374 radio.circle('shadow', 11, 11, 9) 0375 radio.circle(color2, 10, 10, 9) 0376 radio.circle(color1, 10, 10, 9, alpha=alpha) 0377 radio.circle(color2, 10, 10, 8) 0378 radio.save('radio-unchecked' + state + ending) 0379 if state != '': 0380 radio.circle(color1, 10, 10, 6, alpha=alpha) 0381 radio.save('radio-checked' + state + ending) 0382 radio.half_circle(color2, 10, 10, 4, alpha=alpha) 0383 radio.save('radio-mixed' + state + ending) 0384 0385 # selectionmode 0386 selectionmode = Assets(40, 40, scl) 0387 selectionmode.rounded_rectancle('shadow', 18, 18, 12, 12, 3) 0388 selectionmode.rounded_rectancle(color2, 18, 18, 11, 11, 3) 0389 selectionmode.rounded_rectancle(color1, 18, 18, 11, 11, 3, alpha=alpha) 0390 selectionmode.rounded_rectancle(color2, 16, 16, 12, 12, 2) 0391 selectionmode.save('check-selectionmode-unchecked' + state + ending) 0392 if state != '': 0393 selectionmode.rounded_rectancle( 0394 color1, 12, 12, 14, 14, 1, alpha=alpha) 0395 selectionmode.save('check-selectionmode-checked' + state + ending) 0396 0397 0398 def buttons(color1, color2, color3, state, alpha=1.0): 0399 button = Assets(20, 20) 0400 button.rounded_rectancle('shadow', 18, 18, 2, 2, 3) 0401 button.rounded_rectancle(color1, 18, 18, 1, 1, 3) 0402 button.rounded_rectancle(color2, 18, 18, 1, 1, 3, alpha=alpha) 0403 if state == '-active': 0404 button.rounded_rectancle(color3, 18, 18, 1, 1, 3, gradient=True) 0405 else: 0406 button.rounded_rectancle(color1, 16, 16, 2, 2, 2) 0407 button.rounded_rectancle(color3, 16, 16, 2, 2, 2, gradient=True) 0408 button.save('button' + state + '.png') 0409 0410 0411 def togglebuttons(color1, color2, color3, state, alpha=1.0): 0412 button = Assets(20, 20) 0413 button.rounded_rectancle(color1, 18, 18, 1, 1, 3) 0414 button.rounded_rectancle(color2, 18, 18, 1, 1, 3, alpha=alpha) 0415 if state == '-active': 0416 button.rounded_rectancle(color3, 18, 18, 1, 1, 3, gradient=True) 0417 else: 0418 button.rounded_rectancle(color1, 16, 16, 2, 2, 2) 0419 button.rounded_rectancle(color3, 16, 16, 2, 2, 2, gradient=True) 0420 button.save('togglebutton' + state + '.png') 0421 0422 0423 def scale_slider(color1, color2, color3, state, alpha=1.0): 0424 scale = Assets(20, 20) 0425 scale.circle(color1, 10, 10, 10) 0426 scale.circle(color2, 10, 10, 10, alpha=alpha) 0427 scale.circle(color1, 10, 10, 9) 0428 scale.circle(color3, 10, 10, 9, gradient=True) 0429 scale.save('scale-slider' + state + '.png') 0430 0431 0432 def scale_trough(color): 0433 trough_h = Assets(20, 20) 0434 trough_h.rounded_rectancle(color, 20, 6, 0, 7, 3) 0435 trough_h.save('scale-trough-horizontal.png') 0436 0437 trough_h = Assets(20, 20) 0438 trough_h.rounded_rectancle(color, 6, 20, 7, 0, 3) 0439 trough_h.save('scale-trough-vertical.png') 0440 0441 0442 def tabs(color1, color2, state): 0443 if state == '-inactive': 0444 alpha = 0.2 0445 else: 0446 alpha = 1.0 0447 direction = ['-bottom', '-left', '-top', '-right'] 0448 for i in range(0, 4): 0449 tab = Assets(20, 20, rotation=i) 0450 tab.tab(color1, 20, 20, 0, 0, 3, alpha) 0451 if state == '-active': 0452 tab.tab(color2, 18, 19, 1, 0, 2) 0453 tab.save('tab' + direction[i] + state + '.png') 0454 0455 0456 def arrows(color, state, alpha=1.0): 0457 direction = ['-up', '-right', '-down', '-left'] 0458 for i in range(0, 4): 0459 arw = Assets(12, 12, rotation=i) 0460 arw.arrow(color, alpha) 0461 arw.save('arrow' + direction[i] + state + '.png') 0462 0463 arw = Assets(8, 8, rotation=i) 0464 arw.arrow_small(color, alpha) 0465 arw.save('arrow-small' + direction[i] + state + '.png') 0466 0467 0468 def menu_arrow(color, state, alpha=1.0): 0469 arrow = Assets(12, 12, rotation=1) 0470 arrow.arrow(color, alpha) 0471 arrow.save('menu-arrow' + state + '.png') 0472 0473 0474 def scrollbar_slider(color1, color2, color3): 0475 for scl in [1, 2]: 0476 if scl == 2: 0477 ending = '@2.png' 0478 else: 0479 ending = '.png' 0480 slider = Assets(30, 20, scl) 0481 slider.rounded_rectancle(color1, 30, 10, 0, 5, 5, 1) 0482 slider.save('scrollbar-slider-horizontal-active' + ending) 0483 0484 slider = Assets(30, 20, scl) 0485 slider.rounded_rectancle(color2, 30, 6, 0, 7, 3, 1) 0486 slider.save('scrollbar-slider-horizontal-hover' + ending) 0487 0488 slider = Assets(30, 20, scl) 0489 slider.rounded_rectancle(color3, 30, 6, 0, 7, 3, 0.4) 0490 slider.save('scrollbar-slider-horizontal' + ending) 0491 0492 slider = Assets(20, 30, scl) 0493 slider.rounded_rectancle(color1, 10, 30, 5, 0, 5, 1) 0494 slider.save('scrollbar-slider-vertical-active' + ending) 0495 0496 slider = Assets(20, 30, scl) 0497 slider.rounded_rectancle(color2, 6, 30, 7, 0, 3, 1) 0498 slider.save('scrollbar-slider-vertical-hover' + ending) 0499 0500 slider = Assets(20, 30, scl) 0501 slider.rounded_rectancle(color3, 6, 30, 7, 0, 3, 0.4) 0502 slider.save('scrollbar-slider-vertical' + ending) 0503 0504 0505 def scrollbar_trough(color): 0506 for scl in [1, 2]: 0507 if scl == 2: 0508 ending = '@2.png' 0509 else: 0510 ending = '.png' 0511 trough = Assets(56, 20, scl) 0512 trough.rounded_rectancle(color, 49, 6, 3.5, 7, 3, 0.3) 0513 trough.save('scrollbar-trough-horizontal' + ending) 0514 0515 trough = Assets(20, 56, scl) 0516 trough.rounded_rectancle(color, 6, 49, 7, 3.5, 3, 0.3) 0517 trough.save('scrollbar-trough-vertical' + ending) 0518 0519 0520 def titlebuttons(color1, color2, state): 0521 for scl in [1, 2]: 0522 if scl == 2: 0523 ending = '@2.png' 0524 else: 0525 ending = '.png' 0526 title_minimize = Assets(18, 18, scl) 0527 title_maximize = Assets(18, 18, scl) 0528 title_maximized = Assets(18, 18, scl) 0529 if state == '' or state == '-backdrop': 0530 title_minimize.minimize(color1) 0531 title_maximize.maximize(color1) 0532 title_maximized.maximize_maximized(color1) 0533 else: 0534 title_minimize.circle(color1, 9, 9, 9) 0535 title_maximize.circle(color1, 9, 9, 9) 0536 title_maximized.circle(color1, 9, 9, 9) 0537 title_minimize.minimize() 0538 title_maximize.maximize() 0539 title_maximized.maximize_maximized() 0540 title_minimize.save('titlebutton-minimize' + state + ending) 0541 title_maximize.save('titlebutton-maximize' + state + ending) 0542 title_maximized.save('titlebutton-maximize-maximized' + state + ending) 0543 0544 title_close = Assets(18, 18, scl) 0545 title_close.circle(color2, 9, 9, 9) 0546 title_close.close() 0547 title_close.save('titlebutton-close' + state + ending) 0548 0549 0550 def entry(color1, color2, color3, state, alpha=1.0): 0551 entry = Assets(20, 20) 0552 entry.background(color1) 0553 entry.rounded_rectancle(color2, 18, 18, 1, 1, 3, alpha=alpha) 0554 entry.rounded_rectancle(color3, 16, 16, 2, 2, 2) 0555 entry.rounded_rectancle(color3, 16, 16, 2, 2, 2) 0556 entry.save('entry' + state + '.png') 0557 0558 entry = Assets(20, 20, rotation=1) 0559 entry.background(color1) 0560 entry.tab(color2, 18, 19, 1, 0, 3, alpha=alpha) 0561 entry.tab(color3, 16, 18, 2, 0, 2) 0562 entry.save('combo-entry' + state + '.png') 0563 0564 entry_button = Assets(20, 20, rotation=3) 0565 entry_button.background(color1) 0566 entry_button.tab(color2, 18, 19, 1, 0, 3, alpha=alpha) 0567 entry_button.tab(color3, 16, 18, 2, 0, 2) 0568 entry_button.save('combo-entry-button' + state + '.png') 0569 0570 if state != '-active': 0571 direction = ['-down', '-down-rtl', '-up-rtl', '-up'] 0572 for i in range(0, 4): 0573 spin = Assets(20, 20, rotation=i) 0574 spin.background(color1) 0575 spin.spinbutton(color2, 19, 19, 0, 0, 3, alpha=alpha) 0576 spin.spinbutton(color3, 18, 18, 0, 0, 2) 0577 spin.save('spinbutton' + direction[i] + state + '.png') 0578 0579 0580 def mixed(color1, color2, color3): 0581 nll = Assets(20, 20) 0582 nll.save('null.png') 0583 0584 # Frame 0585 frame = Assets(20, 20) 0586 frame.rounded_rectancle(color1, 20, 20, 0, 0, 3) 0587 frame.rounded_rectancle(color2, 18, 18, 1, 1, 2) 0588 frame.save('frame.png') 0589 0590 # Tree header 0591 header = Assets(20, 20) 0592 header.background(color2) 0593 header.line(color1, 0, 19, 20, 1) 0594 header.line(color1, 19, 0, 1, 20) 0595 header.save('tree-header.png') 0596 0597 # Notebook gap 0598 notebook_gap = Assets(4, 2) 0599 notebook_gap.line(color2, 1, 0, 2, 2) 0600 notebook_gap.save('notebook-gap-horizontal.png') 0601 0602 notebook_gap = Assets(2, 4) 0603 notebook_gap.line(color2, 0, 1, 2, 2) 0604 notebook_gap.save('notebook-gap-vertical.png') 0605 0606 # Notebook frame 0607 direction = ['-top', '-right', '-bottom', '-bottom'] 0608 for i in range(0, 4): 0609 notebook_frame = Assets(20, 20, rotation=i) 0610 notebook_frame.notebook(color1, 20, 20, 0, 0, 3) 0611 notebook_frame.notebook(color2, 18, 18, 1, 1, 2) 0612 notebook_frame.save('notebook-frame' + direction[i] + '.png') 0613 0614 # Frame gap 0615 frame_gap = Assets(2, 1) 0616 frame_gap.line(color1, 1, 0, 1, 1) 0617 frame_gap.save('frame-gap-start.png') 0618 0619 frame_gap = Assets(2, 1) 0620 frame_gap.line(color1, 0, 0, 1, 1) 0621 frame_gap.save('frame-gap-end.png') 0622 0623 # Lines 0624 lines = Assets(20, 1) 0625 lines.line(color1, 0, 0, 20, 1) 0626 lines.save('line-h.png') 0627 0628 lines = Assets(1, 20) 0629 lines.line(color1, 0, 0, 1, 20) 0630 lines.save('line-v.png') 0631 0632 lines = Assets(20, 1) 0633 lines.line(color2, 0, 0, 20, 1) 0634 lines.save('handle-h.png') 0635 0636 lines = Assets(1, 20) 0637 lines.line(color2, 0, 0, 1, 20) 0638 lines.save('handle-v.png') 0639 0640 menubar = Assets(20, 20) 0641 menubar.line(color3, 1, 1, 18, 18) 0642 menubar.save('menubar-button.png') 0643 0644 0645 def toolbar(color1, color2, color3): 0646 # Toolbar background 0647 bar = Assets(20, 20) 0648 bar.background(color2) 0649 bar.save('toolbar-background.png') 0650 0651 # Toolbutton toggled 0652 toolbutton = Assets(20, 20) 0653 toolbutton.rounded_rectancle(color1, 18, 18, 1, 1, 3) 0654 toolbutton.save('toolbutton-toggled.png') 0655 0656 # Toolbutton hover 0657 toolbutton = Assets(20, 20) 0658 toolbutton.rounded_rectancle(color3, 18, 18, 1, 1, 3) 0659 toolbutton.rounded_rectancle(color2, 16, 16, 2, 2, 2) 0660 toolbutton.save('toolbutton-hover.png') 0661 0662 # Toolbutton active 0663 toolbutton = Assets(20, 20) 0664 toolbutton.rounded_rectancle(color3, 18, 18, 1, 1, 3) 0665 toolbutton.save('toolbutton-active.png') 0666 0667 0668 def progressbar(color1, color2, state=''): 0669 bar = Assets(10, 10) 0670 bar.rounded_rectancle(color1, 10, 10, 0, 0, 3) 0671 bar.save('progressbar-bar' + state + '.png') 0672 0673 trough = Assets(10, 10) 0674 trough.rounded_rectancle(color2, 10, 10, 0, 0, 3) 0675 trough.save('progressbar-trough' + state + '.png') 0676 0677 0678 def html(color): 0679 return '#%02x%02x%02x' % (int(color[0]*255), 0680 int(color[1]*255), 0681 int(color[2]*255)) 0682 0683 0684 def mix(color, mix_color, amount): 0685 r = color[0] * amount + mix_color[0] * (1 - amount) 0686 g = color[1] * amount + mix_color[1] * (1 - amount) 0687 b = color[2] * amount + mix_color[2] * (1 - amount) 0688 return (r, g, b) 0689 # ___________________________________________________________________________________ 0690 0691 0692 parser = argparse.ArgumentParser( 0693 description='Generates Breeze assets according to the specified color ' 0694 'scheme.') 0695 parser.add_argument('--colorscheme', '-c', action='store', 0696 default='/usr/share/color-schemes/BreezeLight.colors', 0697 help='color scheme to use') 0698 parser.add_argument('--basecolorscheme', '-b', action='store', 0699 default='/usr/share/color-schemes/BreezeLight.colors', 0700 help='base color scheme') 0701 0702 parser.add_argument('--assets-dir', '-a', action='store', 0703 default='assets', 0704 help='location of the directory to place assets') 0705 parser.add_argument('--gtk2-dir', '-g', action='store', default='gtk2', 0706 help='location of gtk2 directory to define the color ' 0707 'scheme variables') 0708 parser.add_argument('--gtk3-scss-dir', '-G', action='store', default='.', 0709 help='location of global.scss to define the color ' 0710 'scheme variables') 0711 0712 args = parser.parse_args() 0713 0714 assets_path = args.assets_dir 0715 make_sure_path_exists(assets_path) 0716 0717 _colors = ReadKdeGlobals(args.basecolorscheme).read_globals(args.colorscheme) 0718 0719 border_color = Color(_colors, 'WindowBackgroundNormal', 0720 'WindowForegroundNormal', 0.75) 0721 window_bg = Color(_colors, 'WindowBackgroundNormal') 0722 window_fg = Color(_colors, 'WindowForegroundNormal') 0723 check_color = Color(_colors, 'WindowBackgroundNormal', 0724 'WindowForegroundNormal', 0.5) 0725 button_bg = Color(_colors, 'ButtonBackgroundNormal') 0726 button_fg = Color(_colors, 'ButtonForegroundNormal') 0727 button_hover = Color(_colors, 'ButtonDecorationHover') 0728 button_active = Color(_colors, 'ButtonDecorationFocus') 0729 selection_bg = Color(_colors, 'SelectionBackgroundNormal') 0730 selection_fg = Color(_colors, 'SelectionForegroundNormal') 0731 view_bg = Color(_colors, 'ViewBackgroundNormal') 0732 view_fg = Color(_colors, 'ViewForegroundNormal') 0733 view_hover = Color(_colors, 'ViewDecorationHover') 0734 view_active = Color(_colors, 'ViewDecorationFocus') 0735 titlebutton = Color(_colors, 'WMactiveForeground') 0736 titlebutton_active = Color(_colors, 'WMactiveForeground') 0737 closebutton_hover = Color(_colors, 'ViewForegroundNegative') 0738 closebutton_hover.lighten_color(0.5) 0739 closebutton_active = Color(_colors, 'ViewForegroundNegative') 0740 titlebutton_inactive = Color(_colors, 'WMinactiveForeground') 0741 titlebutton_inactive_active = Color(_colors, 'WMinactiveForeground') 0742 tooltip_fg = Color(_colors, 'TooltipForegroundNormal') 0743 tooltip_bg = Color(_colors, 'TooltipBackgroundNormal') 0744 0745 check_items(check_color.rgb, window_bg.rgb, '') 0746 check_items(button_hover.rgb, window_bg.rgb, '-hover') 0747 check_items(button_active.rgb, window_bg.rgb, '-active') 0748 check_items(check_color.insensitive, window_bg.rgb, 0749 '-insensitive', border_color.insensitive_alpha) 0750 check_items(check_color.inactive, window_bg.rgb, 0751 '-backdrop', border_color.inactive_alpha) 0752 check_items(check_color.inactive_insensitive, window_bg.rgb, 0753 '-backdrop-insensitive', border_color.inactive_insensitive_alpha) 0754 0755 buttons(window_bg.rgb, border_color.rgb, button_bg.gradient(), '') 0756 buttons(window_bg.rgb, button_hover.rgb, button_bg.gradient(), '-hover') 0757 buttons(window_bg.rgb, button_hover.rgb, 0758 button_hover.gradient('active'), '-active') 0759 buttons(window_bg.rgb, border_color.rgb, 0760 button_bg.gradient(alpha=button_bg.insensitive_alpha), '-insensitive', 0761 border_color.insensitive_alpha) 0762 0763 togglebuttons(window_bg.rgb, border_color.rgb, button_bg.gradient(), '') 0764 togglebuttons(window_bg.rgb, button_hover.rgb, button_bg.gradient(), '-hover') 0765 togglebuttons(window_bg.rgb, button_hover.rgb, 0766 button_hover.gradient('active'), '-active') 0767 togglebuttons(window_bg.rgb, border_color.rgb, 0768 button_bg.gradient(alpha=button_bg.insensitive_alpha), 0769 '-insensitive', border_color.insensitive_alpha) 0770 0771 scale_slider(window_bg.rgb, border_color.rgb, button_bg.gradient(), '') 0772 scale_slider(window_bg.rgb, button_hover.rgb, button_bg.gradient(), '-hover') 0773 scale_slider(window_bg.rgb, button_active.rgb, button_bg.gradient(), '-active') 0774 scale_slider(window_bg.rgb, border_color.rgb, 0775 button_bg.gradient(alpha=button_bg.insensitive_alpha), 0776 '-insensitive', border_color.insensitive_alpha) 0777 scale_trough(border_color.rgb) 0778 0779 tabs(border_color.rgb, window_bg.rgb, '-active') 0780 tabs(window_fg.rgb, window_bg.rgb, '-inactive') 0781 0782 arrows(button_fg.rgb, '') 0783 arrows(button_hover.rgb, '-hover') 0784 arrows(button_active.rgb, '-active') 0785 arrows(button_fg.insensitive, '-insensitive', button_fg.insensitive_alpha) 0786 menu_arrow(window_fg.rgb, '') 0787 menu_arrow(selection_fg.rgb, '-selected') 0788 menu_arrow(window_fg.insensitive, '-insensitive', window_fg.insensitive_alpha) 0789 0790 scrollbar_slider(view_active.rgb, view_hover.rgb, view_fg.rgb) 0791 scrollbar_trough(window_fg.rgb) 0792 0793 titlebuttons(titlebutton.rgb, titlebutton.rgb, '') 0794 titlebuttons(titlebutton.rgb, closebutton_hover.rgb, '-hover') 0795 titlebuttons(titlebutton_active.rgb, closebutton_active.rgb, '-active') 0796 titlebuttons(titlebutton_inactive.rgb, titlebutton_inactive.rgb, '-backdrop') 0797 titlebuttons(titlebutton_inactive.rgb, 0798 closebutton_hover.rgb, '-hover-backdrop') 0799 titlebuttons(titlebutton_inactive_active.rgb, 0800 closebutton_active.rgb, '-active-backdrop') 0801 0802 entry(window_bg.rgb, border_color.rgb, view_bg.rgb, '') 0803 entry(window_bg.rgb, view_active.rgb, view_bg.rgb, '-active') 0804 entry(window_bg.rgb, border_color.insensitive, None, 0805 '-insensitive', border_color.insensitive_alpha) 0806 0807 progressbar(selection_bg.rgb, mix(window_fg.rgb, window_bg.rgb, 0.3)) 0808 0809 mixed(border_color.rgb, window_bg.rgb, button_active.rgb) 0810 0811 toolbar(border_color.rgb, window_bg.rgb, button_hover.rgb) 0812 0813 gtk2 = open(os.path.join(args.gtk2_dir, 'gtkrc'), 'w') 0814 gtk2.write( 0815 '# Theme: Breeze-gtk\n' 0816 '# Description: Breeze theme for GTK+2.0\n' 0817 '\n' 0818 'gtk-color-scheme = "text_color:' + html(window_fg.rgb) + '"\n' 0819 'gtk-color-scheme = "base_color:' + html(view_bg.rgb) + '"\n' 0820 'gtk-color-scheme = "insensitive_base_color:' + 0821 html(view_bg.insensitive) + '"\n' 0822 'gtk-color-scheme = "fg_color:' + html(window_fg.rgb) + '"\n' 0823 'gtk-color-scheme = "bg_color:' + html(window_bg.rgb) + '"\n' 0824 'gtk-color-scheme = "selected_fg_color:' + html(selection_fg.rgb) + '"\n' 0825 'gtk-color-scheme = "selected_bg_color:' + html(selection_bg.rgb) + '"\n' 0826 'gtk-color-scheme = "button_fg_color:' + html(button_fg.rgb) + '"\n' 0827 'gtk-color-scheme = "tooltip_fg_color:' + html(tooltip_fg.rgb) + '"\n' 0828 'gtk-color-scheme = "tooltip_bg_color:' + html(tooltip_bg.rgb) + '"\n' 0829 'gtk-color-scheme = "insensitive_fg_color:' + 0830 html(mix(window_fg.insensitive, window_bg.rgb, 0831 window_fg.insensitive_alpha)) + '"\n' 0832 'gtk-color-scheme = "insensitive_text_color:' + 0833 html(mix(view_fg.insensitive, view_bg.rgb, 0834 view_fg.insensitive_alpha)) + '"\n' 0835 'gtk-color-scheme = "button_insensitive_fg_color:' + 0836 html(mix(button_fg.insensitive, button_bg.rgb, 0837 button_fg.insensitive_alpha)) + '"\n' 0838 'gtk-color-scheme = "button_active:' + html(button_active.rgb) + '"\n' 0839 'gtk-color-scheme = "border_color:' + html(border_color.rgb) + '"\n' 0840 '\n' 0841 'include "widgets/default"\n' 0842 'include "widgets/buttons"\n' 0843 'include "widgets/menu"\n' 0844 'include "widgets/entry"\n' 0845 'include "widgets/notebook"\n' 0846 'include "widgets/range"\n' 0847 'include "widgets/scrollbar"\n' 0848 'include "widgets/toolbar"\n' 0849 'include "widgets/progressbar"\n' 0850 'include "widgets/misc"\n' 0851 'include "widgets/styles"\n' 0852 ) 0853 gtk2.close() 0854 0855 gtk3 = open(os.path.join(args.gtk3_scss_dir, '_global.scss'), 'w') 0856 for key in sorted(_colors): 0857 if key == 'DisabledColor' or key == 'InactiveColor': 0858 gtk3.write('${0}:rgb({1});\n'.format(key, _colors[key])) 0859 elif 'Disabled' in key or 'Inactive' in key: 0860 gtk3.write('${0}:{1};\n'.format(key, _colors[key])) 0861 elif re.match('[0-9]+,[0-9]+,[0-9]+', _colors[key]): 0862 gtk3.write('${0}:rgb({1});\n'.format(key, _colors[key])) 0863 gtk3.close()