示例#1
0
    def __init__(self,
                 func,
                 pos,
                 size,
                 text='',
                 color=GREEN,
                 anchor=CENTER,
                 takeArg=False,
                 enable=True,
                 flags=0):
        """
        Creates a clickable button.

        :param func: callback function with no arguments
        :param size: widget size. Can be a callable or a 2-tuple.
        :param pos: widget position. Can be a callable or a 2-tuple.
        :param anchor: widget anchor
        :param text: Text to be displayed on the button
        :param color: the natural color of the button
        :param flags: see BaseButton
        """

        super().__init__(func, pos, size, anchor, flags)

        self.color = color
        self.hovered = False
        self.hover_enabled = True
        self.pressed = False
        self.takesArg = takeArg
        self._arg = None
        self._isEnabled = enable
        self.text = SimpleText(text, lambda: self.center,
                               bw_contrasted(self.color), self.color,
                               Font(self.height - 6, unit=Font.PIXEL))
示例#2
0
    def __init__(self,
                 func,
                 pos,
                 size,
                 min_=0,
                 max_=100,
                 step=1,
                 color=BLUE,
                 *,
                 bg_color=LIGHT_GREY,
                 show_val=True,
                 interval=1,
                 anchor=CENTER,
                 inital=None,
                 rounding=2,
                 v_type=int):
        """
        Creates a SlideBar.
        
        Use focus() when the user selects the bar and unfous() when he release the SB.
        
        :param size: widget size. Can be a callable or a 2-tuple.
        :param pos: widget position. Can be a callable or a 2-tuple.
        :param anchor: widget anchor
        :param show_val: if False, doesn't display the value on the cursor
        :param func: Callback function when a value is changed
        :param min_: The eminimum value of the picker
        :param max_: The maximum value of the picker
        :param step: The step
        :param color: color of the cursor
        :param bg_color: color of the background
        :param interval: minimum milisec elapsed between two calls to *func*
        :param inital: initial value for the SB
        :param rounding: number of digits to round values
        :param v_type: type of value. Can be float/int/Decimal/Fraction etc.
            you will have an object of this type using get()
        """

        super().__init__(pos, size, anchor)

        self.color = color
        self.bg_color = bg_color
        self.func = func
        self._value = inital if inital is not None else min_
        self.min = min_
        self.max = max_
        self.step = step
        self.show_val = show_val
        self.rounding = rounding
        self.v_type = v_type

        font = Font(self.height // 2)
        self.text_val = SimpleText(self.get, lambda:
                                   (self.value_px, self.centery),
                                   bw_contrasted(self.color), font)

        self.interval = interval
示例#3
0
文件: buttons.py 项目: xjzpguob/GUI
class RoundButton(Button):
    def __init__(self, func, pos, radius: int, text='', color=GREEN, anchor=CENTER, flags=0):
        super().__init__(func, pos, (radius * 2, radius * 2), text, color, anchor, flags)

        self.text = SimpleText(text, lambda: self.center, bw_contrasted(self.color), self.color,
                               Font(self.height // 2, unit=Font.PIXEL))

    def render(self, surf):
        """Draw the button on the surface."""
        if not self.flags & self.NO_SHADOW:
            circle(surf, self.center + self._bg_delta, self.width / 2, LIGHT_GREY)
        circle(surf, self.center + self._front_delta, self.width / 2, self._get_color())

        self.text.center = self.center + self._front_delta
        self.text.render(surf)
示例#4
0
    def __init__(self,
                 parent,
                 name,
                 pos,
                 size,
                 anchor=TOPLEFT,
                 item_size=20,
                 color=CONCRETE,
                 bg_color=WHITE,
                 sep_color=CONCRETE):

        super().__init__(pos, size, anchor, item_size, sep_color)

        self.parent = parent
        self.title = SimpleText(
            name, pos
        )  #, color, bg_color, BoldFont(self.height, BoldFont.POINT), TOPLEFT)
        self.structure.append(self.title)
示例#5
0
class SlideBar(BaseWidget):
    """
    A slide bar to bick a value in a range.
    
    Don't forget to call focus() and unfocus() when the user click on the SlideBar
    """
    def __init__(self,
                 func,
                 pos,
                 size,
                 min_=0,
                 max_=100,
                 step=1,
                 color=BLUE,
                 *,
                 bg_color=LIGHT_GREY,
                 show_val=True,
                 interval=1,
                 anchor=CENTER,
                 inital=None,
                 rounding=2,
                 v_type=int):
        """
        Creates a SlideBar.
        
        Use focus() when the user selects the bar and unfous() when he release the SB.
        
        :param size: widget size. Can be a callable or a 2-tuple.
        :param pos: widget position. Can be a callable or a 2-tuple.
        :param anchor: widget anchor
        :param show_val: if False, doesn't display the value on the cursor
        :param func: Callback function when a value is changed
        :param min_: The eminimum value of the picker
        :param max_: The maximum value of the picker
        :param step: The step
        :param color: color of the cursor
        :param bg_color: color of the background
        :param interval: minimum milisec elapsed between two calls to *func*
        :param inital: initial value for the SB
        :param rounding: number of digits to round values
        :param v_type: type of value. Can be float/int/Decimal/Fraction etc.
            you will have an object of this type using get()
        """

        super().__init__(pos, size, anchor)

        self.color = color
        self.bg_color = bg_color
        self.func = func
        self._value = inital if inital is not None else min_
        self.min = min_
        self.max = max_
        self.step = step
        self.show_val = show_val
        self.rounding = rounding
        self.v_type = v_type

        font = Font(self.height // 2)
        self.text_val = SimpleText(self.get, lambda:
                                   (self.value_px, self.centery),
                                   bw_contrasted(self.color), font)

        self.interval = interval

    def __repr__(self):
        # return f'SlideBar({self.min}:{self.max}:{self.step}; {super().__repr__()}, Value: {self.get()})'
        return 'SlideBar({}:{}:{}; {}, Value: {})'.format(
            self.min, self.max, self.step,
            super().__repr__(), self.get())

    def get(self):
        """The current value of the bar"""
        return round(self.v_type(self._value), self.rounding)

    def set(self, value):
        """Set the value of the bar. If the value is out of bound, sets it to an extremum"""
        value = min(self.max, max(self.min, value))
        self._value = value
        start_new_thread(self.func, (self.get(), ))

    def _start(self):
        """Starts checking if the SB is shifted"""

        # TODO : make an update method instead

        last_call = 42
        while self._focus:
            sleep(1 / 100)

            mouse = pygame.mouse.get_pos()
            last_value = self.get()
            self.value_px = mouse[0]

            # we do not need to do anything when it the same value
            if self.get() == last_value:
                continue

            if last_call + self.interval / 1000 < time():
                last_call = time()
                self.func(self.get())

    def focus(self):
        """Gives the focus to the widget"""
        self._focus = True

        start_new_thread(SlideBar._start, (self, ))

    @property
    def value_px(self):
        """The position in pixels of the cursor"""
        step = self.w / (self.max - self.min)
        return self.x + step * (
            self.get() - self.min
        )  # -self.min so self.x is the minimum possible place

    @value_px.setter
    def value_px(self, value):
        value = min(self.right, max(self.left, value))

        delta_x = value - self.x
        prop = delta_x / self.width
        real = prop * (self.max - self.min)
        self._value = self.min + round(real / self.step) * self.step

    def render(self, display):
        """Renders the bar on the display"""

        # the bar
        bar_rect = pygame.Rect(0, 0, self.width, self.height // 3)
        bar_rect.center = self.center
        display.fill(self.bg_color, bar_rect)

        # the cursor
        circle(display, (self.value_px, self.centery), self.height // 2,
               self.color)

        # the value
        if self.show_val:
            self.text_val.render(display)
示例#6
0
    def __init__(self):
        super(Lamacorp, self).__init__()

        header_size = 60
        h_color = BLUE
        nb_button = 8
        button_size = lambda:(self.SCREEN_SIZE[0] - 40) / nb_button

        self.tab = None
        self.header = self.add(Rectangle((0, 0), lambda: (self.SCREEN_SIZE[0], header_size), h_color))
        self.line = self.add(Line((0, header_size), lambda: (self.SCREEN_SIZE[0], header_size), GOLD))
        self.title = self.add(
            SimpleText(self.NAME, (16, 8), GOLD, h_color, BoldFont(header_size - 16, Font.PIXEL, BoldFont.LIGHT),
                       TOPLEFT)
        )

        def get_funcs(color, i, row):
            def _pos():
                return int(20 + button_size() * i), header_size + 8 + 38 * row

            def _size():
                return int(button_size() - 6), 30

            def _action():
                rgb = name2rgb(color)
                rgb_light = mix(WHITESMOKE, rgb, 0.6)
                self.line.color = rgb_light
                self.BORDER_COLOR = rgb
                self.header.color = rgb
                self.title.bg_color = rgb
                self.die.color = 255 - rgb[0], 255 - rgb[1], 255 - rgb[2]
                self.title.color = WHITESMOKE
                self.choose_hint.text = str(color.hex).capitalize()
                self.choose_hint.color = rgb
                self.quit.color = rgb
                self.tab = color
                print(color, color.rgb, color.hex)

            text = texts[row][i % len(texts[row])]

            return _action, _pos, _size, text

        start = colour.Color("green"), colour.Color("#00caca")
        end = colour.Color('gold'), colour.Color('navy')
        texts = [
            "That's some beautiful colors and buttons man ! :P Yolooo".split(),
            'There is 64 differents types of buttons ! :o :P'.split()
        ]

        # the buttons
        for row in range(2):
            for i, color in enumerate(start[row].range_to(end[row], nb_button)):
                self.add(Button(*get_funcs(color, i, row), name2rgb(color), TOPLEFT, 4 * i + 32 * row))

        self.die = self.add(
            RoundButton(pygame.display.iconify, lambda: self.SCREEN_SIZE + Sep(-10, -10), 40, 'Die', h_color,
                        BOTTOMRIGHT), lambda: self.tab
        )

        self.quit = self.add(
            RoundButton(quit, lambda: (self.SCREEN_SIZE[0] - 8, 8), header_size // 2 - 8, 'X', h_color, TOPRIGHT,
                        Button.NO_MOVE | Button.NO_SHADOW)
        )

        self.choose_hint = self.add(
            SimpleText('Choose your color !', lambda:(self.SCREEN_SIZE[0] // 2, (self.SCREEN_SIZE[1] + header_size) // 2),
                       CONCRETE, self.BACKGROUND_COLOR, Font(50)),
            # lambda: False
        )

        self.rounded = self.add(
            Rectangle((120, 40), (300, 300), color=(0, 0, 255, 120), style=Rectangle.ROUNDED)
        )

        self.tect_box = self.add(InLineTextBox(lambda:(self.SCREEN_SIZE[0]//2, self.SCREEN_SIZE[1] - 50),
                                               (self.SCREEN_SIZE[0]//2), MIDNIGHT_BLUE))
        self.add(Rectangle(self.tect_box.topleft, self.tect_box.size, GOLD, Rectangle.BORDER))
示例#7
0
文件: buttons.py 项目: xjzpguob/GUI
class Button(BaseButton):
    """A basic button."""

    NO_MOVE = 4
    NO_SHADOW = 8
    NO_ROUNDING = 16
    NO_HOVER = 32

    def __init__(self, func, pos, size, text='', color=GREEN, anchor=CENTER, flags=0):
        """
        Creates a clickable button.
        
        :param func: callback function with no arguments
        :param size: widget size. Can be a callable or a 2-tuple.
        :param pos: widget position. Can be a callable or a 2-tuple.
        :param anchor: widget anchor
        :param text: Text to be displayed on the button
        :param color: the natural color of the button
        :param flags: see BaseButton
        """

        super().__init__(func, pos, size, anchor, flags)

        self.color = color
        self.hovered = False
        self.hover_enabled = True
        self.pressed = False
        self.text = SimpleText(text, lambda: self.center, bw_contrasted(self.color), self.color,
                               Font(self.height - 6, unit=Font.PIXEL))

    def _get_color(self):
        """Return the color of the button, depending on its state"""
        if self.clicked and self.hovered:  # the mouse is over the button
            color = mix(self.color, BLACK, 0.8)

        elif self.hovered and not self.flags & self.NO_HOVER:
            color = mix(self.color, BLACK, 0.93)

        else:
            color = self.color

        self.text.bg_color = color
        return color

    @property
    def _front_delta(self):
        """Return the offset of the colored part."""
        if self.flags & self.NO_MOVE:
            return Separator(0, 0)

        if self.clicked and self.hovered:  # the mouse is over the button
            delta = 2

        elif self.hovered and not self.flags & self.NO_HOVER:
            delta = 0

        else:
            delta = 0

        return Separator(delta, delta)

    @property
    def _bg_delta(self):
        """Return the offset of the shadow."""
        if self.flags and self.NO_MOVE:
            return Separator(2, 2)

        if self.clicked and self.hovered:  # the mouse is over the button
            delta = 2

        elif self.hovered and not self.flags & self.NO_HOVER:
            delta = 2

        else:
            delta = 2

        return Separator(delta, delta)

    def update(self, event_or_list):
        """Update the button with the events."""

        for e in super().update(event_or_list):
            if e.type == MOUSEBUTTONDOWN:
                if e.pos in self:
                    self.click()
                else:
                    self.release(force_no_call=True)

            elif e.type == MOUSEBUTTONUP:
                self.release(force_no_call=e.pos not in self)

            elif e.type == MOUSEMOTION:
                if e.pos in self:
                    self.hovered = True
                else:
                    self.hovered = False

    def render(self, surf):
        """Render the button on a surface."""
        pos, size = self.topleft, self.size

        if not self.flags & self.NO_SHADOW:
            if self.flags & self.NO_ROUNDING:
                pygame.draw.rect(surf, LIGHT_GREY, (pos + self._bg_delta, size))
            else:
                roundrect(surf, (pos + self._bg_delta, size), LIGHT_GREY + (100,), 5)

        if self.flags & self.NO_ROUNDING:
            pygame.draw.rect(surf, self._get_color(), (pos + self._front_delta, size))
        else:
            roundrect(surf, (pos + self._front_delta, size), self._get_color(), 5)

        self.text.center = self.center + self._front_delta
        self.text.render(surf)
示例#8
0
文件: buttons.py 项目: xjzpguob/GUI
    def __init__(self, func, pos, radius: int, text='', color=GREEN, anchor=CENTER, flags=0):
        super().__init__(func, pos, (radius * 2, radius * 2), text, color, anchor, flags)

        self.text = SimpleText(text, lambda: self.center, bw_contrasted(self.color), self.color,
                               Font(self.height // 2, unit=Font.PIXEL))
示例#9
0
class Button(BaseButton):
    """A basic button."""

    NO_MOVE = 4
    NO_SHADOW = 8
    NO_ROUNDING = 16
    NO_HOVER = 32

    def __init__(self,
                 func,
                 pos,
                 size,
                 text='',
                 color=GREEN,
                 anchor=CENTER,
                 takeArg=False,
                 enable=True,
                 flags=0):
        """
        Creates a clickable button.

        :param func: callback function with no arguments
        :param size: widget size. Can be a callable or a 2-tuple.
        :param pos: widget position. Can be a callable or a 2-tuple.
        :param anchor: widget anchor
        :param text: Text to be displayed on the button
        :param color: the natural color of the button
        :param flags: see BaseButton
        """

        super().__init__(func, pos, size, anchor, flags)

        self.color = color
        self.hovered = False
        self.hover_enabled = True
        self.pressed = False
        self.takesArg = takeArg
        self._arg = None
        self._isEnabled = enable
        self.text = SimpleText(text, lambda: self.center,
                               bw_contrasted(self.color), self.color,
                               Font(self.height - 6, unit=Font.PIXEL))

    @property
    def isEnabled(self):
        return self._isEnabled

    @isEnabled.setter
    def isEnabled(self, value):
        if not isinstance(value, bool):
            raise TypeError("Value must be a boolean type. Got " +
                            str(type(value)) + " instead.")

    @property
    def arg(self):
        return self._arg

    @arg.setter
    def arg(self, value):
        if self.takesArg == False:
            raise KeyError("This button does not take arguments")
        else:
            self._arg = value

    def click(self, force_no_call=False, milis=None):
        """
        Call when the button is pressed. This start the callback function in a thread
        If :milis is given, will release the button after :milis miliseconds
        Completely overridden because the super class's method did not take arguments
        """
        if not self.isEnabled:
            return False

        if self.clicked:
            return False

        if not force_no_call and self.flags & self.CALL_ON_PRESS:
            if self.flags & self.THREADED_CALL:
                if self.takesArg:
                    start_new_thread(self.func, self.arg)
                else:
                    start_new_thread(self.func, ())
            else:
                if (self.takesArg):
                    self.func(self.arg)
                else:
                    self.func()

        BaseWidget.click()

        if milis is not None:
            start_new_thread(self.release, (), {'milis': milis})

    def _get_color(self):
        """Return the color of the button, depending on its state"""
        if self.clicked and self.hovered:  # the mouse is over the button
            color = mix(self.color, BLACK, 0.8)

        elif self.hovered and not self.flags & self.NO_HOVER:
            color = mix(self.color, BLACK, 0.93)

        else:
            color = self.color

        self.text.bg_color = color
        return color

    @property
    def _front_delta(self):
        """Return the offset of the colored part."""
        if self.flags & self.NO_MOVE:
            return Separator(0, 0)

        if self.clicked and self.hovered:  # the mouse is over the button
            delta = 2

        elif self.hovered and not self.flags & self.NO_HOVER:
            delta = 0

        else:
            delta = 0

        return Separator(delta, delta)

    @property
    def _bg_delta(self):
        """Return the offset of the shadow."""
        if self.flags and self.NO_MOVE:
            return Separator(2, 2)

        if self.clicked and self.hovered:  # the mouse is over the button
            delta = 2

        elif self.hovered and not self.flags & self.NO_HOVER:
            delta = 2

        else:
            delta = 2

        return Separator(delta, delta)

    def update(self, event_or_list):
        """Update the button with the events."""

        for e in super().update(event_or_list):
            if e.type == MOUSEBUTTONDOWN:
                if e.pos in self:
                    self.click()
                else:
                    self.release(force_no_call=True)

            elif e.type == MOUSEBUTTONUP:
                self.release(force_no_call=e.pos not in self)

            elif e.type == MOUSEMOTION:
                if e.pos in self:
                    self.hovered = True
                else:
                    self.hovered = False

    def render(self, surf):
        """Render the button on a surface."""
        pos, size = self.topleft, self.size

        if not self.flags & self.NO_SHADOW:
            if self.flags & self.NO_ROUNDING:
                pygame.draw.rect(surf, LIGHT_GREY,
                                 (pos + self._bg_delta, size))
            else:
                roundrect(surf, (pos + self._bg_delta, size),
                          LIGHT_GREY + (100, ), 5)

        if self.flags & self.NO_ROUNDING:
            pygame.draw.rect(surf, self._get_color(),
                             (pos + self._front_delta, size))
        else:
            roundrect(surf, (pos + self._front_delta, size), self._get_color(),
                      5)

        self.text.center = self.center + self._front_delta
        self.text.render(surf)