def _get_paint_chip_shadow(color): """Paint chip shadow edge color""" shadow = HCYColor(color=color) ky = gui.style.PAINT_CHIP_SHADOW_HCY_Y_MULT kc = gui.style.PAINT_CHIP_SHADOW_HCY_C_MULT shadow.y = clamp(shadow.y * ky, 0, 1) shadow.c = clamp(shadow.c * kc, 0, 1) return shadow
def _get_paint_chip_highlight(color): """Paint chip highlight edge color""" highlight = HCYColor(color=color) ky = gui.style.PAINT_CHIP_HIGHLIGHT_HCY_Y_MULT kc = gui.style.PAINT_CHIP_HIGHLIGHT_HCY_C_MULT highlight.y = clamp(highlight.y * ky, 0, 1) highlight.c = clamp(highlight.c * kc, 0, 1) return highlight
def __motion_notify_cb(self, widget, event): """Button1 motion handler.""" pos = event.x, event.y if (self.__button_down is not None) and self.__button_down == 1: if self.IS_DRAG_SOURCE: if not self.__drag_start_color: return False start_pos = self.__drag_start_pos dx = pos[0] - start_pos[0] dy = pos[1] - start_pos[1] dist = math.hypot(dx, dy) if (dist > self._drag_threshold) and self.__drag_start_color: logger.debug( "Start drag (dist=%0.3f) with colour %r", dist, self.__drag_start_color, ) self.__drag_start_color = None self.drag_begin_with_coordinates( targets = Gtk.TargetList.new([ Gtk.TargetEntry.new(*e) for e in self._DRAG_TARGETS ]), actions = Gdk.DragAction.MOVE | Gdk.DragAction.COPY, button = 1, event = event, x = event.x, y = event.y, ) return True # a drag was just started else: # Non-drag-source widgets update the color continuously while # the mouse button is held down and the pointer moved. color = self.get_color_at_position(event.x, event.y) self.set_managed_color(color) # Relative chroma/luma/hue bending with other buttons. elif ((self.__button_down is not None) and self.ALLOW_HCY_TWEAKING and self.__button_down > 1): if self.__drag_start_color is None: return False col = HCYColor(color=self.__drag_start_color) alloc = self.get_allocation() w, h = alloc.width, alloc.height size = max(w, h) ex, ey = event.x, event.y sx, sy = self.__drag_start_pos dx, dy = sx - ex, sy - ey # Pick a dimension to tweak if event.state & Gdk.ModifierType.SHIFT_MASK: bend = "chroma" dy = -dy elif event.state & Gdk.ModifierType.CONTROL_MASK: bend = "hue" else: bend = "luma" dy = -dy # Interpretation of dx depends on text direction if widget.get_direction() == Gtk.TextDirection.RTL: dx = -dx # Use the delta with the largest absolute value # FIXME: this has some jarring discontinities dd = dx if abs(dx) > abs(dy) else dy if bend == "chroma": c0 = clamp(col.c, 0., 1.) p = (c0 * size) - dd col.c = clamp(p / size, 0., 1.) elif bend == "hue": h0 = clamp(col.h, 0., 1.) p = (h0 * size) - dd h = p / size while h < 0: h += 1.0 col.h = h % 1.0 else: # luma y0 = clamp(col.y, 0., 1.) p = (y0 * size) - dd col.y = clamp(p / size, 0., 1.) self.set_managed_color(col) # Let other registered handlers run, normally. return False
def __motion_notify_cb(self, widget, event): """Button1 motion handler.""" pos = event.x, event.y if self.__button_down == 1: if self.IS_DRAG_SOURCE: if not self.__drag_start_pos: return False start_pos = self.__drag_start_pos dx = pos[0] - start_pos[0] dy = pos[1] - start_pos[1] dist = math.hypot(dx, dy) if (dist > self._drag_threshold) and self.__drag_start_color: logger.debug( "Start drag (dist=%0.3f) with colour %r", dist, self.__drag_start_color, ) self.__drag_start_color = None self.drag_begin_with_coordinates( targets = Gtk.TargetList.new([ Gtk.TargetEntry.new(*e) for e in self._DRAG_TARGETS ]), actions = Gdk.DragAction.MOVE | Gdk.DragAction.COPY, button = 1, event = event, x = event.x, y = event.y, ) return True # a drag was just started else: # Non-drag-source widgets update the color continuously while # the mouse button is held down and the pointer moved. color = self.get_color_at_position(event.x, event.y) self.set_managed_color(color) # Relative chroma/luma/hue bending with other buttons. elif self.ALLOW_HCY_TWEAKING and self.__button_down > 1: if self.__drag_start_color is None: return False col = HCYColor(color=self.__drag_start_color) alloc = self.get_allocation() w, h = alloc.width, alloc.height size = max(w, h) ex, ey = event.x, event.y sx, sy = self.__drag_start_pos dx, dy = sx - ex, sy - ey # Pick a dimension to tweak if event.state & Gdk.ModifierType.SHIFT_MASK: bend = "chroma" dy = -dy elif event.state & Gdk.ModifierType.CONTROL_MASK: bend = "hue" else: bend = "luma" dy = -dy # Interpretation of dx depends on text direction if widget.get_direction() == Gtk.TextDirection.RTL: dx = -dx # Use the delta with the largest absolute value # FIXME: this has some jarring discontinities dd = dx if abs(dx) > abs(dy) else dy if bend == "chroma": c0 = clamp(col.c, 0., 1.) p = (c0 * size) - dd col.c = clamp(p / size, 0., 1.) elif bend == "hue": h0 = clamp(col.h, 0., 1.) p = (h0 * size) - dd h = p / size while h < 0: h += 1.0 col.h = h % 1.0 else: # luma y0 = clamp(col.y, 0., 1.) p = (y0 * size) - dd col.y = clamp(p / size, 0., 1.) self.set_managed_color(col) # Let other registered handlers run, normally. return False
def color_at_normalized_polar_pos(self, r, theta): col = HCYColor(color=self.get_managed_color()) col.h = theta col.c = r return col
def _palette_render(palette, cr, rows, columns, swatch_size, bg_color, offset_x=0, offset_y=0, rtl=False): """Renders a Palette according to a precalculated grid. :param cr: a Cairo context :param int rows: number of rows in the layout :param int columns: number of columns in the layout :param int swatch_size: size of each swatch, in pixels :param lib.color.UIColor bg_color: color used when rendering the patterned placeholder for an empty palette slot. :param bool rtl: layout direction: set to True to render right to left, instead of left to right. Currently ignored. """ HIGHLIGHT_DLUMA = 0.05 if len(palette) == 0: return if rows is None or columns is None: return cr.save() cr.translate(offset_x, offset_y) # Sizes and colors swatch_w = swatch_h = swatch_size light_col = HCYColor(color=bg_color) light_col.y += HIGHLIGHT_DLUMA dark_col = HCYColor(color=bg_color) dark_col.y -= HIGHLIGHT_DLUMA if light_col.y >= 1: light_col.y = 1.0 dark_col.y = 1.0 - (2*HIGHLIGHT_DLUMA) if dark_col.y <= 0: dark_col.y = 0.0 light_col.y = 0.0 + (2*HIGHLIGHT_DLUMA) # Upper left outline (bottom right is covered below by the # individual chips' shadows) ul_col = HCYColor(color=bg_color) ul_col.y *= 0.75 ul_col.c *= 0.5 cr.set_line_join(cairo.LINE_JOIN_ROUND) cr.set_line_cap(cairo.LINE_CAP_ROUND) cr.set_source_rgb(*ul_col.get_rgb()) cr.move_to(0.5, rows*swatch_h - 1) cr.line_to(0.5, 0.5) row1cells = min(columns, len(palette)) # needed? cr.line_to(row1cells*swatch_w - 1, 0.5) cr.set_line_width(2) cr.stroke() # Draw into the predefined grid r = c = 0 cr.set_line_width(1.0) cr.set_line_cap(cairo.LINE_CAP_SQUARE) for col in palette.iter_colors(): s_x = c*swatch_w s_y = r*swatch_h s_w = swatch_w s_h = swatch_h # Select fill bg and pattern fg colors, Tango-style edge highlight # and lower-right shadow. if col is None: # Empty slot, fill with a pattern hi_rgb = light_col.get_rgb() fill_bg_rgb = dark_col.get_rgb() fill_fg_rgb = light_col.get_rgb() sh_col = HCYColor(color=bg_color) sh_col.y *= 0.75 sh_col.c *= 0.5 sh_rgb = sh_col.get_rgb() else: # Color swatch hi_col = HCYColor(color=col) hi_col.y = min(hi_col.y * 1.1, 1) hi_col.c = min(hi_col.c * 1.1, 1) sh_col = HCYColor(color=col) sh_col.y *= 0.666 sh_col.c *= 0.5 hi_rgb = hi_col.get_rgb() fill_bg_rgb = col.get_rgb() fill_fg_rgb = None sh_rgb = sh_col.get_rgb() # Draw the swatch / color chip cr.set_source_rgb(*sh_rgb) cr.rectangle(s_x, s_y, s_w, s_h) cr.fill() cr.set_source_rgb(*fill_bg_rgb) cr.rectangle(s_x, s_y, s_w-1, s_h-1) cr.fill() if fill_fg_rgb is not None: s_w2 = int((s_w-1) / 2) s_h2 = int((s_h-1) / 2) cr.set_source_rgb(*fill_fg_rgb) cr.rectangle(s_x, s_y, s_w2, s_h2) cr.fill() cr.rectangle(s_x+s_w2, s_y+s_h2, s_w2, s_h2) cr.fill() cr.set_source_rgb(*hi_rgb) cr.rectangle(s_x+0.5, s_y+0.5, s_w-2, s_h-2) cr.stroke() c += 1 if c >= columns: c = 0 r += 1 cr.restore()
def get_color_for_bar_amount(self, amt): col = HCYColor(color=self.get_managed_color()) col.c = amt return col