Painting is done in tileddrawwidget.py.
"""
-MYPAINT_VERSION="0.9.1+git"
+MYPAINT_VERSION="1.0.0"
-import os, math, time
+import os, math, time, webbrowser
from gettext import gettext as _
import gtk, gobject
from gtk import gdk, keysyms
import pango
-import colorselectionwindow, historypopup, stategroup, colorpicker, windowing, layout
+import colorselectionwindow, historypopup, stategroup, colorpicker, windowing, layout, toolbar
import dialogs
from lib import helpers
import stock
return True
# Dispatch regular GTK events.
- for ag in drawwindow.action_group, doc.action_group:
- action = ag.get_action(action_name)
- if action is not None:
- action.activate()
- return True
+ action = drawwindow.app.find_action(action_name)
+ if action is not None:
+ action.activate()
+ return True
def button_release_cb_abstraction(win, event, doc):
#print event.device, event.button
lm = app.layout_manager
layout.MainWindow.__init__(self, lm)
+
+ # Park the focus on the main tdw rather than on the toolbar. Default
+ # activation doesn't really mean much for MyPaint's main window, so
+ # it's safe to do this and it looks better.
+ self.main_widget.set_can_default(True)
+ self.main_widget.set_can_focus(True)
+ self.main_widget.grab_focus()
+
self.main_widget.connect("button-press-event", self.button_press_cb)
self.main_widget.connect("button-release-event",self.button_release_cb)
self.main_widget.connect("scroll-event", self.scroll_cb)
('ColorMenu', None, _('Color')),
('ColorPickerPopup', gtk.STOCK_COLOR_PICKER, _('Pick Color'), 'r', None, self.popup_cb),
('ColorHistoryPopup', None, _('Color History'), 'x', None, self.popup_cb),
- ('ColorChangerPopup', None, _('Color Changer'), 'v', None, self.popup_cb),
+ ('ColorChangerCrossedBowlPopup', None, _('Color Changer (crossed bowl)'), 'v', None, self.popup_cb),
+ ('ColorChangerWashPopup', None, _('Color Changer (washed)'), 'c', None, self.popup_cb),
('ColorRingPopup', None, _('Color Ring'), None, None, self.popup_cb),
+ ('ColorDetailsDialog', None, _("Color Details"), None, None, self.color_details_dialog_cb),
('ContextMenu', None, _('Brushkeys')),
('ContextHelp', gtk.STOCK_HELP, _('Help!'), None, None, self.show_infodialog_cb),
('ScratchCopyBackground', None, _('Copy Background to Scratchpad'), None, None, self.scratchpad_copy_background_cb),
('BrushMenu', None, _('Brush')),
- ('ImportBrushPack', gtk.STOCK_OPEN, _('Import brush package...'), '', None, self.import_brush_pack_cb),
+ ('BrushChooserPopup', stock.TOOL_BRUSH, _("Change Brush..."), 'b', None, self.brush_chooser_popup_cb),
+ ('DownloadBrushPack', gtk.STOCK_OPEN, _('Download more brushes (in web browser)'), '', None, self.download_brush_pack_cb),
+ ('ImportBrushPack', gtk.STOCK_OPEN, _('Import brush package...'), '', None, self.import_brush_pack_cb),
('HelpMenu', None, _('Help')),
('Docu', gtk.STOCK_INFO, _('Where is the Documentation?'), None, None, self.show_infodialog_cb),
('ViewMenu', None, _('View')),
('MenuishBarMenu', None, _('Toolbars')),
('ShowPopupMenu', None, _('Popup Menu'), 'Menu', None, self.popupmenu_show_cb),
- ('Fullscreen', gtk.STOCK_FULLSCREEN, _('Fullscreen'), 'F11', None, self.fullscreen_cb),
+ ('Fullscreen', gtk.STOCK_FULLSCREEN, None, 'F11', None, self.fullscreen_cb),
('ViewHelp', gtk.STOCK_HELP, _('Help'), None, None, self.show_infodialog_cb),
]
ag = self.action_group = gtk.ActionGroup('WindowActions')
+ self.app.add_action_group(ag)
ag.add_actions(actions)
+ self.update_fullscreen_action()
# Toggle actions
toggle_actions = [
('BackgroundWindow', gtk.STOCK_PAGE_SETUP,
_('Background'), None, None, self.toggle_window_cb),
('BrushSelectionWindow', stock.TOOL_BRUSH,
- None, None, _("Toggle the Brush selector"),
+ None, None,
+ _("Edit and reorganise Brush Lists"),
self.toggle_window_cb),
('BrushSettingsWindow', gtk.STOCK_PROPERTIES,
- _('Brush Editor'), '<control>b', None,
+ _('Brush Settings Editor'), '<control>b',
+ _("Change Brush Settings in detail"),
self.toggle_window_cb),
('ColorSelectionWindow', stock.TOOL_COLOR_SELECTOR,
None, None, _("Toggle the Colour Triangle"),
# Keyboard handling
for action in self.action_group.list_actions():
self.app.kbm.takeover_action(action)
- self.app.ui_manager.insert_action_group(ag, -1)
def init_stategroups(self):
sg = stategroup.StateGroup()
p2s = sg.create_popup_state
- changer = p2s(colorselectionwindow.ColorChangerPopup(self.app))
+ changer_crossed_bowl = p2s(colorselectionwindow.ColorChangerCrossedBowlPopup(self.app))
+ changer_wash = p2s(colorselectionwindow.ColorChangerWashPopup(self.app))
ring = p2s(colorselectionwindow.ColorRingPopup(self.app))
hist = p2s(historypopup.HistoryPopup(self.app, self.app.doc.model))
pick = self.colorpick_state = p2s(colorpicker.ColorPicker(self.app, self.app.doc.model))
self.popup_states = {
- 'ColorChangerPopup': changer,
+ 'ColorChangerCrossedBowlPopup': changer_crossed_bowl,
+ 'ColorChangerWashPopup': changer_wash,
'ColorRingPopup': ring,
'ColorHistoryPopup': hist,
'ColorPickerPopup': pick,
}
- changer.next_state = ring
- ring.next_state = changer
- changer.autoleave_timeout = None
+
+ # not sure how useful this is; we can't cycle at the moment
+ changer_crossed_bowl.next_state = ring
+ ring.next_state = changer_wash
+ changer_wash.next_state = ring
+
+ changer_wash.autoleave_timeout = None
+ changer_crossed_bowl.autoleave_timeout = None
ring.autoleave_timeout = None
pick.max_key_hit_duration = 0.0
self.menubar = self.app.ui_manager.get_widget('/Menubar')
def init_toolbar(self):
- toolbarpath = os.path.join(self.app.datapath, 'gui/toolbar.xml')
- toolbarbar_xml = open(toolbarpath).read()
- self.app.ui_manager.add_ui_from_string(toolbarbar_xml)
- self.toolbar1 = self.app.ui_manager.get_widget('/toolbar1')
- self.toolbar1.set_style(gtk.TOOLBAR_ICONS)
- self.toolbar1.set_border_width(0)
- self.toolbar1.connect("style-set", self.on_toolbar1_style_set)
- self.toolbar = gtk.HBox()
- self.menu_button = FakeMenuButton(_("MyPaint"), self.popupmenu)
- self.menu_button.set_border_width(0)
- self.toolbar.pack_start(self.menu_button, False, False)
- self.toolbar.pack_start(self.toolbar1, True, True)
- self.menu_button.set_flags(gtk.CAN_DEFAULT)
- self.set_default(self.menu_button)
-
- def on_toolbar1_style_set(self, widget, oldstyle):
- style = widget.style.copy()
- self.menu_button.set_style(style)
- style = widget.style.copy()
- self.toolbar.set_style(style)
+ self.toolbar_manager = toolbar.ToolbarManager(self)
+ self.toolbar = self.toolbar_manager.toolbar1
def _clone_menu(self, xml, name, owner=None):
"""
state.activate(action)
+ def brush_chooser_popup_cb(self, action):
+ # It may be even nicer to do this as a real popup state with
+ # mouse-out to cancel. The Action is named accordingly. For now
+ # though a modal dialog will do as an implementation.
+ dialogs.change_current_brush_quick(self.app)
+
+ def color_details_dialog_cb(self, action):
+ dialogs.change_current_color_detailed(self.app)
+
+
# User-toggleable UI pieces: things like toolbars, status bars, menu bars.
# Saved between sessions.
toolbar_visible = self.toolbar.get_property("visible")
menubar_visible = self.menubar.get_property("visible")
if toolbar_visible and menubar_visible:
- self.menu_button.hide()
+ self.toolbar_manager.menu_button.hide()
else:
- self.menu_button.show_all()
+ self.toolbar_manager.menu_button.show_all()
def on_menuishbar_radio_change(self, radioaction, current):
self.set_show_subwindows(True)
del self._restore_subwindows_on_unfullscreen
self.update_menu_button()
+ self.update_fullscreen_action()
+
+ def update_fullscreen_action(self):
+ action = self.action_group.get_action("Fullscreen")
+ if self.is_fullscreen:
+ action.set_stock_id(gtk.STOCK_LEAVE_FULLSCREEN)
+ action.set_tooltip(_("Leave Fullscreen Mode"))
+ action.set_label(_("UnFullscreen"))
+ else:
+ action.set_stock_id(gtk.STOCK_FULLSCREEN)
+ action.set_tooltip(_("Enter Fullscreen Mode"))
+ action.set_label(_("Fullscreen"))
def popupmenu_show_cb(self, action):
self.show_popupmenu()
def show_popupmenu(self, event=None):
self.menubar.set_sensitive(False) # excessive feedback?
- self.menu_button.set_sensitive(False)
+ self.toolbar_manager.menu_button.set_sensitive(False)
button = 1
time = 0
if event is not None:
# the other. Makes it clear that the popups are the same thing as
# the full menu, maybe.
self.menubar.set_sensitive(True)
- self.menu_button.set_sensitive(True)
+ self.toolbar_manager.menu_button.set_sensitive(True)
self.popupmenu_last_active = self.popupmenu.get_active()
# BEGIN -- Scratchpad menu options
enabled = self.app.doc.model.frame_enabled
self.app.doc.model.set_frame_enabled(not enabled)
+ def download_brush_pack_cb(self, *junk):
+ url = 'http://wiki.mypaint.info/index.php?title=Brush_Packages/redirect_mypaint_1.0_gui'
+ print 'URL:', url
+ webbrowser.open(url)
+
def import_brush_pack_cb(self, *junk):
format_id, filename = dialogs.open_dialog(_("Import brush package..."), self,
[(_("MyPaint brush package (*.zip)"), "*.zip")])
u'David Grundberg (%s)' % _('programming'),
u"Krzysztof Pasek (%s)" % _('programming'),
u"Ben O'Steen (%s)" % _('programming'),
+ u"Ferry Jérémie (%s)" % _('programming'),
+ u"しげっち 'sigetch' (%s)" % _('programming'),
])
d.set_artists([
u"Artis Rozentāls (%s)" % _('brushes'),
self.app.message_dialog(text[action.get_name()])
-class FakeMenuButton(gtk.EventBox):
- """Launches the popup menu when clicked.
-
- One of these sits to the left of the real toolbar when the main menu bar is
- hidden. In addition to providing access to a popup menu associated with the
- main view, this is a little more compliant with Fitts's Law than a normal
- `gtk.MenuBar`: when the window is fullscreened with only the "toolbar"
- present the ``(0, 0)`` screen pixel hits this button. Support note: Compiz
- edge bindings sometimes get in the way of this, so turn those off if you
- want Fitts's compliance.
- """
-
- def __init__(self, text, menu):
- gtk.EventBox.__init__(self)
- self.menu = menu
- self.label = gtk.Label(text)
- self.label.set_padding(8, 0)
-
- # Text settings
- #self.label.set_angle(5)
- attrs = pango.AttrList()
- attrs.change(pango.AttrWeight(pango.WEIGHT_HEAVY, 0, -1))
- self.label.set_attributes(attrs)
-
- # Intercept mouse clicks and use them for activating the togglebutton
- # even if they're in its border, or (0, 0). Fitts would approve.
- invis = self.invis_window = gtk.EventBox()
- invis.set_visible_window(False)
- invis.set_above_child(True)
- invis.connect("button-press-event", self.on_button_press)
- invis.connect("enter-notify-event", self.on_enter)
- invis.connect("leave-notify-event", self.on_leave)
-
- # The underlying togglebutton can default and focus. Might as well make
- # the Return key do something useful rather than invoking the 1st
- # toolbar item.
- self.togglebutton = gtk.ToggleButton()
- self.togglebutton.add(self.label)
- self.togglebutton.set_relief(gtk.RELIEF_HALF)
- self.togglebutton.set_flags(gtk.CAN_FOCUS)
- self.togglebutton.set_flags(gtk.CAN_DEFAULT)
- self.togglebutton.connect("toggled", self.on_togglebutton_toggled)
-
- invis.add(self.togglebutton)
- self.add(invis)
- for sig in "selection-done", "deactivate", "cancel":
- menu.connect(sig, self.on_menu_dismiss)
-
-
- def on_enter(self, widget, event):
- # Not this set_state(). That one.
- #self.togglebutton.set_state(gtk.STATE_PRELIGHT)
- gtk.Widget.set_state(self.togglebutton, gtk.STATE_PRELIGHT)
-
-
- def on_leave(self, widget, event):
- #self.togglebutton.set_state(gtk.STATE_NORMAL)
- gtk.Widget.set_state(self.togglebutton, gtk.STATE_NORMAL)
-
-
- def on_button_press(self, widget, event):
- # Post the menu. Menu operation is much more convincing if we call
- # popup() with event details here rather than leaving it to the toggled
- # handler.
- pos_func = self._get_popup_menu_position
- self.menu.popup(None, None, pos_func, event.button, event.time)
- self.togglebutton.set_active(True)
-
-
- def on_togglebutton_toggled(self, togglebutton):
- # Post the menu from a keypress. Dismiss handler untoggles it.
- if togglebutton.get_active():
- if not self.menu.get_property("visible"):
- pos_func = self._get_popup_menu_position
- self.menu.popup(None, None, pos_func, 1, 0)
-
-
- def on_menu_dismiss(self, *a, **kw):
- # Reset the button state when the user's finished, and
- # park focus back on the menu button.
- self.set_state(gtk.STATE_NORMAL)
- self.togglebutton.set_active(False)
- self.togglebutton.grab_focus()
-
-
- def _get_popup_menu_position(self, menu, *junk):
- # Underneath the button, at the same x position.
- x, y = self.window.get_origin()
- y += self.allocation.height
- return x, y, True
-
-
- def set_style(self, style):
- # Propagate style changes to all children as well. Since this button is
- # stored on the toolbar, the main window makes it share a style with
- # it. Looks prettier.
- gtk.EventBox.set_style(self, style)
- style = style.copy()
- widget = self.togglebutton
- widget.set_style(style)
- style = style.copy()
- widget = widget.get_child()
- widget.set_style(style)