1# This file is part of MyPaint.
2# Copyright (C) 2011-2018 by the MyPaint Development Team.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8
9"""The application toolbar, and its specialised widgets"""
10
11
12## Imports
13
14from __future__ import division, print_function
15import os
16from gettext import gettext as _
17
18from lib.gibindings import Gtk
19
20from . import widgets
21
22
23## Module constants
24
25
26FRAMEWORK_XML = 'toolbar.xml'
27MERGEABLE_XML = [
28    ("toolbar1_file", 'toolbar-file.xml', _("File handling")),
29    ("toolbar1_scrap", 'toolbar-scrap.xml', _("Scraps switcher")),
30    ("toolbar1_edit", 'toolbar-edit.xml', _("Undo and Redo")),
31    ("toolbar1_blendmodes", 'toolbar-blendmodes.xml', _("Blend Modes")),
32    ("toolbar1_linemodes", 'toolbar-linemodes.xml', _("Line Modes")),
33    ("toolbar1_view_modes", 'toolbar-view-modes.xml', _("View (Main)")),
34    ("toolbar1_view_manips", 'toolbar-view-manips.xml',
35        _("View (Alternative/Secondary)")),
36    ("toolbar1_view_resets", 'toolbar-view-resets.xml',
37        _("View (Resetting)")),
38]
39
40
41## Class definitions
42
43class ToolbarManager (object):
44    """Manager for toolbars, currently just the main one.
45
46    The main toolbar, /toolbar1, contains a menu button and quick
47    access to the painting tools.
48    """
49
50    def __init__(self, draw_window):
51        super(ToolbarManager, self).__init__()
52        self.draw_window = draw_window
53        self.app = draw_window.app
54        self.toolbar1_ui_loaded = {}  # {name: merge_id, ...}
55        self.init_actions()
56        ui_dir = os.path.dirname(os.path.abspath(__file__))
57        toolbarpath = os.path.join(ui_dir, FRAMEWORK_XML)
58        self.app.ui_manager.add_ui_from_file(toolbarpath)
59        self.toolbar1 = self.app.ui_manager.get_widget('/toolbar1')
60        self.toolbar1.set_style(Gtk.ToolbarStyle.ICONS)
61        self.toolbar1.set_icon_size(widgets.get_toolbar_icon_size())
62        self.toolbar1.set_border_width(0)
63        self.toolbar1.set_show_arrow(True)
64        self.toolbar1.connect(
65            "popup-context-menu",
66            self.on_toolbar1_popup_context_menu
67        )
68        self.toolbar1_popup = self.app.ui_manager\
69            .get_widget('/toolbar1-settings-menu')
70        for item in self.toolbar1:
71            if isinstance(item, Gtk.SeparatorToolItem):
72                item.set_draw(False)
73        self.toolbar2 = self.app.ui_manager.get_widget('/toolbar2')
74        self.toolbar2.set_style(Gtk.ToolbarStyle.ICONS)
75        self.toolbar2.set_icon_size(widgets.get_toolbar_icon_size())
76        self.toolbar2.set_border_width(0)
77        self.toolbar2.set_show_arrow(False)
78        for toolbar in (self.toolbar1, self.toolbar2):
79            styles = toolbar.get_style_context()
80            styles.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
81
82        # Merge in UI pieces based on the user's saved preferences
83        for action in self.settings_actions:
84            name = action.get_property("name")
85            active = self.app.preferences["ui.toolbar_items"].get(name, False)
86            action.set_active(active)
87            action.toggled()
88
89    def init_actions(self):
90        ag = self.draw_window.action_group
91        actions = []
92
93        self.settings_actions = []
94        for name, ui_xml, label in MERGEABLE_XML:
95            action = Gtk.ToggleAction.new(name, label, None, None)
96            action.connect("toggled", self.on_settings_toggle, ui_xml)
97            self.settings_actions.append(action)
98        actions += self.settings_actions
99
100        for action in actions:
101            ag.add_action(action)
102
103    def on_toolbar1_popup_context_menu(self, toolbar, x, y, button):
104        menu = self.toolbar1_popup
105
106        def _posfunc(*a):
107            return x, y, True
108        time = Gtk.get_current_event_time()
109        menu.popup(None, None, _posfunc, None, button, time)
110
111    def on_settings_toggle(self, toggleaction, ui_xml_file):
112        name = toggleaction.get_property("name")
113        merge_id = self.toolbar1_ui_loaded.get(name, None)
114        if toggleaction.get_active():
115            self.app.preferences["ui.toolbar_items"][name] = True
116            if merge_id is not None:
117                return
118            ui_dir = os.path.dirname(os.path.abspath(__file__))
119            ui_xml_path = os.path.join(ui_dir, ui_xml_file)
120            merge_id = self.app.ui_manager.add_ui_from_file(ui_xml_path)
121            self.toolbar1_ui_loaded[name] = merge_id
122        else:
123            self.app.preferences["ui.toolbar_items"][name] = False
124            if merge_id is None:
125                return
126            self.app.ui_manager.remove_ui(merge_id)
127            self.toolbar1_ui_loaded.pop(name)
128