Ejemplo n.º 1
0
class Control(object):

	highlighted = overridable_property('highlighted')
	enabled = overridable_property('enabled')
	value = overridable_property('value')
	
	enable = None
	ref = None
	_highlighted = False
	_enabled = True
	_value = None

	def get_value(self):
		ref = self.ref
		if ref:
			return ref.get()
		else:
			return self._value
	
	def set_value(self, x):
		ref = self.ref
		if ref:
			ref.set(x)
		else:
			self._value = x
Ejemplo n.º 2
0
class Control(object):
    highlighted = overridable_property('highlighted')
    enabled = overridable_property('enabled')
    value = overridable_property('value')

    enable = None
    ref = None
    _highlighted = False
    _enabled = True
    _value = None

    def get_value(self):
        ref = self.ref
        if ref:
            return ref.get()
        else:
            return self._value

    def set_value(self, x):
        ref = self.ref
        if ref:
            ref.set(x)
        else:
            self._value = x

    def get_highlighted(self):
        return self._highlighted

    def get_enabled(self):
        enable = self.enable
        if enable:
            return enable()
        else:
            return self._enabled

    def set_enabled(self, x):
        self._enabled = x

    if __builtins__.get("mcenf_tab_to_next"):

        def key_down(self, event):
            """Handles key press.
            Captured events are ENTER and SPACE key press.
            :param event: object: The event being processed."""
            key = event.key
            if key in (K_RETURN, K_KP_ENTER, K_SPACE):
                self.call_handler("action")
            else:
                Widget.key_down(self, event)
class Image(Widget):
    #  image   Image to display

    highlight_color = ThemeProperty('highlight_color')

    image = overridable_property('image')

    highlighted = False

    def __init__(self, image=None, rect=None, **kwds):
        Widget.__init__(self, rect, **kwds)
        if image:
            if isinstance(image, basestring):
                image = resource.get_image(image)
            w, h = image.get_size()
            d = 2 * self.margin
            self.size = w + d, h + d
            self._image = image

    def get_image(self):
        return self._image

    def set_image(self, x):
        self._image = x

    def draw(self, surf):
        frame = surf.get_rect()
        if self.highlighted:
            surf.fill(self.highlight_color)
        image = self.image
        r = image.get_rect()
        r.center = frame.center
        surf.blit(image, r)
Ejemplo n.º 4
0
class MenuBar(Widget):

	menus = overridable_property('menus', "List of Menu instances")

	def __init__(self, menus = None, width = 0, **kwds):
		font = self.predict_font(kwds)
		height = font.get_linesize()
		Widget.__init__(self, Rect(0, 0, width, height), **kwds)
		self.menus = menus or []
		self._hilited_menu = None
	
	def get_menus(self):
		return self._menus
	
	def set_menus(self, x):
		self._menus = x
	
	def draw(self, surf):
		fg = self.fg_color
		bg = self.bg_color
		font = self.font
		hilited = self._hilited_menu
		x = 0
		for menu in self._menus:
			text = " %s " % menu.title
			if menu is hilited:
				buf = font.render(text, True, bg, fg)
			else:
				buf = font.render(text, True, fg, bg)
			surf.blit(buf, (x, 0))
			x += surf.get_width()
	
	def mouse_down(self, e):
		mx = e.local[0]
		font = self.font
		x = 0
		for menu in self._menus:
			text = " %s " % menu.title
			w = font.size(text)[0]
			if x <= mx < x + w:
				self.show_menu(menu, x)
	
	def show_menu(self, menu, x):
		self._hilited_menu = menu
		try:
			i = menu.present(self, (x, self.height))
		finally:
			self._hilited_menu = None
		menu.invoke_item(i)
	
	def handle_command_key(self, e):
		menus = self.menus
		for m in xrange(len(menus)-1, -1, -1):
			menu = menus[m]
			i = menu.find_item_for_key(e)
			if i >= 0:
				menu.invoke_item(i)
				return True
		return False
class Label(Widget):
    text = overridable_property('text')
    align = overridable_property('align')

    hover_color = ThemeProperty('hover_color')
    highlight_color = ThemeProperty('highlight_color')
    disabled_color = ThemeProperty('disabled_color')
    highlight_bg_color = ThemeProperty('highlight_bg_color')
    hover_bg_color = ThemeProperty('hover_bg_color')
    enabled_bg_color = ThemeProperty('enabled_bg_color')
    disabled_bg_color = ThemeProperty('disabled_bg_color')

    enabled = True
    highlighted = False
    _align = 'l'

    def __init__(self, text, width=None, **kwds):
        Widget.__init__(self, **kwds)
        font = self.font
        text = _(text, doNotTranslate=kwds.get('doNotTranslate', False))
        lines = text.split("\n")
        tw, th = 0, 0
        for line in lines:
            w, h = font.size(line)
            tw = max(tw, w)
            th += h
        if width is not None:
            tw = width
        else:
            tw = max(1, tw)
        d = 2 * self.margin
        self.size = (tw + d, th + d)
        self._text = text

    def __repr__(self):
        return "Label {0}, child of {1}".format(self.text, self.parent)

    def get_text(self):
        return self._text

    def set_text(self, x):
        self._text = _(x)

    def get_align(self):
        return self._align

    def set_align(self, x):
        self._align = x

    def draw(self, surface):
        if not self.enabled:
            fg = self.disabled_color
            bg = self.disabled_bg_color
        else:
            fg = self.fg_color
            bg = self.enabled_bg_color
            if self.is_default:
                fg = self.default_choice_color or fg
                bg = self.default_choice_bg_color or bg
            if self.is_hover:
                fg = self.hover_color or fg
                bg = self.hover_bg_color or bg
            if self.highlighted:
                fg = self.highlight_color or fg
                bg = self.highlight_bg_color or bg

        self.draw_with(surface, fg, bg)

    is_default = False

    def draw_with(self, surface, fg, bg=None):
        if bg:
            r = surface.get_rect()
            b = self.border_width
            if b:
                e = -2 * b
                r.inflate_ip(e, e)
            surface.fill(bg, r)
        m = self.margin
        align = self.align
        width = surface.get_width()
        y = m
        lines = self.text.split("\n")
        font = self.font
        dy = font.get_linesize()
        for line in lines:
            if len(line):
                size = font.size(line)
                if size[0] == 0:
                    continue

                image = font.render(line, True, fg)
                r = image.get_rect()
                r.top = y
                if align == 'l':
                    r.left = m
                elif align == 'r':
                    r.right = width - m
                else:
                    r.centerx = width // 2
                surface.blit(image, r)
            y += dy
Ejemplo n.º 6
0
class Label(Widget):
    text = overridable_property('text')
    align = overridable_property('align')

    hover_color = ThemeProperty('hover_color')
    highlight_color = ThemeProperty('highlight_color')
    disabled_color = ThemeProperty('disabled_color')
    highlight_bg_color = ThemeProperty('highlight_bg_color')
    hover_bg_color = ThemeProperty('hover_bg_color')
    enabled_bg_color = ThemeProperty('enabled_bg_color')
    disabled_bg_color = ThemeProperty('disabled_bg_color')

    enabled = True
    highlighted = False
    _align = 'l'

    def __init__(self, text, width=None, base_text=None, **kwds):
        #-# Translation live update preparation
        # base_text: to be used each time a widget takes a formated string
        #            defaults to 'text'.
        Widget.__init__(self, **kwds)
        #-# Translation live update preparation
        self.fixed_width = width
        self.base_text = base_text or text
        self.previous_translation = _(text,
                                      doNotTranslate=kwds.get(
                                          'doNotTranslate', False))
        #-#
        self._text = _(text, doNotTranslate=kwds.get('doNotTranslate', False))
        #-#
        self.calc_size()
        #-#

    #-# Translation live update preparation
    def calc_size(self):
        lines = self._text.split("\n")
        tw, th = 0, 0
        for i in range(len(lines)):
            line = lines[i]
            if i == len(lines) - 1:
                w, h = self.font.size(line)
            else:
                w, h = self.font.size(line)[0], self.font.get_linesize()
            tw = max(tw, w)
            th += h
        if self.fixed_width is not None:
            tw = self.fixed_width
        else:
            tw = max(1, tw)
        d = 2 * self.margin
        self.size = (tw + d, th + d)

    def get_update_translation(self):
        return Widget.update_translation(self)

    def set_update_ui(self, v):
        self.text = self.base_text
        self.set_text(self.base_text)
        self.calc_size()
        Widget.set_update_ui(self, v)

    #-#

    def __repr__(self):
        return "Label {0}, child of {1}".format(self.text, self.parent)

    def get_text(self):
        return self._text

    def set_text(self, x, doNotTranslate=False):
        self._text = _(x, doNotTranslate=doNotTranslate or self.doNotTranslate)
        self.calc_size()

    def get_align(self):
        return self._align

    def set_align(self, x):
        self._align = x

    def draw(self, surface):
        if not self.enabled:
            fg = self.disabled_color
            bg = self.disabled_bg_color
        else:
            fg = self.fg_color
            bg = self.enabled_bg_color
            if self.is_default:
                fg = self.default_choice_color or fg
                bg = self.default_choice_bg_color or bg
            if self.is_hover:
                fg = self.hover_color or fg
                bg = self.hover_bg_color or bg
            if self.highlighted:
                fg = self.highlight_color or fg
                bg = self.highlight_bg_color or bg

        self.draw_with(surface, fg, bg)

    is_default = False

    def draw_with(self, surface, fg, bg=None):
        if bg:
            r = surface.get_rect()
            b = self.border_width
            if b:
                e = -2 * b
                r.inflate_ip(e, e)
            surface.fill(bg, r)
        m = self.margin
        align = self.align
        width = surface.get_width()
        y = m
        lines = self.text.split("\n")
        font = self.font
        dy = font.get_linesize()
        for line in lines:
            if len(line):
                size = font.size(line)
                if size[0] == 0:
                    continue

                image = font.render(line, True, fg)
                r = image.get_rect()
                r.top = y
                if align == 'l':
                    r.left = m
                elif align == 'r':
                    r.right = width - m
                else:
                    r.centerx = width // 2
                surface.blit(image, r)
            y += dy
Ejemplo n.º 7
0
class TextEditor(Widget):

    upper = False
    tab_stop = True

    _text = ""

    def __init__(self, width, upper=None, **kwds):
        Widget.__init__(self, **kwds)
        self.set_size_for_text(width)
        if upper is not None:
            self.upper = upper
        self.insertion_point = None

    def get_text(self):
        return self._text

    def set_text(self, text):
        self._text = text

    text = overridable_property('text')

    def draw(self, surface):
        frame = self.get_margin_rect()
        fg = self.fg_color
        font = self.font
        focused = self.has_focus()
        text, i = self.get_text_and_insertion_point()
        if focused and i is None:
            surface.fill(self.sel_color, frame)
        image = font.render(text, True, fg)
        surface.blit(image, frame)
        if focused and i is not None:
            x, h = font.size(text[:i])
            x += frame.left
            y = frame.top
            draw.line(surface, fg, (x, y), (x, y + h - 1))

    def key_down(self, event):
        if not (event.cmd or event.alt):
            k = event.key
            if k == K_LEFT:
                self.move_insertion_point(-1)
                return
            if k == K_RIGHT:
                self.move_insertion_point(1)
                return
            if k == K_TAB:
                self.attention_lost()
                self.tab_to_next()
                return
            try:
                c = event.unicode
            except ValueError:
                c = ""
            if self.insert_char(c) <> 'pass':
                return
        if event.cmd and event.unicode:
            self.attention_lost()
        self.call_parent_handler('key_down', event)

    def get_text_and_insertion_point(self):
        text = self.get_text()
        i = self.insertion_point
        if i is not None:
            i = max(0, min(i, len(text)))
        return text, i

    def move_insertion_point(self, d):
        text, i = self.get_text_and_insertion_point()
        if i is None:
            if d > 0:
                i = len(text)
            else:
                i = 0
        else:
            i = max(0, min(i + d, len(text)))
        self.insertion_point = i

    def insert_char(self, c):
        if self.upper:
            c = c.upper()
        if c <= "\x7f":
            if c == "\x08" or c == "\x7f":
                text, i = self.get_text_and_insertion_point()
                if i is None:
                    text = ""
                    i = 0
                else:
                    text = text[:i - 1] + text[i:]
                    i -= 1
                self.change_text(text)
                self.insertion_point = i
                return
            elif c == "\r" or c == "\x03":
                return self.call_handler('enter_action')
            elif c == "\x1b":
                return self.call_handler('escape_action')
            elif c >= "\x20":
                if self.allow_char(c):
                    text, i = self.get_text_and_insertion_point()
                    if i is None:
                        text = c
                        i = 1
                    else:
                        text = text[:i] + c + text[i:]
                        i += 1
                    self.change_text(text)
                    self.insertion_point = i
                    return
        return 'pass'

    def allow_char(self, c):
        return True

    def mouse_down(self, e):
        self.focus()
        x, y = e.local
        text = self.get_text()
        font = self.font
        n = len(text)

        def width(i):
            return font.size(text[:i])[0]

        i1 = 0
        i2 = len(text)
        x1 = 0
        x2 = width(i2)
        while i2 - i1 > 1:
            i3 = (i1 + i2) // 2
            x3 = width(i3)
            if x > x3:
                i1, x1 = i3, x3
            else:
                i2, x2 = i3, x3
        if x - x1 > (x2 - x1) // 2:
            i = i2
        else:
            i = i1
        self.insertion_point = i

    def change_text(self, text):
        self.set_text(text)
        self.call_handler('change_action')
Ejemplo n.º 8
0
class TextEditorWrapped(Widget):
    upper = False
    tab_stop = True

    _text = u""

    def __init__(self, width, lines, upper=None, **kwds):
        Widget.__init__(self, **kwds)
        self.set_size_for_text(width, lines)
        if upper is not None:
            self.upper = upper
        self.insertion_point = None
        self.insertion_step = None
        self.insertion_line = None
        self.selection_start = None
        self.selection_end = None
        self.topLine = 0
        self.dispLines = lines
        self.textChanged = True

    def get_text(self):
        return self._text

    def set_text(self, text):
        self._text = _(text)
        self.textChanged = True

    text = overridable_property('text')
    #Text line list and text line EoL index reference
    textL = []
    textRefList = []

    def draw(self, surface):
        frame = self.get_margin_rect()
        fg = self.fg_color
        font = self.font
        focused = self.has_focus()
        text, i, il = self.get_text_and_insertion_data()
        ip = self.insertion_point
        self.doFix = True

        self.updateTextWrap()

        #Scroll the text up or down if necessary
        if self.insertion_line > self.topLine + self.dispLines - 1:
            self.scroll_down()
        elif self.insertion_line < self.topLine:
            self.scroll_up()

        #Draw Border
        draw.rect(
            surface, self.sel_color,
            pygame.Rect(frame.left, frame.top, frame.size[0], frame.size[1]),
            1)

        #Draw Selection Highlighting if Applicable
        if focused and ip is None:
            if self.selection_start is None or self.selection_end is None:
                surface.fill(self.sel_color, frame)
            else:
                startLine, startStep = self.get_char_position(
                    self.selection_start)
                endLine, endStep = self.get_char_position(self.selection_end)
                rects = []

                if startLine == endLine:
                    if startStep > endStep:
                        x1, h = font.size(self.textL[startLine][0:endStep])
                        x2, h = font.size(self.textL[startLine][0:startStep])
                        x1 += frame.left
                        x2 += frame.left
                        lineOffset = startLine - self.topLine
                        y = frame.top + lineOffset * h
                        if lineOffset >= 0:
                            selRect = pygame.Rect(x1, y, (x2 - x1), h)
                    else:
                        x1, h = font.size(self.textL[startLine][0:startStep])
                        x2, h = font.size(self.textL[startLine][0:endStep])
                        x1 += frame.left
                        x2 += frame.left
                        lineOffset = startLine - self.topLine
                        y = frame.top + lineOffset * h
                        if lineOffset >= 0:
                            selRect = pygame.Rect(x1, y, (x2 - x1), h)
                    draw.rect(surface, self.sel_color, selRect)
                elif startLine < endLine:
                    x1, h = font.size(self.textL[startLine][0:startStep])
                    x2, h = font.size(self.textL[endLine][0:endStep])
                    x1 += frame.left
                    x2 += frame.left
                    lineOffsetS = startLine - self.topLine
                    lineOffsetE = endLine - self.topLine
                    lDiff = lineOffsetE - lineOffsetS
                    while lDiff > 1 and 0 <= lDiff + lineOffsetS + lDiff < self.dispLines:
                        y = frame.top + lineOffsetS * h + (lDiff - 1) * h
                        rects.append(
                            pygame.Rect(frame.left, y,
                                        frame.right - frame.left, h))
                        lDiff += -1
                    y = frame.top + lineOffsetS * h
                    if lineOffsetS >= 0:
                        rects.append(pygame.Rect(x1, y, frame.right - x1, h))
                    y = frame.top + lineOffsetE * h
                    if lineOffsetE < self.dispLines:
                        rects.append(
                            pygame.Rect(frame.left, y, x2 - frame.left, h))
                    for selRect in rects:
                        draw.rect(surface, self.sel_color, selRect)
                elif startLine > endLine:
                    x2, h = font.size(self.textL[startLine][0:startStep])
                    x1, h = font.size(self.textL[endLine][0:endStep])
                    x1 += frame.left
                    x2 += frame.left
                    lineOffsetE = startLine - self.topLine
                    lineOffsetS = endLine - self.topLine
                    lDiff = lineOffsetE - lineOffsetS
                    while lDiff > 1 and 0 <= lDiff + lineOffsetS + lDiff < self.dispLines:
                        y = frame.top + lineOffsetS * h + (lDiff - 1) * h
                        rects.append(
                            pygame.Rect(frame.left, y,
                                        frame.right - frame.left, h))
                        lDiff += -1
                    y = frame.top + lineOffsetS * h
                    if lineOffsetS >= 0:
                        rects.append(pygame.Rect(x1, y, frame.right - x1, h))
                    y = frame.top + lineOffsetE * h
                    if lineOffsetE < self.dispLines:
                        rects.append(
                            pygame.Rect(frame.left, y, x2 - frame.left, h))
                    for selRect in rects:
                        draw.rect(surface, self.sel_color, selRect)

                    # Draw Lines of Text
        h = 0
        for textLine in self.textL[self.topLine:self.topLine + self.dispLines]:
            image = font.render(textLine, True, fg)
            surface.blit(image, frame.move(0, h))
            h += font.size(textLine)[1]

        # Draw Cursor if Applicable
        if focused and ip is not None and i is not None and il is not None:
            if self.textL:
                x, h = font.size(self.textL[il][:i])
            else:
                x, h = (0, font.size("X")[1])
            if ip != i:
                if self.doFix:
                    self.move_insertion_point(-1)
                    self.doFix = False
                x += font.size(self.textL[il][i])[0]
                if not self.doFix:
                    self.move_insertion_point(1)
            x += frame.left
            y = frame.top + h * (il - self.topLine)
            draw.line(surface, fg, (x, y), (x, y + h - 1))

    def key_down(self, event):
        self.get_root().notMove = True
        if not event.cmd or (event.alt and event.unicode):
            k = event.key
            if k == K_LEFT:
                if not (key.get_mods() & KMOD_SHIFT):
                    self.move_insertion_point(-1)
                else:
                    if self.selection_end is None and self.selection_start is None and self.insertion_point is None:
                        return
                    if self.selection_end is None and self.insertion_point != 0:
                        self.selection_start = self.insertion_point
                        self.selection_end = self.insertion_point - 1
                        self.insertion_point = None
                    elif self.selection_end is not None and self.selection_end != 0:
                        self.selection_end -= 1
                        if self.selection_end == self.selection_start:
                            self.insertion_point = self.selection_end
                            self.selection_end = None
                            self.selection_start = None
                return
            if k == K_RIGHT:
                if not (key.get_mods() & KMOD_SHIFT):
                    self.move_insertion_point(1)
                else:
                    if self.selection_end is None and self.selection_start is None and self.insertion_point is None:
                        return
                    if self.selection_start is None and self.insertion_point < len(
                            self.text):
                        self.selection_start = self.insertion_point
                        self.selection_end = self.insertion_point + 1
                        self.insertion_point = None
                    elif self.selection_start is not None and self.selection_end < len(
                            self.text):
                        self.selection_end += 1
                        if self.selection_end == self.selection_start:
                            self.insertion_point = self.selection_end
                            self.selection_end = None
                            self.selection_start = None
                return
            if k == K_TAB:
                self.attention_lost()
                self.tab_to_next()
                return
            if k == K_DOWN:
                self.move_insertion_line(1)
                return
            if k == K_UP:
                self.move_insertion_line(-1)
                return
            if k == K_HOME:
                if not (key.get_mods() & KMOD_SHIFT):
                    self.selection_start = None
                    self.selection_end = None
                    self.insertion_point = 0
                    self.sync_line_and_step()
                elif self.insertion_point != 0:
                    if self.insertion_point is not None:
                        self.selection_start = self.insertion_point
                        self.insertion_point = None
                    self.selection_end = 0
                    if self.selection_end == self.selection_start:
                        self.insertion_point = self.selection_end
                        self.selection_end = None
                        self.selection_start = None
                        self.sync_line_and_step()
                return
            if k == K_END:
                if not (key.get_mods() & KMOD_SHIFT):
                    self.selection_start = None
                    self.selection_end = None
                    self.insertion_point = len(self.text)
                    self.sync_line_and_step()
                elif self.insertion_point != len(self.text):
                    if self.insertion_point is not None:
                        self.selection_start = self.insertion_point
                        self.insertion_point = None
                    self.selection_end = len(self.text)
                    if self.selection_end == self.selection_start:
                        self.insertion_point = self.selection_end
                        self.selection_end = None
                        self.selection_start = None
                        self.sync_line_and_step()
                return
            try:
                c = event.unicode
            except ValueError:
                print 'value error'
                c = ""
            if self.insert_char(c, k) != 'pass':
                return
        if event.cmd and event.unicode:
            if event.key == K_c or event.key == K_x:
                try:
                    #pygame.scrap.put(SCRAP_TEXT, self.text)
                    text, i = self.get_text_and_insertion_point()
                    if i is None and (self.selection_start is None
                                      or self.selection_end is None):
                        text = self.text
                    elif i is None and self.selection_start is not None and self.selection_end is not None:
                        text = text[(
                            min(self.selection_start, self.selection_end)
                        ):max(self.selection_start, self.selection_end)]
                    else:
                        return
                    pyperclip.copy(text)
                except:
                    print "scrap not available"
                finally:
                    if event.key == K_x and i is None:
                        self.insert_char(event.unicode, K_BACKSPACE)

            elif event.key == K_v:
                try:
                    #t = pygame.scrap.get(SCRAP_TEXT).replace('\0', '')
                    t = pyperclip.paste().replace("\n", " ")
                    if t is not None:
                        if self.insertion_point is not None:
                            self.text = self.text[:self.
                                                  insertion_point] + t + self.text[
                                                      self.insertion_point:]
                            self.insertion_point += len(t)
                        elif self.insertion_point is None and (
                                self.selection_start is None
                                or self.selection_end is None):
                            self.text = t
                            self.insertion_point = len(t)
                        elif self.insertion_point is None and self.selection_start is not None and self.selection_end is not None:
                            self.selection_point = min(
                                self.selection_start,
                                self.selection_end) + len(t)
                            self.text = self.text[:(
                                min(self.selection_start, self.selection_end)
                            )] + t + self.text[(max(self.selection_start, self.
                                                    selection_end)):]
                            self.selection_start = None
                            self.selection_end = None
                        else:
                            return
                        self.change_text(self.text)
                        self.sync_line_and_step()
                except:
                    print "scrap not available"
                    #print repr(t)
            else:
                self.attention_lost()

    def key_up(self, event):
        pass

    def get_text_and_insertion_point(self):
        text = self.get_text()
        i = self.insertion_point
        if i is not None:
            i = max(0, min(i, len(text)))
        return text, i

    def get_text_and_insertion_data(self):
        text = self.get_text()
        i = self.insertion_step
        il = self.insertion_line
        if il is not None:
            il = max(0, min(il, (len(self.textL) - 1)))
        if i is not None and il is not None and len(self.textL) > 0:
            i = max(0, min(i, len(self.textL[il]) - 1))
        return text, i, il

    def move_insertion_point(self, d):
        self.selection_end = None
        self.selection_start = None
        text, i = self.get_text_and_insertion_point()
        if i is None:
            if d > 0:
                i = len(text)
            else:
                i = 0
        else:
            i = max(0, min(i + d, len(text)))
        self.insertion_point = i
        self.sync_line_and_step()

    def sync_line_and_step(self):
        self.updateTextWrap()
        self.sync_insertion_line()
        self.sync_insertion_step()

    def sync_insertion_line(self):
        ip = self.insertion_point
        i = 0

        for refVal in self.textRefList:
            if ip > refVal:
                i += 1
            elif ip <= refVal:
                break
        self.insertion_line = i

    def sync_insertion_step(self):
        ip = self.insertion_point
        il = self.insertion_line

        if ip is None:
            self.move_insertion_point(0)
            ip = self.insertion_point
        if il is None:
            self.move_insertion_line(0)
            il = self.insertion_line

        if il > 0:
            refPoint = self.textRefList[il - 1]
        else:
            refPoint = 0
        self.insertion_step = ip - refPoint

    def get_char_position(self, i):
        j = 0

        for refVal in self.textRefList:
            if i > refVal:
                j += 1
            elif i <= refVal:
                break
        line = j

        if line > 0:
            refPoint = self.textRefList[line - 1]
        else:
            refPoint = 0
        step = i - refPoint

        return line, step

    def move_insertion_line(self, d):
        text, i, il = self.get_text_and_insertion_data()

        if self.selection_end is not None:
            endLine, endStep = self.get_char_position(self.selection_end)
            il = endLine
            i = endStep
            self.insertion_step = i
            self.selection_end = None
            self.selection_start = None
        if il is None:
            if d > 0:
                if len(self.textL) > 1:
                    self.insertion_line = d
                else:
                    self.insertion_line = 0
            else:
                self.insertion_line = 0
        if i is None:
            self.insertion_step = 0
        elif 0 <= d + il + d < len(self.textL):
            self.insertion_line = il + d
        if self.insertion_line > 0:
            self.insertion_point = self.textRefList[self.insertion_line -
                                                    1] + self.insertion_step
            if self.insertion_point > len(self.text):
                self.insertion_point = len(self.text)
        else:
            if self.insertion_step is not None:
                self.insertion_point = self.insertion_step
            else:
                self.insertion_point = 0
                self.insertion_step = 0

    def insert_char(self, c, k=None):
        if self.upper:
            c = c.upper()
        if k == K_BACKSPACE or k == K_DELETE:
            text, i = self.get_text_and_insertion_point()
            if i is None and (self.selection_start is None
                              or self.selection_end is None):
                text = ""
                i = 0
                self.insertion_line = i
                self.insertion_step = i
            elif i is None and self.selection_start is not None and self.selection_end is not None:
                i = min(self.selection_start, self.selection_end)
                text = text[:(
                    min(self.selection_start, self.selection_end))] + text[
                        (max(self.selection_start, self.selection_end)):]
                self.selection_start = None
                self.selection_end = None
            elif i > 0:
                if k == K_BACKSPACE:
                    text = text[:i - 1] + text[i:]
                    i -= 1
                else:
                    text = text[:i] + text[i + 1:]
            self.change_text(text)
            self.insertion_point = i
            self.sync_line_and_step()
            return
        elif c == "\r" or c == "\x03":
            return self.call_handler('enter_action')
        elif c == "\x1b":
            return self.call_handler('escape_action')
        elif c >= "\x20":
            if self.allow_char(c):
                text, i = self.get_text_and_insertion_point()
                if i is None and (self.selection_start is None
                                  or self.selection_end is None):
                    text = c
                    i = 1
                elif i is None and self.selection_start is not None and self.selection_end is not None:
                    i = min(self.selection_start, self.selection_end) + 1
                    text = text[:(min(self.selection_start, self.selection_end)
                                  )] + c + text[(max(self.selection_start, self
                                                     .selection_end)):]
                    self.selection_start = None
                    self.selection_end = None
                else:
                    text = text[:i] + c + text[i:]
                    i += 1
                self.change_text(text)
                self.insertion_point = i
                self.sync_line_and_step()
                return
        return 'pass'

    @staticmethod
    def allow_char(c):
        return True

    def mouse_down(self, e):
        self.get_root().notMove = True
        self.focus()
        if e.button == 1:
            if e.num_clicks == 2:
                self.insertion_point = None
                self.selection_start = None
                self.selection_end = None
                return

            x, y = e.local
            i = self.pos_to_index(x, y)
            self.insertion_point = i
            self.selection_start = None
            self.selection_end = None
            self.sync_line_and_step()

        if e.button == 5:
            #            self.scroll_down()
            self.move_insertion_line(1)

        if e.button == 4:
            #            self.scroll_up()
            self.move_insertion_line(-1)

    def mouse_drag(self, e):
        x, y = e.local
        i = self.pos_to_index(x, y)

        if self.insertion_point is not None:
            if i != self.insertion_point:
                if self.selection_start is None:
                    self.selection_start = self.insertion_point
                self.selection_end = i
                self.insertion_point = None
        else:
            if self.selection_start is None:
                self.selection_start = i
            else:
                if self.selection_start == i:
                    self.selection_start = None
                    self.selection_end = None
                    self.insertion_point = i
                else:
                    self.selection_end = i

    def pos_to_index(self, x, y):
        textL = self.textL
        textRef = self.textRefList
        topLine = self.topLine
        dispLines = self.dispLines
        font = self.font

        if textL:
            h = font.size("X")[1]
            line = y // h

            if line >= dispLines:
                line = dispLines - 1

            line += topLine

            if line >= len(textL):
                line = len(textL) - 1

            if line < 0:
                line = 0

            def width(i):
                return font.size(textL[line][:i])[0]

            i1 = 0
            i2 = len(textL[line])
            x1 = 0
            x2 = width(i2)
            while i2 - i1 > 1:
                i3 = (i1 + i2) // 2
                x3 = width(i3)
                if x > x3:
                    i1, x1 = i3, x3
                else:
                    i2, x2 = i3, x3
            if x - x1 > (x2 - x1) // 2:
                i = i2
            else:
                i = i1
            if line > 0:
                i = i + textRef[line - 1]
        else:
            i = 0
        return i

    def change_text(self, text):
        self.set_text(_(text))
        self.textChanged = True
        self.updateTextWrap()
        self.call_handler('change_action')

    def scroll_up(self):
        if self.topLine - 1 >= 0:
            self.topLine += -1

    def scroll_down(self):
        if self.topLine + 1 < len(self.textL) - self.dispLines + 1:
            self.topLine += 1

    def updateTextWrap(self):
        # Update text wrapping for box
        font = self.font
        frame = self.get_margin_rect()
        frameW, frameH = frame.size
        if self.textChanged:
            ix = 0
            iz = 0
            textLi = 0
            text = self.text
            textL = []
            textR = []
            while ix < len(text):
                ix += 1
                if ix == '\r' or ix == '\x03' or ix == '\n':
                    print("RETURN FOUND")
                    if len(textL) > textLi:
                        textL[textLi] = text[iz:ix]
                        textR[textLi] = ix
                    else:
                        textL.append(text[iz:ix])
                        textR.append(ix)
                    iz = ix + 1
                    textLi += 1
                segW = font.size(text[iz:ix])[0]
                if segW > frameW:
                    if len(textL) > textLi:
                        textL[textLi] = text[iz:ix - 1]
                        textR[textLi] = ix - 1
                    else:
                        textL.append(text[iz:ix - 1])
                        textR.append(ix - 1)
                    iz = ix - 1
                    textLi += 1
            if iz < ix:
                if len(textL) > textLi:
                    textL[textLi] = text[iz:ix]
                    textR[textLi] = ix
                else:
                    textL.append(text[iz:ix])
                    textR.append(ix)
                iz = ix
                textLi += 1
            textL = textL[:textLi]
            textR = textR[:textLi]
            self.textL = textL
            self.textRefList = textR
            self.textChanged = False

            i = 0
Ejemplo n.º 9
0
class TextEditor(Widget):
    upper = False
    tab_stop = True
    _text = u""

    def __init__(self, width, upper=None, **kwds):
        Widget.__init__(self, **kwds)
        self.set_size_for_text(width)
        if upper is not None:
            self.upper = upper
        self.insertion_point = None
        self.root = self.get_root()

    def get_text(self):
        return self._text

    def set_text(self, text):
        self._text = _(text)

    text = overridable_property('text')

    def draw(self, surface):
        frame = self.get_margin_rect()
        fg = self.fg_color
        font = self.font
        focused = self.has_focus()
        text, i = self.get_text_and_insertion_point()
        if focused and i is None:
            surface.fill(self.sel_color, frame)
        image = font.render(text, True, fg)
        surface.blit(image, frame)
        if focused and i is not None:
            x, h = font.size(text[:i])
            x += frame.left
            y = frame.top
            draw.line(surface, fg, (x, y), (x, y + h - 1))

    def key_down(self, event):
        self.root.notMove = True
        if not event.cmd or (event.alt and event.unicode):
            k = event.key
            if k == K_LEFT:
                self.move_insertion_point(-1)
                return
            if k == K_RIGHT:
                self.move_insertion_point(1)
                return
            if k == K_TAB:
                self.attention_lost()
                self.tab_to_next()
                return
            try:
                c = event.unicode
            except ValueError:
                c = ""
            if k != K_DOWN and k != K_UP:
                if self.insert_char(c, k) != 'pass':
                    return
        if event.cmd and event.unicode:
            if event.key == K_c:
                try:
                    #pygame.scrap.put(SCRAP_TEXT, self.text)
                    pyperclip.copy(self.text)
                except:
                    print "scrap not available"

            elif event.key == K_v:
                try:
                    #t = pygame.scrap.get(SCRAP_TEXT).replace('\0', '')
                    t = pyperclip.paste()
                    DEF_ENC = locale.getdefaultlocale()[1]
                    if DEF_ENC is None:
                        DEF_ENC = "UTF-8"
                    if type(t) == unicode and DEF_ENC != "UTF-8":
                        t = t.encode(DEF_ENC)
                    allow = True
                    for char in t:
                        if not self.allow_char(char):
                            allow = False
                    if allow:
                        self.text = t
                except:
                    print "scrap not available"
            else:
                self.attention_lost()

    def key_up(self, event):
        pass

    def get_text_and_insertion_point(self):
        text = self.get_text()
        i = self.insertion_point
        if i is not None:
            i = max(0, min(i, len(text)))
        return text, i

    def move_insertion_point(self, d):
        text, i = self.get_text_and_insertion_point()
        if i is None:
            if d > 0:
                i = len(text)
            else:
                i = 0
        else:
            i = max(0, min(i + d, len(text)))
        self.insertion_point = i

    def insert_char(self, c, k=None):
        if self.upper:
            c = c.upper()
        if k == K_BACKSPACE or k == K_DELETE:
            text, i = self.get_text_and_insertion_point()
            if i is None:
                text = ""
                i = 0
            else:
                if k == K_BACKSPACE:
                    text = text[:i - 1] + text[i:]
                    i -= 1
                else:
                    text = text[:i] + text[i + 1:]
            self.change_text(text)
            self.insertion_point = i
            return
        elif c == "\r" or c == "\x03":
            return self.call_handler('enter_action')
        elif c == "\x1b":
            return self.call_handler('escape_action')
        elif c >= "\x20":
            if self.allow_char(c):
                text, i = self.get_text_and_insertion_point()
                if i is None:
                    text = c
                    i = 1
                else:
                    text = text[:i] + c + text[i:]
                    i += 1
                self.change_text(text)
                self.insertion_point = i
                return
        return 'pass'

    def allow_char(self, c):
        return True

    def mouse_down(self, e):
        self.root.notMove = True
        self.focus()
        if e.num_clicks == 2:
            self.insertion_point = None
            return

        x, y = e.local
        i = self.pos_to_index(x)
        self.insertion_point = i

    def pos_to_index(self, x):
        text = self.get_text()
        font = self.font

        def width(i):
            return font.size(text[:i])[0]

        i1 = 0
        i2 = len(text)
        x1 = 0
        x2 = width(i2)
        while i2 - i1 > 1:
            i3 = (i1 + i2) // 2
            x3 = width(i3)
            if x > x3:
                i1, x1 = i3, x3
            else:
                i2, x2 = i3, x3
        if x - x1 > (x2 - x1) // 2:
            i = i2
        else:
            i = i1

        return i

    def change_text(self, text):
        self.set_text(text)
        self.call_handler('change_action')
Ejemplo n.º 10
0
class Label(Widget):

	text = overridable_property('text')
	align = overridable_property('align')

	highlight_color = ThemeProperty('highlight_color')
	disabled_color = ThemeProperty('disabled_color')
	highlight_bg_color = ThemeProperty('highlight_bg_color')
	enabled_bg_color = ThemeProperty('enabled_bg_color')
	disabled_bg_color = ThemeProperty('disabled_bg_color')
	
	enabled = True
	highlighted = False
	_align = 'l'
	
	def __init__(self, text, width = None, **kwds):
		Widget.__init__(self, **kwds)
		font = self.font
		lines = text.split("\n")
		tw, th = 0, 0
		for line in lines:
			w, h = font.size(line)
			tw = max(tw, w)
			th += h
		if width is not None:
			tw = width
		else:
			tw = max(1, tw)
		d = 2 * self.margin
		self.size = (tw + d, th + d)
		self._text = text
	
	def get_text(self):
		return self._text
	
	def set_text(self, x):
		self._text = x
	
	def get_align(self):
		return self._align
	
	def set_align(self, x):
		self._align = x

	def draw(self, surface):
		if not self.enabled:
			fg = self.disabled_color
			bg = self.disabled_bg_color
		elif self.highlighted:
			fg = self.highlight_color
			bg = self.highlight_bg_color
		else:
			fg = self.fg_color
			bg = self.enabled_bg_color
		self.draw_with(surface, fg, bg)

	def draw_with(self, surface, fg, bg = None):
		if bg:
			r = surface.get_rect()
			b = self.border_width
			if b:
				e = - 2 * b
				r.inflate_ip(e, e)
			surface.fill(bg, r)
		m = self.margin
		align = self.align
		width = surface.get_width()
		y = m
		lines = self.text.split("\n")
		font = self.font
		dy = font.get_linesize()
		for line in lines:
			image = font.render(line, True, fg)
			r = image.get_rect()
			r.top = y
			if align == 'l':
				r.left = m
			elif align == 'r':
				r.right = width - m
			else:
				r.centerx = width // 2
			surface.blit(image, r)
			y += dy
Ejemplo n.º 11
0
class Label(Widget):
    text = overridable_property('text')
    align = overridable_property('align')

    highlight_color = ThemeProperty('highlight_color')
    disabled_color = ThemeProperty('disabled_color')
    highlight_bg_color = ThemeProperty('highlight_bg_color')
    enabled_bg_color = ThemeProperty('enabled_bg_color')
    disabled_bg_color = ThemeProperty('disabled_bg_color')
    
    enabled = True
    highlighted = False
    _align = 'l'
    
    def __init__(self, text, width = None, **kwds):
        Widget.__init__(self, **kwds)
        font = self.font
        self.set_text(text)
        return
    
        lines = text.split("\n")
        tw, th = 0, 0
        for line in lines:
            w, h = font.size(line)
            tw = max(tw, w)
            th += h
        if width is not None:
            tw = width
        else:
            tw = max(1, tw)
        d = 2 * self.margin
        self.size = (tw + d, th + d)
        self._text = text
    
    
    def get_text(self):
        return self._text
    
    def _render_image(self):
        '''
        Render image to be blited on draw
        '''
        line_height = self.font.get_linesize()
        lines = self._text.split("\n")
        fg = self.fg_color
        bg = self.bg_color
        line_images = []
        line_width = 0
        for line in lines:
            print bg
            img = self.font.render(line, True, fg)
            line_width = max(line_width, img.get_width())
            line_images.append(img)
        space = self.border_width + self.margin
        self.width = 2*space + line_width
        self.height = 2*space + len(line_images)*line_height
        self._image = pygame.Surface(self.size)
        if bg:
            self._image.fill()
        dest = pygame.Rect((0,0),(self.width,line_height))
        for img in line_images:
            dest.width = img.get_width()
            if self.align=='c':
                dest.centerx = self.width/2
            elif self.align=='r':
                dest.right = self.width
#            else:
#                dest.left = 0
            # blit it
            self._image.blit(img, dest)
            dest.top += dest.height
            
            
    
    def set_text(self, text):
        self._text = text
        self._render_image()
    
    
    def get_align(self):
        return self._align
    
    def set_align(self, x):
        self._align = x
        self._render_image()

    def draw(self, surface):
        surface.blit(self._image, self.rect)


    def draw_with(self, surface, fg, bg = None):
        if bg:
            r = surface.get_rect()
            b = self.border_width
            if b:
                e = - 2 * b
                r.inflate_ip(e, e)
            surface.fill(bg, r)
        m = self.margin
        align = self.align
        width = surface.get_width()
        y = m
        lines = self.text.split("\n")
        font = self.font
        dy = font.get_linesize()
        for line in lines:
            image = font.render(line, True, fg)
            r = image.get_rect()
            r.top = y
            if align == 'l':
                r.left = m
            elif align == 'r':
                r.right = width - m
            else:
                r.centerx = width // 2
            surface.blit(image, r)
            y += dy