def get(self, index): """ Fetches a color from the palette based on index value. :param index: int, the index of the color to fetch. :return: Color, the color at the specified index. """ if (not isinstance(index, int) or 0 > index >= len(self.__color_palette)): show_error('Tried getting an index that\'s not in the palette!') return return self.__color_palette[index]
def display_message(self, message): """ Shows a temporary message that is removed after the time expires. :param message: str, the message to display. """ if not isinstance(message, str): show_error('Invalid message text received!') return self.__palette_display_label.config(text=message) self.__main_window.after( 2000, lambda: self.__palette_display_label.config(text=''))
def set_picked_color(self, picked_color): """ Sets the provided color as the picked color in the palette. :return: Palette, the palette with currently picked color. """ if (not isinstance(picked_color, Color) or picked_color not in self.__color_palette): show_error('Tried to set invalid picked color!') return self.__picked_color = picked_color return self
def to_tint(self, tint_percentage): """ Tints (lightens) the palette colors according to provided tint amount. :param tint_percentage: int, the percentage of tint to apply. :return: Palette, the tinted color palette. """ if (not isinstance(tint_percentage, int) or 0 > tint_percentage > 100): show_error('Invalid tint percentage received!') return for color in self.values(): color.tint(tint_percentage) return self
def to_tone(self, tone_percentage): """ Tones (saturates) the palette colors according to provided tone amount. :param tone_percentage: int, the percentage of tone to apply. :return: Palette, the toned color palette. """ if (not isinstance(tone_percentage, int) or 0 > tone_percentage > 100): show_error('Invalid tone percentage received!') return for color in self.values(): color.tone(tone_percentage) return self
def set_color_scheme(self, color_scheme_key): """ Sets the color scheme for the palette according to provided color scheme key. :param color_scheme_key: str, the color scheme to set. :return: Palette, the palette with set color scheme. """ if (not isinstance(color_scheme_key, str) or color_scheme_key not in self.__COLOR_SCHEMES): show_error(f'Invalid color scheme {color_scheme_key} provided!') return self.__color_scheme = color_scheme_key return self
def to_shade(self, shade_percentage): """ Shades (darkens) the palette colors according to provided shade amount. :param shade_percentage: int, the percentage of shade to apply. :return: Palette, the shaded color palette. """ if (not isinstance(shade_percentage, int) or 0 > shade_percentage > 100): show_error('Invalid shade percentage received!') return for color in self.values(): color.shade(shade_percentage) return self
def export_palette_to_file(self): """ Prompts for location to save the file. Creates a file and converts the current palette to a string representation to write it to the file. """ try: date_and_time = str(datetime.now()).split(':') filename = f'Palette {date_and_time[0]}.{date_and_time[1]}.txt' file = asksaveasfile(mode='w', defaultextension='.txt', initialfile=filename) if file is None: return content = 'Colorian Palette\n' + \ '================\n\n' color_scheme = \ self.__selected_color_wheel_palette.get_color_scheme() content += \ color_scheme + ' color scheme\n' + \ ('-' * (len(color_scheme) + 13)) + '\n' for color in ( self.__selected_color_wheel_palette.get_scheme_colors()): content += str(color) + '\n' content += '\n' content += 'Color wheel\n' + \ '-----------\n' for color in self.__selected_color_wheel_palette.values(): content += str(color) + '\n' print(content, file=file) file.close() except OSError: show_error('Exporting to file ran into trouble!') return self.display_message('Palette exported!')
def set_color_wheel(self, color_wheel_key): """ Sets the colors of the palette according to provided color wheel key. :param color_wheel_key: str, the color wheel to set. :return: Palette, the palette with set color wheel. """ if (not isinstance(color_wheel_key, str) or color_wheel_key not in self.__color_wheels): show_error(f'Invalid color wheel key provided!') return self.__color_palette = self.__color_wheels[color_wheel_key] self.__color_wheel = color_wheel_key return self
def find_by_name(self, name): """ Fetches a color from the palette by name. :name: str, the name of the color to search for. :return: Color, the color with the searched name. """ if not isinstance(name, str): show_error('Invalid color name to search for received!') return for color_in_palette in self.values(): if name == color_in_palette.name(): return color_in_palette show_error('The searched color couldn\'t be found!') return
def sort_color_wheel(self, first_color): """ Organizes the palette to color wheel order starting with provided root color. :param first_color: Color, the root color to be arranged as first. :return: Palette, the sorted palette. """ if (not isinstance(first_color, Color) or first_color not in self.__color_palette): show_error('Invalid color to sort by provided!') return self.__color_palette = \ self.__color_palette[self.__color_palette.index(first_color):] + \ self.__color_palette[:self.__color_palette.index(first_color)] return self
def clamp_fraction_value(self, color_value): """ Clamps the provided fraction value to valid range 0.0-1.0. Converts the value to a float if int is provided. :param color_value: float, the value to clamp. :return: float, the value in 0.0-1.0. """ if (not isinstance(color_value, float) and not isinstance(color_value, int)): show_error('Invalid fraction value to clamp received!') return if color_value < 0.0: return 0.0 elif color_value > 1.0: return 1.0 else: return float(color_value)
def clamp_rgb_value(self, rgb_value): """ Clamps the RGB value to valid range 0-255. Converts the value to an int if a float is provided. :param rgb_value: float, the value to clamp. :return: int, the RGB value in 0-255. """ if (not isinstance(rgb_value, float) and not isinstance(rgb_value, int)): show_error('Invalid RGB value to clamp received!') return if rgb_value < 0: return 0 elif rgb_value > 255: return 255 else: return round(rgb_value)
def shade(self, shade_percentage): """ Modifies the shade of the color as in adds black to it. :param shade_percentage: int, the percentage of shading to apply. :return: Color, the shaded color. """ if (not isinstance(shade_percentage, int) or 0 > shade_percentage > 100): show_error('Invalid shade parameter received!') return shade_fraction = shade_percentage / 100 self.__red = self.clamp_rgb_value(self.__red * (1 - shade_fraction)) self.__green = self.clamp_rgb_value(self.__green * (1 - shade_fraction)) self.__blue = self.clamp_rgb_value(self.__blue * (1 - shade_fraction)) return self
def brightness(self, brightness_amount): """ Modify the luminance aka brightness of the color in relation to the colors original luminance amount. Maintains the colors original hue. :param brightness_amount: float, the amount of brightness 0.0-255.0 """ if (not isinstance(brightness_amount, float)): show_error('Invalid brightness value received!') return brightness_change = brightness_amount - self.__original_brightness new_red_rgb_value = self.__original_red + brightness_change new_green_rgb_value = self.__original_green + brightness_change new_blue_rgb_value = self.__original_blue + brightness_change self.__red = self.clamp_rgb_value(new_red_rgb_value) self.__green = self.clamp_rgb_value(new_green_rgb_value) self.__blue = self.clamp_rgb_value(new_blue_rgb_value)
def tint(self, tint_percentage): """ Modifies the tint of the color as in adds white to it. :param tint_percentage: int, the percentage of tinting to apply. :return: Color, the tinted color. """ if (not isinstance(tint_percentage, int) or 0 > tint_percentage > 100): show_error('Invalid tint parameter received!') return tint_fraction = tint_percentage / 100 self.__red = self.clamp_rgb_value(self.__red + (255 - self.__red) * tint_fraction) self.__green = self.clamp_rgb_value(self.__green + (255 - self.__green) * tint_fraction) self.__blue = self.clamp_rgb_value(self.__blue + (255 - self.__blue) * tint_fraction) return self
def tone(self, tone_percentage): """ Modifies the saturation aka tone of the color as in adds gray to it. :param tone_percentage: int, the percentage of toning to apply. :return: Color, the toned color. """ if (not isinstance(tone_percentage, int) or 0 > tone_percentage > 100): show_error('Invalid tone parameter received!') return tone_amount = tone_percentage / 100 red_amount = self.__red / 255 green_amount = self.__green / 255 blue_amount = self.__blue / 255 color_hsv = colorsys.rgb_to_hsv(red_amount, green_amount, blue_amount) saturation_amount = self.clamp_fraction_value(color_hsv[1] + (color_hsv[1] * tone_amount)) toned_color_hsv = (color_hsv[0], saturation_amount, color_hsv[2]) toned_rgb_color = colorsys.hsv_to_rgb(toned_color_hsv[0], toned_color_hsv[1], toned_color_hsv[2]) toned_rgb_values = (self.clamp_rgb_value(toned_rgb_color[0] * 255), self.clamp_rgb_value(toned_rgb_color[1] * 255), self.clamp_rgb_value(toned_rgb_color[2] * 255)) self.__red = toned_rgb_values[0] self.__green = toned_rgb_values[1] self.__blue = toned_rgb_values[2] return self
def __init__(self, color_wheel='RYB'): """ Creates a Palette instance that represents a group of Color instances. the palette has colors from a specific color wheel, a color scheme and a picked color. """ self.__RYB_COLORS = [ Color(254, 39, 18, 'Red'), Color(252, 96, 10, 'Red-orange'), Color(251, 153, 2, 'Orange'), Color(252, 204, 26, 'Yellow-orange'), Color(254, 254, 51, 'Yellow'), Color(178, 215, 50, 'Yellow-green'), Color(102, 176, 50, 'Green'), Color(52, 124, 152, 'Blue-green'), Color(2, 71, 254, 'Blue'), Color(68, 36, 214, 'Blue-purple'), Color(134, 1, 175, 'Purple'), Color(194, 20, 96, 'Red-purple') ] self.__RGB_COLORS = [ Color(255, 0, 0, 'Red'), Color(255, 128, 0, 'Orange'), Color(255, 255, 0, 'Yellow'), Color(128, 255, 0, 'Chartreuse Green'), Color(0, 255, 0, 'Green'), Color(0, 255, 128, 'Spring Green'), Color(0, 255, 255, 'Cyan'), Color(0, 128, 255, 'Azure'), Color(0, 0, 255, 'Blue'), Color(128, 0, 255, 'Violet'), Color(255, 0, 255, 'Magenta'), Color(255, 0, 128, 'Rose') ] self.__CMYK_COLORS = [ Color(0, 255, 255, 'Cyan'), Color(0, 128, 255, 'Azure'), Color(0, 0, 255, 'Blue'), Color(128, 0, 255, 'Violet'), Color(255, 0, 255, 'Magenta'), Color(255, 0, 128, 'Rose'), Color(255, 0, 0, 'Red'), Color(255, 128, 0, 'Orange'), Color(255, 255, 0, 'Yellow'), Color(128, 255, 0, 'Chartreuse Green'), Color(0, 255, 0, 'Green'), Color(0, 255, 128, 'Spring Green') ] self.__color_wheels = { 'RYB': self.__RYB_COLORS, 'RGB': self.__RGB_COLORS, 'CMYK': self.__CMYK_COLORS } """ Color schemes are presented as arrays with each 12 hue in the color wheel representing index values 0-11 with root color being value 0. """ self.__COLOR_SCHEMES = { 'Analogous': [0, 1, 11], 'Complementary': [0, 6], 'Triadic': [0, 4, 8], 'Tetradic': [0, 2, 6, 8], 'Square': [0, 3, 6, 9], 'Split-complementary': [0, 5, 7], 'Double split-complementary': [0, 1, 5, 7, 11], 'Clash': [0, 2, 8], 'Intermediate': [0, 2, 4, 6, 8, 10] } if (not isinstance(color_wheel, str) or color_wheel.upper() not in self.__color_wheels): show_error(f'Value {color_wheel} is not a valid color wheel!') return self.__color_palette = self.__color_wheels[color_wheel.upper()] self.__color_wheel = color_wheel.upper() self.__color_scheme = list(self.__COLOR_SCHEMES.keys())[0] self.__picked_color = self.__color_palette[0]
def log_e(error): # print error main.show_error(error)