Пример #1
0
 def update_colour(self):
     res, _ = colorchooser.askcolor(self.colour_button['bg'])
     if res is None:
         return
     res = np.array(res)
     self.colour_button['bg'] = util.convert_colour(res.astype(int))
     self.colour_button['activebackground'] = util.convert_colour((res * 0.9).astype(int))
Пример #2
0
    def __init__(self):
        super().__init__()
        if len(self.objects) > 1:
            self.cancel()
            set_error('Only 1 polygon can be edited at once')
            raise StopAction()
        if self.objects[0]['type'] == 'circle':
            self.cancel()
            set_error("Circles can't be edited")
            raise StopAction()

        shared.selected_colour = col = self.objects[0]['colour']
        shared.colour_button['bg'] = util.convert_colour(col)
        shared.colour_button['activebackground'] = util.convert_colour(
            np.multiply(col, 15 / 16).astype(int))
        self.selection = None
Пример #3
0
def create_preview(filename):
    with open(filename) as f:
        level = json.load(f)
    scale = 1/10

    size = np.array([140,100])
    screen = pygame.Surface(size)
    screen.fill((255,255,255))
    centre = np.array(level.get('spawn', (0,0))) - size / 2 / scale

    for obj in level['objects']:
        colour = obj['colour']
        if obj['type'] == 'circle':
            pos = (obj['pos'] - centre) * scale
            pygame.draw.circle(screen, colour, pos.astype(int), round(obj['radius'] * scale))
        elif obj['type'] == 'polygon':
            points = [((pos - centre) * scale).astype(int) for pos in obj['points']]
            pygame.draw.polygon(screen, colour, points)
        elif obj['type'] == 'text':
            drawn = font.create_character(obj['char'], obj['size'] * scale)

            offset = drawn.offset + (obj['pos'] - centre) * scale
            for tri in drawn.triangles:
                pygame.draw.polygon(screen, colour, (np.array(tri) + offset).astype(int))

    image = tk.PhotoImage()
    for x in range(size[0]):
        for y in range(size[1]):
            colour = screen.get_at((x,y))[:3]
            image.put(util.convert_colour(colour), to=(x,y))
    return image
Пример #4
0
    def generate_list_entry(self, player):
        var = tk.StringVar(value=int(player['active']))
        def onchange(*_):
            value = bool(int(var.get()))
            player['active'] = value
        var.trace("w", onchange)
        self.vars.append(var) # Nice garbage collection

        entry = tk.Frame(self.list, borderwidth=1, relief='raised')
        #entry['bg'] = 'green'
        tk.Label(entry, text=player['name'], anchor='w', width=10, font=body).pack(side='left')
        tk.Frame(entry, width=25, height=15, bg=util.convert_colour(player['colour']), highlightthickness=1, highlightbackground='black').pack(side='left')
        tk.Checkbutton(entry, variable=var).pack(side='left')
        tk.Button(entry, text='Del', command=partial(self.remove_player, player), padx=3, pady=3).pack(side='right', padx=2, pady=2)
        tk.Button(entry, text='Edit', command=partial(self.modify_entry, player), padx=3, pady=3).pack(side='right', padx=2, pady=2)
        return entry
Пример #5
0
    def __init__(self, callback, player=None):
        super().__init__()
        new = player is None
        if new:
            player = {'name': '', 'active':True, 'colour': [255,0,0], 'controls': [None]*4}

        tk.Label(self, text=('Create' if new else 'Modify')+' Player', font=h2).grid(row=0,column=0,columnspan=2)

        self.callback = callback
        self.active = player['active']

        tk.Label(self, text='Name:').grid(row=1, column=0)
        self.name_var = tk.StringVar(value=player['name'])
        tk.Entry(self, textvariable=self.name_var, width=15).grid(row=1,column=1)

        tk.Label(self, text='Colour:').grid(row=2,column=0)
        self.colour_button = tk.Button(self, command=self.update_colour, bg=util.convert_colour(player['colour']), activebackground=util.convert_colour((np.array(player['colour']) * 0.9).astype(int)))
        self.colour_button.grid(row=2,column=1, sticky='ew')

        keys = tk.Frame(self)
        for i in range(3):
            keys.grid_columnconfigure(i, minsize=40)
        for i in range(2):
            keys.grid_rowconfigure(i, minsize=40)

        self.buttons = [tk.Button(keys,command=partial(self.update_key, i)) for i in range(4)]
        self.buttons[0].grid(row=1,column=2,sticky='nsew')
        self.buttons[2].grid(row=1,column=1,sticky='nsew')
        self.buttons[1].grid(row=1,column=0,sticky='nsew')
        self.buttons[3].grid(row=0,column=1,sticky='nsew')

        self.controls = player['controls'].copy()

        for key, button in zip(self.controls, self.buttons):
            try:
                code = getattr(pg_locals, 'K_' + key)
                button['text'] = pygame.key.name(code)
            except:
                button['text'] = 'Unknown Key'

        keys.grid(row=3,column=0,columnspan=2)

        footer = tk.Frame(self)
        tk.Button(footer, text='Save', command=self.save_player).pack(side='left')
        tk.Button(footer, text='Cancel', command=pop_stack).pack(side='left')
        footer.grid(row=4,column=0,columnspan=2)
Пример #6
0
 def change_colour(*hsv):
     rgb = (util.HSVtoRGB(*hsv) * 255).astype(int)
     shared.selected_colour = rgb.tolist()
     shared.colour_button['bg'] = util.convert_colour(rgb)
     shared.colour_button['activebackground'] = util.convert_colour(
         (rgb * (15 / 16)).astype(int))
Пример #7
0
def run(initial_file):
    shared.root = root = tk.Tk()
    inner = tk.Frame(root, name='inner_frame')
    inner.pack(padx=5, pady=(0, 5), side='left', anchor='n')

    ttk.Separator(root, orient=tk.VERTICAL).pack(side='left', fill='y')

    saveload = tk.Frame(inner)
    saveload.grid(row=0)
    # tk.Label(saveload,text='Save/Load').grid(row=0,column=0,columnspan=3)
    tk.Frame(saveload, height=5).grid(row=0, columnspan=3)
    tk.Button(saveload, text='Save', command=save_pressed).grid(row=1,
                                                                column=0)
    tk.Button(saveload, text='Save As', command=save_as_pressed).grid(row=1,
                                                                      column=1)
    tk.Button(saveload, text='Load', command=load_pressed).grid(row=1,
                                                                column=2)

    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=1, sticky='ew', pady=5)

    general = tk.Frame(inner)
    general.grid(row=2)
    tk.Button(general,
              text='Select',
              command=actions.set_action(actions.Select)).grid(row=0,
                                                               column=0,
                                                               columnspan=2,
                                                               sticky='ew')
    tk.Button(general, text='Undo', command=undo_pressed).grid(row=1, column=0)
    tk.Button(general, text='Redo', command=redo_pressed).grid(row=1, column=1)

    def change_colour(*hsv):
        rgb = (util.HSVtoRGB(*hsv) * 255).astype(int)
        shared.selected_colour = rgb.tolist()
        shared.colour_button['bg'] = util.convert_colour(rgb)
        shared.colour_button['activebackground'] = util.convert_colour(
            (rgb * (15 / 16)).astype(int))

    shared.colour_button = tk.Button(
        general, command=widgets.open_picker(change_colour))
    shared.colour_button.grid(row=2, column=0, columnspan=2, ipadx=10)
    shared.colour_button['bg'] = util.convert_colour(shared.selected_colour)
    shared.colour_button['activebackground'] = util.convert_colour(
        np.multiply(shared.selected_colour, 15 / 16).astype(int))
    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=3, sticky='ew', pady=5)

    create = tk.Frame(inner)
    create.grid(row=4)
    tk.Label(create, text='Create').grid(row=0, column=0, columnspan=2)
    tk.Button(create, text='Polygon',
              command=actions.polygon_pressed).grid(row=1, column=0)
    tk.Button(create,
              text='Rectangle',
              command=actions.set_action(actions.Rectangle)).grid(row=1,
                                                                  column=1)
    tk.Button(create, text='NGon',
              command=actions.set_action(actions.NGon)).grid(row=2, column=0)
    tk.Button(create,
              text='Circle',
              command=actions.set_action(actions.Circle)).grid(row=2, column=1)
    tk.Button(create, text='Text',
              command=actions.set_action(actions.Text)).grid(row=3, column=0)

    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=5, sticky='ew', pady=5)

    modify = tk.Frame(inner)
    modify.grid(row=6)
    tk.Label(modify, text='Modify').grid(row=0, column=0, columnspan=2)
    tk.Button(modify,
              text='Rotate',
              command=actions.set_action(actions.Rotate)).grid(row=1,
                                                               column=0,
                                                               sticky='ew')
    tk.Button(modify,
              text='Translate',
              command=actions.set_action(actions.Translate)).grid(row=1,
                                                                  column=1,
                                                                  sticky='ew')
    tk.Button(modify,
              text='Smooth',
              command=actions.set_action(actions.Smooth)).grid(row=2,
                                                               column=0,
                                                               sticky='ew')
    tk.Button(modify, text='Edit',
              command=actions.set_action(actions.Edit)).grid(row=2,
                                                             column=1,
                                                             sticky='ew')
    tk.Button(modify,
              text='Delete',
              command=actions.set_action(actions.Delete)).grid(row=3,
                                                               column=0,
                                                               sticky='ew')
    tk.Button(modify,
              text='Duplicate',
              command=actions.set_action(actions.Duplicate)).grid(row=3,
                                                                  column=1,
                                                                  sticky='ew')
    tk.Button(modify,
              text='Properties',
              command=actions.set_action(actions.Properties)).grid(
                  row=4, column=0, columnspan=2)

    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=7, sticky='ew', pady=5)

    joints = tk.Frame(inner)
    joints.grid(row=8)
    tk.Label(joints, text='Joints').grid(row=0, column=0, columnspan=2)

    tk.Button(joints,
              text='Pivot',
              command=actions.set_action(actions.AddPivot)).grid(row=1,
                                                                 column=0)
    tk.Button(joints,
              text='Fixed',
              command=actions.set_action(actions.AddFixed)).grid(row=1,
                                                                 column=1)
    tk.Button(joints,
              text='Delete',
              command=actions.set_action(actions.RemoveJoint)).grid(row=2,
                                                                    column=0)

    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=9, sticky='ew', pady=5)

    globalProps = tk.Frame(inner)
    globalProps.grid(row=10)
    tk.Label(globalProps, text='Script').grid(row=0, column=0, columnspan=2)

    tk.Button(globalProps, text='Edit', command=open_script).grid(row=1,
                                                                  column=0)
    tk.Button(globalProps,
              text='Group',
              command=actions.set_action(actions.Group)).grid(row=1, column=1)

    ttk.Separator(inner, orient=tk.HORIZONTAL).grid(row=11,
                                                    sticky='ew',
                                                    pady=5)

    # Extra section inserted by current_action.

    error = tk.StringVar(name='error_var')
    tk.Label(inner, textvariable=error, wraplength=180).grid(row=14)

    actions.Smooth.min_angle = tk.StringVar(value=str(
        actions.Smooth.min_angle))  # Hmmm

    shared.level = load_file(initial_file)

    root.title('Editor')

    root.update_idletasks()
    root.update()

    def on_closing():
        nonlocal running
        running = False

    root.protocol("WM_DELETE_WINDOW", on_closing)

    if os.name == 'nt':  # Embedded pygame window
        root.minsize(800, inner.winfo_height())
        pygameFrame = tk.Frame(root)
        pygameFrame.pack(side='left', expand=True, fill='both')
        os.environ['SDL_WINDOWID'] = str(pygameFrame.winfo_id())
        screen = pygame.display.set_mode(flags=pg_locals.NOFRAME)
    else:  # Seperate windows
        root.attributes("-topmost", True)
        size = 1024, 768
        screen = pygame.display.set_mode(size, pg_locals.RESIZABLE)
        pygame.display.set_caption('Editor')

    pygame.font.init()
    position_font = pygame.font.SysFont(None, 15)

    clock = pygame.time.Clock()

    god = shared.god = God(screen)
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pg_locals.KEYDOWN:
                action = SHORTCUTS.get(event.key)
                if action is not None:
                    actions.set_action(action)()
            elif event.type == pg_locals.MOUSEBUTTONDOWN:
                if shared.colour_picker is not None:
                    obj = actions.get_object_at(god.get_cursor_position())
                    if obj is None:
                        colour = 1, 1, 1
                    else:
                        colour = np.divide(obj['colour'], 255)
                    shared.colour_picker.update_all(util.RGBtoHSV(*colour))
                elif god.current_action is not None:
                    #print(event.button)
                    try:
                        god.current_action.click(god.get_cursor_position(),
                                                 event.button)
                    except actions.StopAction as e:
                        if e.history_entry is not None:
                            shared.history = shared.history[:shared.
                                                            history_index + 1]

                            shared.history.append(e.history_entry)
                            shared.history_index = len(shared.history) - 1
                        god.current_action = None

            elif event.type == pg_locals.VIDEORESIZE:  # Only occurs on non embedded pygame
                screen = pygame.display.set_mode(event.size,
                                                 pg_locals.RESIZABLE)
            elif event.type == pg_locals.QUIT:  # Only occurs on non embedded pygame
                running = False
        god.update()

        screen.fill((255, 255, 255))

        for i, obj in enumerate(shared.level['objects']):
            outline = (2, (0, 0, 255)) if i in shared.selection else (1, (0, 0,
                                                                          0))
            god.draw_object(obj, outline)

        for i, joint in enumerate(shared.level['constraints']):
            outline = (2, (0, 0,
                           255)) if i in shared.joint_selection else (1, (0, 0,
                                                                          0))
            if joint['type'] == 'pivot':
                god.draw_circle(joint['pos'], 5, None, outline)
            elif joint['type'] == 'fixed':
                god.draw_line(np.subtract(joint['pos'], (3, 3)),
                              np.add(joint['pos'], (3, 3)), *outline[::-1])
                god.draw_line(np.subtract(joint['pos'], (-3, 3)),
                              np.add(joint['pos'], (-3, 3)), *outline[::-1])

        if god.current_action is not None:
            god.current_action.render()

        pos = god.get_cursor_position()
        rendered_position = position_font.render('{:},{:}'.format(*pos), True,
                                                 (0, 0, 0, 255))
        screen_pos = np.add(pygame.mouse.get_pos(), (0, -8))
        screen.blit(rendered_position, screen_pos)

        pygame.display.update()

        root.update_idletasks()
        root.update()

        clock.tick(60)

    root.destroy()
    pygame.quit()
Пример #8
0
 def unselect(self):
     self['bg'] = self.label['bg'] = util.convert_colour((240, 240, 237))
Пример #9
0
    def __init__(self, initial_colour=(255,255,255)):
        super().__init__()
        self.size = 150

        self.resizable(False, False)
        self.title('Colour Picker')
        self.attributes('-topmost', True)

        self.canvas = tk.Canvas(self, width=self.size + 20, height=self.size + 12, bg='white')
        self.canvas.bind('<B1-Motion>', self.move)
        self.canvas.bind('<Button-1>', self.click)
        self.canvas.bind('<ButtonRelease-1>', self.release)

        def try_close():
            self.colour = None
            self.destroy()
        self.protocol("WM_DELETE_WINDOW", try_close)

        self.img = tk.PhotoImage(width=self.size, height=self.size)
        self.canvas.create_image((0,0), anchor=tk.NW, image=self.img, state="normal")

        self._base_wheel = np.array([
            [
            util.HSVtoRGB(math.atan2(y,x)/math.pi/2, math.sqrt(x**2+y**2) / self.size*2, 1) if x**2+y**2 <= self.size*self.size/4 else (-1,-1,-1) for x in range(-self.size//2, self.size//2)
            ] for y in range(-self.size//2, self.size//2)])
        self._format_str = ' '.join('{' + ' '.join('#%02x%02x%02x' for _ in range(self.size)) + '}' for _ in range(self.size))

        self.canvas.create_line(self.size+10, 10, self.size+10, self.size-10, width=5, capstyle=tk.ROUND, fill=util.convert_colour((100,100,100)))

        self.canvas.grid(row=0, column=0, columnspan=2)

        self.cursors = [None]*2

        self.rgb_controls = [tk.StringVar() for i in range(3)]
        self.hsv_controls = [tk.StringVar() for i in range(3)]
        def updateHSV(*_):
            if self.selected is not None:
                return
            try:
                new_colour = [float(channel.get()) for channel in self.rgb_controls]
            except ValueError:
                return
            if min(new_colour) < 0 or max(new_colour) > 1:
                return

            new_colour = util.RGBtoHSV(*new_colour)
            self.selected = 3
            for channel, val in zip(self.hsv_controls, new_colour):
                channel.set(round(val, 2))
            self.selected = None
            self.update_cursors(new_colour)

        def updateRGB(*_):
            if self.selected is not None:
                return
            try:
                new_colour = [float(channel.get()) for channel in self.hsv_controls]
            except ValueError:
                return
            if min(new_colour) < 0 or max(new_colour) > 1:
                return

            self.selected = 3
            for channel, val in zip(self.rgb_controls, util.HSVtoRGB(*new_colour)):
                channel.set(round(val, 2))
            self.selected = None
            self.update_cursors(new_colour)

        for i, rgb, hsv in zip(range(3), self.rgb_controls, self.hsv_controls):
            tk.Spinbox(self,from_=0,to=1,increment=0.1,width=8, textvariable=rgb).grid(row=i+1,column=0, sticky='e')
            tk.Spinbox(self,from_=0,to=1,increment=0.1,width=8, textvariable=hsv).grid(row=i+1,column=1, sticky='w')

            rgb.trace('w', updateHSV)
            hsv.trace('w', updateRGB)

        tk.Button(self, text='Select', command=self.destroy).grid(row=4,column=0,columnspan=2)

        self.selected = None

        self.update_all(util.RGBtoHSV(*np.divide(initial_colour,255)))
Пример #10
0
 def set_colour(self, *col):
     rgb = (util.HSVtoRGB(*col)*255).astype(int)
     self['bg'] = util.convert_colour(rgb)
     self['activebackground'] = util.convert_colour((rgb*(15/16)).astype(int))
     self.set_target(rgb.tolist())
Пример #11
0
 def create_line(self, col):
     self.canvas.create_line(10, self.size+5, self.size+10, self.size+5, width=9, capstyle=tk.ROUND, fill=util.convert_colour((col*255).astype(int)))