Example #1
0
def get_libs_version_string():
    """Get a string describing the versions of important libs.

    >>> type(get_libs_version_string()) == str
    True

    """
    versions = [
        ("Python", "{major}.{minor}.{micro}".format(
            major=sys.version_info.major,
            minor=sys.version_info.minor,
            micro=sys.version_info.micro,
        )),
        ("GTK", "{major}.{minor}.{micro}".format(
            major=Gtk.get_major_version(),
            minor=Gtk.get_minor_version(),
            micro=Gtk.get_micro_version(),
        )),
        ("GdkPixbuf", GdkPixbuf.PIXBUF_VERSION),
        ("Cairo", cairo.cairo_version_string()),  # NOT cairo.version
        ("GLib", "{major}.{minor}.{micro}".format(
            major=GLib.MAJOR_VERSION,
            minor=GLib.MINOR_VERSION,
            micro=GLib.MICRO_VERSION,
        )),
    ]
    return ", ".join([" ".join(t) for t in versions])
def _test():
    """Run interactive tests, outside the application."""
    logging.basicConfig()
    win = BrushEditorWindow()
    win.connect("delete-event", lambda *a: Gtk.main_quit())
    win.show_all()
    Gtk.main()
Example #3
0
 def __init__(self):
     """Initialize, called by the LayerMode FactoryAction making a menu"""
     Gtk.ImageMenuItem.__init__(self)
     menu = Gtk.Menu()
     self._menu_items = []
     prev_item = None
     spec_separator = (None, )
     modes_menu_spec = (STACK_MODES + spec_separator + STANDARD_MODES)
     for mode in modes_menu_spec:
         if mode is None:
             menu.append(Gtk.SeparatorMenuItem())
             continue
         label, tooltip = MODE_STRINGS.get(mode)
         if prev_item is None:
             item = Gtk.RadioMenuItem()
         else:
             item = Gtk.RadioMenuItem(group=prev_item)
         item.set_label(label)
         item.set_tooltip_text(tooltip)
         item.connect("activate", self._item_activated_cb, mode)
         menu.append(item)
         self._menu_items.append((mode, item))
         prev_item = item
     self._submenu = menu
     self.set_submenu(self._submenu)
     self._submenu.show_all()
     from gui.application import get_app
     app = get_app()
     self._model = app.doc.model
     rootstack = self._model.layer_stack
     rootstack.layer_properties_changed += self._update_actions
     rootstack.current_path_updated += self._update_actions
     self._updating = False
     self._update_actions()
Example #4
0
 def drag_begin_cb(self, widget, context):
     color = self.get_managed_color()
     preview = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 32,
                                    32)
     pixel = color.to_fill_pixel()
     preview.fill(pixel)
     Gtk.drag_set_icon_pixbuf(context, preview, 0, 0)
Example #5
0
 def __init__(self, app):
     self.app = app
     combo = Gtk.ComboBox()
     store = Gtk.ListStore()
     store.set_column_types((str, str))
     for k, v in _FILE_OPEN_OPTIONS:
         store.append((k, v))
     combo.set_model(store)
     combo.set_active(0)
     cell = Gtk.CellRendererText()
     combo.pack_start(cell, True)
     combo.add_attribute(cell, 'text', 1)
     combo_label = Gtk.Label(
         # TRANSLATORS: This is a label for a dropdown menu in the
         # TRANSLATORS: file chooser dialog when loading .ora files.
         label=C_("File Load Compat Options", "Compatibility mode:"))
     hbox = Gtk.HBox()
     hbox.set_spacing(6)
     hbox.pack_start(combo_label, False, False, 0)
     hbox.pack_start(combo, False, False, 0)
     hbox.show_all()
     hbox.set_visible(False)
     self._compat_override = None
     self._combo = combo
     combo.connect('changed', self._combo_changed_cb)
     self._widget = hbox
Example #6
0
def open_dialog(title, window, filters):
    """Show a file chooser dialog.

    Filters should be a list of tuples: (filtertitle, globpattern).

    Returns a tuple of the form (fileformat, filename). Here
    "fileformat" is the index of the filter that matched filename, or
    None if there were no matches).  "filename" is None if no file was
    selected.

    """
    dialog = Gtk.FileChooserDialog(title, window, Gtk.FileChooserAction.OPEN,
                                   (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                    Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
    dialog.set_default_response(Gtk.ResponseType.OK)
    for filter_title, pattern in filters:
        f = Gtk.FileFilter()
        f.set_name(filter_title)
        f.add_pattern(pattern)
        dialog.add_filter(f)

    result = (None, None)
    if dialog.run() == Gtk.ResponseType.OK:
        filename = dialog.get_filename()
        if isinstance(filename, bytes):
            filename = filename.decode('utf-8')
        file_format = None
        for i, (_junk, pattern) in enumerate(filters):
            if fnmatch(filename, pattern):
                file_format = i
                break
        result = (file_format, filename)
    dialog.hide()
    return result
Example #7
0
    def add_to_grid(self, grid, row):
        for c in self._confmap.values():
            c.setup_preference(self.get_prefpath())

        outgrid = grid
        outrow = row
        if self.label is not None:
            self._expander = Gtk.Expander(label=self.label)
            self._expander.set_expanded(self.expanded)
            outgrid = Gtk.Grid()
            self._expander.add(outgrid)
            grid.attach(self._expander, 1, row, 1, 1)
            outrow = 0
            row += 1

        if self.removable:
            self._remove_btn = Gtk.Button(label="Remove")
            self._remove_btn.connect("clicked", self.remove)
            outgrid.attach(self._remove_btn, 0, outrow, 2, 1)
            outrow += 1

        for c in self._confmap.values():
            outrow = c.add_to_grid(outgrid, outrow)

        for sc in self._subconfigs:
            outrow = sc.add_to_grid(outgrid, outrow)

        if self.label is not None:
            return row
        return outrow
Example #8
0
def _new_color_adjusters_menu():
    from gui.application import get_app
    app = get_app()
    menu = Gtk.Menu()
    action_names = [
        "HCYWheelTool",
        "HSVWheelTool",
        "PaletteTool",
        "HSVSquareTool",
        "HSVCubeTool",
        "ComponentSlidersTool",
        None,
        "CrossedBowlColorChangerTool",
        "WashColorChangerTool",
        "RingsColorChangerTool",
    ]
    for an in action_names:
        if an is None:
            item = Gtk.SeparatorMenuItem()
        else:
            action = app.find_action(an)
            item = Gtk.MenuItem()
            item.set_use_action_appearance(True)
            item.set_related_action(action)
        menu.append(item)
    return menu
Example #9
0
 def init_specialized_widgets(self, row):
     cname = "slow_tracking"
     label = Gtk.Label()
     # TRANSLATORS: Short alias for "Slow position tracking". This is
     # TRANSLATORS: used on the options panel.
     label.set_text(_("Smooth:"))
     label.set_alignment(1.0, 0.5)
     label.set_hexpand(False)
     self.adjustable_settings.add(cname)
     adj = self.app.brush_adjustment[cname]
     scale = Gtk.Scale.new(Gtk.Orientation.HORIZONTAL, adj)
     scale.set_draw_value(False)
     scale.set_hexpand(True)
     self.attach(label, 0, row, 1, 1)
     self.attach(scale, 1, row, 1, 1)
     row += 1
     cname = "fakepressure"
     label = Gtk.Label()
     # TRANSLATORS: Short alias for "Fake Pressure (for mouse)". This is
     # TRANSLATORS: used on the options panel.
     label.set_text(_("Pressure:"))
     label.set_alignment(1.0, 0.5)
     label.set_hexpand(False)
     changed_cb = self._fakepressure_value_changed_cb
     adj = Gtk.Adjustment(value=0.5,
                          lower=0.0,
                          upper=1.0,
                          step_increment=0.01,
                          page_increment=0.1)
     self.app.fake_adjustment['fakepressure'] = adj
     adj.connect("value-changed", changed_cb)
     scale = Gtk.Scale.new(Gtk.Orientation.HORIZONTAL, adj)
     scale.set_draw_value(False)
     scale.set_hexpand(True)
     self.attach(label, 0, row, 1, 1)
     self.attach(scale, 1, row, 1, 1)
     row += 1
     cname = "fakerotation"
     label = Gtk.Label()
     # TRANSLATORS: Short alias for "Fake Barrel Rotation (for mouse)".
     # TRANSLATORS: This is used on the options panel.
     label.set_text(_("Twist:"))
     label.set_alignment(1.0, 0.5)
     label.set_hexpand(False)
     changed_cb = self._fakerotation_value_changed_cb
     adj = Gtk.Adjustment(value=0.5,
                          lower=0.0,
                          upper=1.0,
                          step_increment=0.0625,
                          page_increment=0.25)
     self.app.fake_adjustment['fakerotation'] = adj
     adj.connect("value-changed", changed_cb)
     scale = Gtk.Scale.new(Gtk.Orientation.HORIZONTAL, adj)
     scale.set_draw_value(False)
     scale.set_hexpand(True)
     self.attach(label, 0, row, 1, 1)
     self.attach(scale, 1, row, 1, 1)
     row += 1
     return row
Example #10
0
def translate(hardware_keycode, state, group):
    # We may need to retry several times to deal with garbled text.

    keymap = Gdk.Keymap.get_default()

    # distinct
    it = list(set([group, 0, 1, 2]))

    ok_to_return = False
    keyval = None
    keyval_lower = None

    for g in it:
        res = keymap.translate_keyboard_state(hardware_keycode,
                                              Gdk.ModifierType(0), g)

        if not res:
            # PyGTK returns None when gdk_keymap_translate_keyboard_state()
            # returns false.  Not sure if this is a bug or a feature - the only
            # time I have seen this happen is when I put my laptop into sleep
            # mode.

            continue

        keyval = res[1]

        # consumed_modifiers = res[4]

        lbl = Gtk.accelerator_get_label(keyval, state)

        if is_ascii(lbl):
            ok_to_return = True
            break

    if not ok_to_return:
        logger.warning(
            'translate_keyboard_state() returned no valid response. '
            'Strange key pressed?')

        return None, None, None, None

    # We want to ignore irrelevant modifiers like ScrollLock.  The stored
    # key binding does not include modifiers that affected its keyval.
    mods = Gdk.ModifierType(state & Gtk.accelerator_get_default_mod_mask())

    keyval_lower = Gdk.keyval_to_lower(keyval)

    # If lowercasing affects the keysym, then we need to include
    # SHIFT in the modifiers. We re-upper case when we match against
    # the keyval, but display and save in caseless form.
    if keyval != keyval_lower:
        mods |= Gdk.ModifierType.SHIFT_MASK

    # So we get (<Shift>j, Shift+J) but just (plus, +). As I
    # understand it.

    accel_label = Gtk.accelerator_get_label(keyval_lower, mods)

    return keyval, keyval_lower, accel_label, mods
Example #11
0
 def wait_for_duration(self, duration):
     if not self.app:
         self.setup()
     self.signal = False
     GObject.timeout_add(int(duration * 1000.0), self.signal_cb)
     self.waiting = True
     while self.waiting:
         Gtk.main_iteration()
Example #12
0
 def drag_begin_cb(self, widget, context):
     preview = self.bm.selected_brush.preview
     preview = preview.scale_simple(
         preview.get_width() // 2,
         preview.get_height() // 2,
         GdkPixbuf.InterpType.BILINEAR,
     )
     Gtk.drag_set_icon_pixbuf(context, preview, 0, 0)
     super(BrushList, self).drag_begin_cb(widget, context)
Example #13
0
 def _drag_begin_cb(self, view, context):
     self.drag_began()
     src_path = self._docmodel.layer_stack.get_current_path()
     self._drag_src_path = src_path
     self._drag_dest_path = None
     src_treepath = Gtk.TreePath(src_path)
     src_icon_surf = self.create_row_drag_icon(src_treepath)
     Gtk.drag_set_icon_surface(context, src_icon_surf)
     self._hover_expand_timer_id = None
Example #14
0
 def wait_for_idle(self):
     "wait until the last mypaint idle handler has finished"
     if not self.app:
         self.setup()
     self.signal = False
     GObject.idle_add(self.signal_cb, priority=GObject.PRIORITY_LOW + 50)
     self.waiting = True
     while self.waiting:
         Gtk.main_iteration()
Example #15
0
 def __init__(self):
     """Initialize"""
     Gtk.Grid.__init__(self)
     self.connect("realize", self._realize_cb)
     # Widgets used in fullscreen mode
     fs_menu = Gtk.Menu()
     self._fs_menu = fs_menu
     self._fs_menubutton = FakeMenuButton(_("<b>MyPaint</b>"), fs_menu)
     self._fs_toolitem = Gtk.ToolItem()
    def _init_adjustments(self):
        """Initializes adjustments for the scales used internally

        When running as part of the MyPaint app, the brush setting ones are
        shared with it.
        """
        # Brush setting base values
        if self.app:
            for s in brushsettings.settings_visible:
                adj = self.app.brush_adjustment[s.cname]
                self._base_adj[s.cname] = adj
            # The application instance manages value-changed callbacks itself.
        else:
            for s in brushsettings.settings_visible:
                adj = Gtk.Adjustment(value=s.default,
                                     lower=s.min,
                                     upper=s.max,
                                     step_increment=0.01,
                                     page_increment=0.1)
                self._base_adj[s.cname] = adj
            changed_cb = self._testmode_base_value_adj_changed_cb
            for cname, adj in iteritems(self._base_adj):
                adj.connect('value-changed', changed_cb, cname)
        # Per-input scale maxima and minima
        for inp in brushsettings.inputs:
            name = inp.name
            adj = Gtk.Adjustment(value=1.0 / 4.0,
                                 lower=-1.0,
                                 upper=1.0,
                                 step_increment=0.01,
                                 page_increment=0.1)
            adj.connect("value-changed", self.input_adj_changed_cb, inp)
            self._input_y_adj[name] = adj
            lower = -20.0
            upper = +20.0
            # Pre-libmypaint split, the limits were read from json and could be
            # None. Now that cannot be checked directly, so instead check if
            # the limits are extreme (in libmypaint, they are set to +-FLT_MAX)
            if abs(inp.hard_min) < 1e16:
                lower = inp.hard_min
            if abs(inp.hard_max) < 1e16:
                upper = inp.hard_max
            adj = Gtk.Adjustment(value=inp.soft_min,
                                 lower=lower,
                                 upper=upper - 0.1,
                                 step_increment=0.01,
                                 page_increment=0.1)
            adj.connect("value-changed", self.input_adj_changed_cb, inp)
            self._input_xmin_adj[name] = adj
            adj = Gtk.Adjustment(value=inp.soft_max,
                                 lower=lower + 0.1,
                                 upper=upper,
                                 step_increment=0.01,
                                 page_increment=0.1)
            adj.connect("value-changed", self.input_adj_changed_cb, inp)
            self._input_xmax_adj[name] = adj
Example #17
0
    def __init__(self):
        super(SymmetryEditOptionsWidget, self).__init__(
            xalign=0.5,
            yalign=0.5,
            xscale=1.0,
            yscale=1.0,
        )
        self._symmetry_type_combo = None
        self._axis_sym_lines_entry = None
        from gui.application import get_app
        self.app = get_app()
        rootstack = self.app.doc.model.layer_stack
        x, y = rootstack.symmetry_center

        def pos_adj(start_val):
            return Gtk.Adjustment(
                value=start_val,
                upper=32000,
                lower=-32000,
                step_increment=1,
                page_increment=100,
            )

        self._axis_pos_adj_x = pos_adj(x)
        self._xpos_cb_id = self._axis_pos_adj_x.connect(
            'value-changed',
            self._axis_pos_adj_x_changed,
        )
        self._axis_pos_adj_y = pos_adj(y)
        self._ypos_cb_id = self._axis_pos_adj_y.connect(
            'value-changed',
            self._axis_pos_adj_y_changed,
        )
        self._axis_angle = Gtk.Adjustment(
            value=rootstack.symmetry_angle,
            upper=180,
            lower=0,
            step_increment=1,
            page_increment=15,
        )
        self._angle_cb_id = self._axis_angle.connect(
            "value-changed", self._angle_value_changed)
        self._axis_symmetry_lines = Gtk.Adjustment(
            value=rootstack.symmetry_lines,
            upper=50,
            lower=2,
            step_increment=1,
            page_increment=3,
        )
        self._lines_cb_id = self._axis_symmetry_lines.connect(
            'value-changed',
            self._axis_rot_symmetry_lines_changed,
        )

        self._init_ui()
        rootstack.symmetry_state_changed += self._symmetry_state_changed_cb
Example #18
0
 def _make_image_button(text, icon_name, cb):
     b = Gtk.Button(label=text)
     i = Gtk.Image()
     i.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
     b.set_image(i)
     b.set_image_position(Gtk.PositionType.TOP)
     b.connect("clicked", cb)
     b.set_can_focus(False)
     b.set_can_default(False)
     return b
Example #19
0
 def _layer_deleted_cb(self, root, path):
     """Updates the display after a layer is removed"""
     self.invalidate_iters()
     self.row_deleted(Gtk.TreePath(path))
     parent_path = path[:-1]
     if not parent_path:
         return
     parent = self._root.deepget(parent_path)
     if len(parent) == 0:
         parent_it = self.get_iter(parent_path)
         self.row_has_child_toggled(Gtk.TreePath(parent_path), parent_it)
Example #20
0
    def __init__(self):
        super(SymmetryEditOptionsWidget, self).__init__(
            xalign=0.5,
            yalign=0.5,
            xscale=1.0,
            yscale=1.0,
        )
        self._axis_pos_x_dialog = None
        self._axis_pos_x_button = None
        self._axis_pos_y_dialog = None
        self._axis_pos_y_button = None
        self._symmetry_type_combo = None
        self._axis_rot_sym_lines_entry = None
        from gui.application import get_app
        self.app = get_app()
        rootstack = self.app.doc.model.layer_stack
        self._axis_pos_adj_x = Gtk.Adjustment(
            value=rootstack.symmetry_x,
            upper=32000,
            lower=-32000,
            step_increment=1,
            page_increment=100,
        )
        self._axis_pos_adj_x.connect(
            'value-changed',
            self._axis_pos_adj_x_changed,
        )
        self._axis_pos_adj_y = Gtk.Adjustment(
            value=rootstack.symmetry_y,
            upper=32000,
            lower=-32000,
            step_increment=1,
            page_increment=100,
        )
        self._axis_pos_adj_y.connect(
            'value-changed',
            self._axis_pos_adj_y_changed,
        )
        self._axis_rot_symmetry_lines = Gtk.Adjustment(
            value=rootstack.rot_symmetry_lines,
            upper=50,
            lower=2,
            step_increment=1,
            page_increment=3,
        )
        self._axis_rot_symmetry_lines.connect(
            'value-changed',
            self._axis_rot_symmetry_lines_changed,
        )

        self._init_ui()
        rootstack.symmetry_state_changed += self._symmetry_state_changed_cb
        self._update_axis_pos_x_button_label(rootstack.symmetry_x)
        self._update_axis_pos_y_button_label(rootstack.symmetry_y)
Example #21
0
 def wait_for_gui(self):
     "wait until all GUI updates are done, but don't wait for bg tasks"
     if not self.app:
         self.setup()
     self.signal = False
     GObject.idle_add(
         self.signal_cb,
         priority=GObject.PRIORITY_DEFAULT_IDLE - 1,
     )
     self.waiting = True
     while self.waiting:
         Gtk.main_iteration()
Example #22
0
 def __init__(self, parent, target):
     super(HCYMaskTemplateDialog, self).__init__(
         title=C_(
             u"HCY Gamut Mask new-from-template dialog: window title",
             "New Gamut Mask from Template",
         ),
         transient_for=parent,
         modal=True,
         destroy_with_parent=True,
         window_position=Gtk.WindowPosition.MOUSE,
     )
     self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT)
     target_mgr = target.get_color_manager()
     prefs_ro = deepcopy(target_mgr.get_prefs())
     datapath = target_mgr.get_data_path()
     mgr = ColorManager(prefs=prefs_ro, datapath=datapath)
     mgr.set_wheel_type(target_mgr.get_wheel_type())
     self.target = target
     for name, desc, mask_shapes_float in self.__templates:
         mask = []
         for mask_shape_float in mask_shapes_float:
             shape = []
             for h, c, y in mask_shape_float:
                 h = mgr.undistort_hue(h)
                 shape.append(HCYColor(h, c, y))
             mask.append(shape)
         label = Gtk.Label()
         label.set_markup("<b>%s</b>\n\n%s" % (name, desc))
         label.set_size_request(375, -1)
         label.set_line_wrap(True)
         label.set_alignment(0, 0.5)
         preview = HCYMaskPreview()
         preview.set_color_manager(mgr)
         preview.set_mask(mask)
         preview_frame = Gtk.AspectFrame(obey_child=True)
         preview_frame.add(preview)
         preview_frame.set_shadow_type(Gtk.ShadowType.NONE)
         hbox = Gtk.HBox()
         hbox.set_spacing(6)
         hbox.pack_start(preview_frame, False, False, 0)
         hbox.pack_start(label, True, True, 0)
         button = Gtk.Button()
         button.add(hbox)
         button.set_relief(Gtk.ReliefStyle.NONE)
         button.connect("clicked", self.__button_clicked_cb, mask)
         self.vbox.pack_start(button, True, True, 0)
     self.connect("response", self.__response_cb)
     self.connect("show", self.__show_cb)
     for w in self.vbox:
         w.show_all()
     ref_color = target.get_managed_color()
     mgr.set_color(ref_color)
Example #23
0
def _test():
    """Interactive UI testing for SettingsEditor and Monitor"""
    logging.basicConfig(level=logging.DEBUG)
    win = Gtk.Window()
    win.set_title("gui.device.SettingsEditor")
    win.set_default_size(500, 400)
    win.connect("destroy", Gtk.main_quit)
    monitor = Monitor(app=None)
    editor = SettingsEditor(monitor)
    win.add(editor)
    win.show_all()
    Gtk.main()
    print(monitor._prefs)
Example #24
0
    def run():
        logger.debug('user_datapath: %r', userdatapath)
        logger.debug('user_confpath: %r', userconfpath)

        # User-configured locale (if enabled by user)
        set_user_configured_locale(userconfpath)

        # Locale setting
        from lib.gettext_setup import init_gettext
        init_gettext(localepath)

        # mypaintlib import is performed first in gui.application now.
        from gui import application

        app_state_dirs = application.StateDirs(
            app_data=datapath,
            app_icons=iconspath,
            user_data=userdatapath,
            user_config=userconfpath,
        )
        app = application.Application(
            filenames=args,
            state_dirs=app_state_dirs,
            version=version,
            fullscreen=options.fullscreen,
        )

        # Gtk must not be imported before init_gettext
        # has been run - else locales will not be set
        # up properly (e.g: left-to-right interfaces for right-to-left scripts)
        # Note that this is not the first import of Gtk in the __program__;
        # it is imported indirectly via the import of gui.application
        from lib.gibindings import Gtk
        settings = Gtk.Settings.get_default()
        dark = app.preferences.get("ui.dark_theme_variant", True)
        settings.set_property("gtk-application-prefer-dark-theme", dark)

        if debug and options.run_and_quit:
            from lib.gibindings import GLib
            GLib.timeout_add(1000, lambda *a: Gtk.main_quit())
        else:
            from gui import gtkexcepthook
            func = app.filehandler.confirm_destructive_action
            gtkexcepthook.quit_confirmation_func = func

        # temporary workaround for gtk3 Ctrl-C bug:
        # https://bugzilla.gnome.org/show_bug.cgi?id=622084
        import signal
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        Gtk.main()
Example #25
0
    def __init__(self, combobox, prefs):
        self.combo = combobox
        self.prefs = prefs
        options_store = Gtk.ListStore()
        options_store.set_column_types((str, str))
        for option in self._OPTIONS:
            options_store.append((option, self._LABELS[option]))
        combobox.set_model(options_store)

        cell = Gtk.CellRendererText()
        combobox.pack_start(cell, True)
        combobox.add_attribute(cell, 'text', 1)
        self.update_ui()
        combobox.connect('changed', self.changed_cb)
def _test():
    win = Gtk.Window()
    win.set_title("accelmap.py")
    win.connect("destroy", Gtk.main_quit)
    builder = Gtk.Builder()
    import gui.factoryaction  # noqa F401: for side effects only
    builder.add_from_file("gui/resources.xml")
    uimgr = builder.get_object("app_ui_manager")
    editor = AccelMapEditor()
    editor.ui_manager = uimgr
    win.add(editor)
    win.set_default_size(400, 300)
    win.show_all()
    Gtk.main()
Example #27
0
 def message_dialog(self,
                    text,
                    secondary_text=None,
                    long_text=None,
                    title=None,
                    investigate_dir=None,
                    investigate_str=None,
                    **kwds):
     """Utility function to show a message/information dialog"""
     d = Gtk.MessageDialog(transient_for=self.drawWindow,
                           buttons=Gtk.ButtonsType.NONE,
                           **kwds)
     # Auxiliary actions first...
     if investigate_dir and os.path.isdir(investigate_dir):
         if not investigate_str:
             tmpl = _(u"Open Folder “{folder_basename}”…")
             investigate_str = tmpl.format(
                 folder_basename=os.path.basename(investigate_dir), )
         d.add_button(investigate_str, -1)
     # ... so that the main actions end up in the bottom-right of the
     # dialog (reversed for rtl scripts), where the eye ends up
     # naturally at the end of the flow.
     d.add_button(_("OK"), Gtk.ResponseType.OK)
     markup = lib.xml.escape(unicode(text))
     d.set_markup(markup)
     if title is not None:
         d.set_title(unicode(title))
     if secondary_text is not None:
         secondary_markup = lib.xml.escape(unicode(secondary_text))
         d.format_secondary_markup(secondary_markup)
     if long_text is not None:
         buf = Gtk.TextBuffer()
         buf.set_text(unicode(long_text))
         tv = Gtk.TextView.new_with_buffer(buf)
         tv.show()
         tv.set_editable(False)
         tv.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
         scrolls = Gtk.ScrolledWindow()
         scrolls.show()
         scrolls.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS)
         scrolls.add(tv)
         scrolls.set_size_request(-1, 300)
         scrolls.set_shadow_type(Gtk.ShadowType.IN)
         d.get_message_area().pack_start(scrolls, True, True, 0)
     response = d.run()
     d.destroy()
     if response == -1:
         lib.fileutils.startfile(investigate_dir, "open")
Example #28
0
 def _realize_cb(self, widget):
     """Assorted setup when the widget is realized"""
     assert self.menubar is not None
     assert self.toolbar1 is not None
     assert self.toolbar2 is not None
     # Packing details for Grid
     self.menubar.set_hexpand(True)
     self.toolbar1.set_hexpand(True)
     self.toolbar2.set_hexpand(False)
     self._fs_menubutton.set_hexpand(False)
     # Specialized styles
     prov = Gtk.CssProvider()
     prov.load_from_data(b"""
             .topbar {
                 padding: 0px; /* required by toolbars */
                 margin: 0px;  /* required by menubar */
             }
         """)
     bars = [self.toolbar1, self.toolbar2, self.menubar]
     for b in bars:
         style = b.get_style_context()
         style.add_provider(prov, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
         style.add_class("topbar")
     # Initial packing; assume a non-fullscreened state
     self.attach(self.menubar, 0, 0, 2, 1)
     self.attach(self.toolbar1, 0, 1, 1, 1)
     self.attach(self.toolbar2, 1, 1, 1, 1)
     # Track state transitions of the window's toplevel
     toplevel = self.get_toplevel()
     assert toplevel is not None
     toplevel.connect("window-state-event", self._toplevel_state_event_cb)
Example #29
0
 def _clicked_cb(self, button):
     """Handle click events on the initiator button."""
     event = Gtk.get_current_event()
     assert event is not None
     assert event.type == Gdk.EventType.BUTTON_RELEASE, (
         "The docs lie! Current event's type is %r." % (event.type, ), )
     self._grab.activate_from_button_event(event)
Example #30
0
    def _clone_menu(self, xml, name, owner=None):
        """Menu duplicator

        Hopefully temporary hack for converting UIManager XML describing the
        main menubar into a rebindable popup menu. UIManager by itself doesn't
        let you do this, by design, but we need a bigger menu than the little
        things it allows you to build.
        """
        ui_elt = ET.fromstring(xml)
        rootmenu_elt = ui_elt.find("menubar")
        rootmenu_elt.attrib["name"] = name
        xml = ET.tostring(ui_elt)
        xml = xml.decode("utf-8")
        self.app.ui_manager.add_ui_from_string(xml)
        tmp_menubar = self.app.ui_manager.get_widget('/' + name)
        popupmenu = Gtk.Menu()
        for item in tmp_menubar.get_children():
            tmp_menubar.remove(item)
            popupmenu.append(item)
        if owner is not None:
            popupmenu.attach_to_widget(owner, None)
        popupmenu.set_title("MyPaint")
        popupmenu.connect("selection-done", self.popupmenu_done_cb)
        popupmenu.connect("deactivate", self.popupmenu_done_cb)
        popupmenu.connect("cancel", self.popupmenu_done_cb)
        self.popupmenu_last_active = None
        return popupmenu