Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

Version: 18.5.0-1 

/ opt / cxoffice / lib / python / placeholderentry.py

# (c) Copyright 2015. CodeWeavers, Inc.

import gobject
import gtk

def _blend_colors(a, b, a_weight, b_weight):
    total_weight = a_weight + b_weight
    return gtk.gdk.Color(
        (a.red * a_weight + b.red * b_weight) // total_weight,
        (a.green * a_weight + b.green * b_weight) // total_weight,
        (a.blue * a_weight + b.blue * b_weight) // total_weight)

class PlaceholderEntry(gtk.Entry):
    __gtype_name__ = 'PlaceholderEntry'
    __gsignals__ = {
        'real-text-changed': (gobject.SIGNAL_RUN_LAST, None, (str,)), # text
    }
    __gproperties__ = {
        'placeholder-string' :
        (gobject.TYPE_STRING,
         "Placeholder String",
         "Text displayed when the textbox is empty.",
         '',
         gobject.PARAM_READABLE | gobject.PARAM_WRITABLE | gobject.PARAM_CONSTRUCT),
        'placeholder-focused' :
        (gobject.TYPE_BOOLEAN,
         "Placeholder Focused",
         "Show placeholder string even when the textbox is focused.",
         True,
         gobject.PARAM_READABLE | gobject.PARAM_WRITABLE | gobject.PARAM_CONSTRUCT),
    }

    def __init__(self):
        self._showing_placeholder = False
        self._setting_placeholder = False
        self._setting_style = False
        self._placeholder_string = ""
        self._placeholder_focus = True
        self._postev_source = None
        self._preedit = ""
        gtk.Entry.__init__(self)

        for signal in ('grab-focus', 'button-press-event', 'button-release-event', 'motion-notify-event', 'key-press-event', 'key-release-event'):
            self.connect(signal, self._pre_event)
            self.connect_after(signal, self._post_event)

        self.connect('changed', self._on_changed)
        self.connect('insert-text', self._on_insert_text)
        self.connect('insert-at-cursor', self._on_insert_at_cursor)
        self.connect('move-cursor', self._on_move_cursor)
        self.connect('preedit-changed', self._on_preedit_changed)
        self.connect('style-set', self._on_style_set)
        self.connect('focus-in-event', self._on_focus_in)
        self.connect('focus-out-event', self._on_focus_out)

    def do_get_property(self, prop):
        if prop.name == 'placeholder-string':
            return self._placeholder_string
        elif prop.name == 'placeholder-focused':
            return self._placeholder_focus
        else:
            raise AttributeError("unknown property %s" % prop.name)

    def do_set_property(self, prop, value):
        if prop.name == 'placeholder-string':
            self._placeholder_string = value
            self._adjust_text()
        elif prop.name == 'placeholder-focused':
            self._placeholder_focus = value
            self._adjust_text()
        else:
            raise AttributeError("unknown property %s" % prop.name)

    def _adjust_style(self):
        if self._setting_style:
            return
        self._setting_style = True

        self.modify_text(gtk.STATE_NORMAL, None)
        self.modify_text(gtk.STATE_ACTIVE, None)

        if self._showing_placeholder:
            # pylint: disable=E1101
            self.modify_text(gtk.STATE_NORMAL, _blend_colors(self.style.text[gtk.STATE_NORMAL], self.style.base[gtk.STATE_NORMAL], 1, 1))
            self.modify_text(gtk.STATE_ACTIVE, _blend_colors(self.style.text[gtk.STATE_ACTIVE], self.style.base[gtk.STATE_ACTIVE], 1, 1))

        self._setting_style = False

    def _suppress_placeholder(self):
        if self._preedit or (not self._placeholder_focus and self.is_focus()):
            return True
        return False

    def _adjust_text(self):
        if not self._showing_placeholder and self._placeholder_string and not self._suppress_placeholder() and not self.get_text():
            self._showing_placeholder = True
            self._adjust_style()
        if self._showing_placeholder and self._suppress_placeholder():
            self._kill_placeholder(True)
        if self._showing_placeholder:
            display_string = self._placeholder_string
            if self.get_text() != display_string:
                self._setting_placeholder = True
                self.set_text(display_string)
                self._setting_placeholder = False
            if self.get_selection_bounds() or self.get_position():
                self.set_position(0)

    def _kill_placeholder(self, clear=False):
        if self._showing_placeholder:
            self._showing_placeholder = False
            self._setting_placeholder = True
            if clear:
                self.set_text('')
            self._setting_placeholder = False
            self._adjust_style()

    def get_real_text(self):
        if self._showing_placeholder:
            return ""
        return self.get_text()

    def _pre_event(self, *_args):
        self._kill_placeholder(True)
        if not self._postev_source:
            # HIGH_IDLE is just before redraws, preventing flickering
            self._postev_source = gobject.idle_add(self._post_event, priority=gobject.PRIORITY_HIGH_IDLE)

    def _post_event(self, *_args):
        self._adjust_text()
        if self._postev_source:
            gobject.source_remove(self._postev_source)
            self._postev_source = None

    def _on_changed(self, _editable):
        if self._setting_placeholder:
            return
        if self._showing_placeholder and self.get_text() not in ('', self._placeholder_string):
            self._kill_placeholder()
        self._adjust_text()
        self.emit('real-text-changed', self.get_real_text())

    def _on_insert_text(self, _editable, _new_text, _new_text_length, _position):
        if self._setting_placeholder:
            return
        if self._showing_placeholder:
            self._kill_placeholder(True)

    def _on_insert_at_cursor(self, _entry, _string):
        if self._setting_placeholder:
            return
        if self._showing_placeholder:
            self._kill_placeholder(True)

    def _on_move_cursor(self, _entry, _step, _count, _extend_selection):
        if self._showing_placeholder:
            self.stop_emission('move-cursor')

    def _on_preedit_changed(self, _entry, preedit):
        self._preedit = preedit
        self._adjust_text()

    def _on_style_set(self, _widget, _previous_style):
        if self._setting_style:
            return
        if self._showing_placeholder:
            self._adjust_style()

    def _on_focus_in(self, _widget, _event):
        self._adjust_text()

    def _on_focus_out(self, _widget, _event):
        self._adjust_text()

if __name__ == '__main__':
    entry1 = PlaceholderEntry()
    entry2 = PlaceholderEntry()

    entry1.set_property('placeholder-string', 'Entry One')
    entry2.set_property('placeholder-string', 'Entry Two')

    entry2.set_property('has-frame', False)
    entry2.set_property('placeholder-focused', False)

    def on_real_text_changed(_entry, text, name):
        print "text changed", text, name

    entry1.connect('real-text-changed', on_real_text_changed, "Entry One")
    entry2.connect('real-text-changed', on_real_text_changed, "Entry Two")

    vbox = gtk.VBox()

    vbox.add(entry1)
    vbox.add(entry2)

    w = gtk.Window()
    w.add(vbox)
    w.show_all()
    w.connect("destroy", lambda w: gtk.main_quit())
    gtk.main()