示例#1
0
def hex_to_colour(h, _try_alt=True):
    """Convert a hex string to colour.
    Supports inputs as #RGB, #RGBA, #RRGGBB and #RRGGBBAA.
    If a longer string is invalid, it will try lower lengths.
    """
    if h.startswith('#'):
        h = h[1:]
    h_len = len(h)
    if h_len >= 8:
        try:
            return (8, [int(h[i*2:i*2+2], 16) for i in range(4)])
        except ValueError:
            if _try_alt:
                return hex_to_colour(h[:6])
    elif h_len >= 6:
        try:
            return (6, [int(h[i*2:i*2+2], 16) for i in range(3)] + [255])
        except ValueError:
            if _try_alt:
                return hex_to_colour(h[:4])
    elif h_len >= 4:
        try:
            return (3, [16*j+j for j in (int(h[i:i+1], 16) for i in range(4))])
        except ValueError:
            if _try_alt:
                return hex_to_colour(h[:3])
    elif h_len >= 3:
        try:
            return (3, [16*j+j for j in (int(h[i:i+1], 16) for i in range(3))] + [255])
        except ValueError:
            pass
    return (0, None)
示例#2
0
    def __init__(self, min_amount, max_amount, colours, offset=0, colour_steps=256, loop=False, cache=None, background=None):
        
        if min_amount >= max_amount:
            colours = [colours[0]]
            max_amount = min_amount + 1
        self.background = background
        self.max = max_amount
        self.min = min_amount
        self.amount = (self.min, self.max)
        self.amount_diff = self.max - self.min
        self.colours = colours
        self.offset = offset
        self.loop = loop
        self._len = len(colours)
        self._len_m = self._len - 1

        self.steps = colour_steps * self._len
        self._step_size = self.amount_diff / self.steps
        
        #Cache results for quick access
        if cache is None:
            self.cache = []
            for i in range(self.steps + 1):
                self.cache.append(self.calculate_colour(self.min + i * self._step_size))
        else:
            self.cache = cache
示例#3
0
 def _preview_gradient(self, width, height):
     """Draw a gradient to test the colours."""
     from PIL import Image
     
     colours = ColourRange(0, width, self.colours)
     
     image = Image.new('RGB', (width, height))
     pixels = image.load()
     
     height_range = range(height)
     for x in range(width):
         colour = colours[x]
         for y in range(height):
             pixels[x, y] = colour
             
     return image
示例#4
0
    def __init__(self, x, y, x_len, y_len=None):
        if y_len is None:
            y_len = x_len
        self.x = x
        self.y = y
        self.x_len = x_len
        self.y_len = y_len
        x_range = tuple(range(x, x + x_len))
        y_range = tuple(range(y, y + y_len))

        #Cache range (and fix error with radius of 0)
        i_start = KEY_CORNER_RADIUS + 1
        i_end = -KEY_CORNER_RADIUS or max(x + x_len, y + y_len)
        self.cache = {
            'x': x_range[i_start:i_end],
            'y': y_range[i_start:i_end],
            'x_start': x_range[1:i_start],
            'y_start': y_range[1:i_start],
            'x_end': x_range[i_end:],
            'y_end': y_range[i_end:]
        }
示例#5
0
def fix_poe_mine_build(profile_name, numpad_key):
    try:
        _num = 'NUM{}'.format(int(numpad_key))
    except ValueError:
        return False
    data = LoadData(profile_name, _reset_sessions=False)

    #Make sure record exists, quick delete if issue is obvious (0 press >0 held)
    try:
        if not data['Keys']['All']['Pressed'][_num]:
            raise KeyError

    except KeyError:
        try:
            del data['Keys']['All']['Held'][_num]
        except KeyError:
            pass

    else:
        #Count the other numpad items
        total = {'pressed': 0, 'held': 0, 'count': 0}
        for i in range(1, 10):
            if i == numpad_key:
                continue

            num = 'NUM{}'.format(i)
            try:
                total['pressed'] += data['Keys']['All']['Pressed'][num]
                total['held'] += data['Keys']['All']['Held'][num]
            except KeyError:
                pass
            else:
                total['count'] += 1

        #Get the average time the numpad is pressed for
        try:
            average_press_time = total['held'] / total['pressed']
        except ZeroDivisionError:
            average_press_time = 0
            Message('Unable to get an average as no other keypad data exists.')
            result = input(
                'Do you want to delete the numpad key instead (y/n)? ')
            if not is_yes(result):
                return False

        #Assign to numpad key
        new_held_time = round_int(data['Keys']['All']['Pressed'][_num] *
                                  average_press_time)
        data['Keys']['All']['Held'][_num] = new_held_time

    return save_data(profile_name, data)
示例#6
0
    def outline(self, border=0, drop_shadow=1):
        coordinates = []
        if not border:
            return coordinates

        #Rounded corners
        top_left = [
            self._circle_offset(x, y, 'TopLeft')
            for x, y in _CIRCLE['TopLeft']['Outline']
        ]
        top_right = [
            self._circle_offset(x, y, 'TopRight')
            for x, y in _CIRCLE['TopRight']['Outline']
        ]
        bottom_left = [
            self._circle_offset(x, y, 'BottomLeft')
            for x, y in _CIRCLE['BottomLeft']['Outline']
        ]
        bottom_right = [
            self._circle_offset(x, y, 'BottomRight')
            for x, y in _CIRCLE['BottomRight']['Outline']
        ]

        #Rounded corner thickness
        #This is a little brute force but everything else I tried didn't work
        r = tuple(range(border))
        for x, y in top_left:
            coordinates += [(x - i, y - j) for i in r for j in r]
        for x, y in top_right:
            coordinates += [(x + i, y - j) for i in r for j in r]
        for x, y in bottom_left:
            coordinates += [(x - i, y + j) for i in r for j in r]
        for x, y in bottom_right:
            coordinates += [(x + i, y + j) for i in r for j in r]

        #Straight lines
        for i in r:
            coordinates += [(_x, self.y - i) for _x in self.cache['x']]
            coordinates += [(_x, self.y + self.y_len + i)
                            for _x in self.cache['x']]
            coordinates += [(self.x - i, _y) for _y in self.cache['y']]
            coordinates += [(self.x + self.x_len + i, _y)
                            for _y in self.cache['y']]

        return coordinates
示例#7
0
def upscale_arrays_to_resolution(arrays, target_resolution, skip=[]):
    """Upscale a dict of arrays to a certain resolution.
    The dictionary key must be a resolution,
    and the values can either be an array or list of arrays.
    
    Use skip to ignore array indexes in the list.
    """
    if isinstance(skip, int):
        skip = [skip]
    skip = set(skip)

    #Count number of arrays
    num_arrays = 0
    for resolution, array_list in get_items(arrays):
        if isinstance(array_list, (list, tuple)):
            array_len = len(array_list)
            num_arrays += array_len - len(
                [i for i in range(array_len) if i in skip])
        elif 0 not in skip:
            num_arrays += 1

    #Upscale each array
    Message('Upscaling arrays to {}x{}...'.format(target_resolution[0],
                                                  target_resolution[1]))
    processed = 0
    output = []
    for resolution, array_list in get_items(arrays):

        if not isinstance(array_list, (list, tuple)):
            array_list = [array_list]

        for i, array in enumerate(array_list):
            if i in skip:
                continue
            processed += 1
            Message('Processing array for {}x{} ({}/{})'.format(
                resolution[0], resolution[1], processed, num_arrays))
            zoom_factor = (target_resolution[1] / resolution[1],
                           target_resolution[0] / resolution[0])
            upscaled = upscale(array, zoom_factor)
            output.append(upscaled)
    return output
示例#8
0
def _save_wrapper(q_send, program_name, data, new_program=False):
    """Handle saving the data files from the thread."""

    if program_name is not None and program_name[0] == DISABLE_TRACKING:
        return

    NOTIFY(SAVE_PREPARE)
    NOTIFY.send(q_send)
    saved = False

    #Get how many attempts to use
    if new_program:
        max_attempts = CONFIG['Save']['MaximumAttemptsSwitch']
    else:
        max_attempts = CONFIG['Save']['MaximumAttemptsNormal']

    compressed_data = prepare_file(data)

    #Attempt to save
    NOTIFY(SAVE_START)
    NOTIFY.send(q_send)
    for i in range(max_attempts):
        if save_data(program_name, compressed_data, _compress=False):
            NOTIFY(SAVE_SUCCESS)
            NOTIFY.send(q_send)
            saved = True
            break

        else:
            if max_attempts == 1:
                NOTIFY(SAVE_FAIL)
                return
            NOTIFY(SAVE_FAIL_RETRY, CONFIG['Save']['WaitAfterFail'], i,
                   max_attempts)
            NOTIFY.send(q_send)
            time.sleep(CONFIG['Save']['WaitAfterFail'])

    if not saved:
        NOTIFY(SAVE_FAIL_END)