Merge branch 'master' of git://git.sugarlabs.org/sugar-toolkit/toolbars
Conflicts: src/sugar/graphics/window.py
This commit is contained in:
commit
0426c0c827
74
examples/radiopalette.py
Normal file
74
examples/radiopalette.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import gtk
|
||||||
|
|
||||||
|
from sugar.graphics.radiopalette import RadioPalette, RadioMenuButton, \
|
||||||
|
RadioToolsButton
|
||||||
|
from sugar.graphics.radiotoolbutton import RadioToolButton
|
||||||
|
from sugar.graphics.toolbutton import ToolButton
|
||||||
|
from sugar.graphics import style
|
||||||
|
|
||||||
|
window = gtk.Window()
|
||||||
|
|
||||||
|
box = gtk.VBox()
|
||||||
|
window.add(box)
|
||||||
|
|
||||||
|
toolbar = gtk.Toolbar()
|
||||||
|
box.pack_start(toolbar, False)
|
||||||
|
|
||||||
|
text_view = gtk.TextView()
|
||||||
|
box.pack_start(text_view)
|
||||||
|
|
||||||
|
def echo(button, label):
|
||||||
|
if not button.props.active:
|
||||||
|
return
|
||||||
|
text_view.props.buffer.props.text += "\n" + label
|
||||||
|
|
||||||
|
# RadioMenuButton
|
||||||
|
|
||||||
|
palette = RadioPalette()
|
||||||
|
|
||||||
|
group = RadioToolButton(
|
||||||
|
icon_name='document-open')
|
||||||
|
group.connect('clicked', lambda button: echo(button, 'document-open'))
|
||||||
|
palette.append(group, 'menu.document-open')
|
||||||
|
|
||||||
|
button = RadioToolButton(
|
||||||
|
icon_name='document-save',
|
||||||
|
group=group)
|
||||||
|
button.connect('clicked', lambda button: echo(button, 'document-save'))
|
||||||
|
palette.append(button, 'menu.document-save')
|
||||||
|
|
||||||
|
button = RadioToolButton(
|
||||||
|
icon_name='document-send',
|
||||||
|
group=group)
|
||||||
|
button.connect('clicked', lambda button: echo(button, 'document-send'))
|
||||||
|
palette.append(button, 'menu.document-send')
|
||||||
|
|
||||||
|
button = RadioMenuButton(palette=palette)
|
||||||
|
toolbar.insert(button, -1)
|
||||||
|
|
||||||
|
# RadioToolsButton
|
||||||
|
|
||||||
|
palette = RadioPalette()
|
||||||
|
|
||||||
|
group = RadioToolButton(
|
||||||
|
icon_name='document-open')
|
||||||
|
group.connect('clicked', lambda button: echo(button, 'document-open'))
|
||||||
|
palette.append(group, 'menu.document-open')
|
||||||
|
|
||||||
|
button = RadioToolButton(
|
||||||
|
icon_name='document-save',
|
||||||
|
group=group)
|
||||||
|
button.connect('clicked', lambda button: echo(button, 'document-save'))
|
||||||
|
palette.append(button, 'menu.document-save')
|
||||||
|
|
||||||
|
button = RadioToolButton(
|
||||||
|
icon_name='document-send',
|
||||||
|
group=group)
|
||||||
|
button.connect('clicked', lambda button: echo(button, 'document-send'))
|
||||||
|
palette.append(button, 'menu.document-send')
|
||||||
|
|
||||||
|
button = RadioToolsButton(palette=palette)
|
||||||
|
toolbar.insert(button, -1)
|
||||||
|
|
||||||
|
window.show_all()
|
||||||
|
gtk.main()
|
1
examples/sugar
Symbolic link
1
examples/sugar
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../src/sugar/
|
50
examples/toolbar.py
Normal file
50
examples/toolbar.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import gtk
|
||||||
|
|
||||||
|
from sugar.graphics.toolbutton import ToolButton
|
||||||
|
from sugar.graphics.toolbarbox import ToolbarBox, ToolbarButton
|
||||||
|
from sugar.graphics import style
|
||||||
|
|
||||||
|
window = gtk.Window()
|
||||||
|
|
||||||
|
box = gtk.VBox()
|
||||||
|
window.add(box)
|
||||||
|
|
||||||
|
toolbar = ToolbarBox()
|
||||||
|
box.pack_start(toolbar, False)
|
||||||
|
|
||||||
|
tollbarbutton_1 = ToolbarButton(
|
||||||
|
page=gtk.Button('sub-widget #1'),
|
||||||
|
icon_name='computer-xo')
|
||||||
|
toolbar.toolbar.insert(tollbarbutton_1, -1)
|
||||||
|
|
||||||
|
tollbarbutton_2 = ToolbarButton(
|
||||||
|
page=gtk.Button('sub-widget #2'),
|
||||||
|
icon_name='button_cancel',
|
||||||
|
tooltip='with custom palette instead of sub-widget')
|
||||||
|
toolbar.toolbar.insert(tollbarbutton_2, -1)
|
||||||
|
|
||||||
|
toolbar.toolbar.insert(gtk.SeparatorToolItem(), -1)
|
||||||
|
|
||||||
|
def del_cb(widget):
|
||||||
|
toolbar.toolbar.remove(tollbarbutton_3)
|
||||||
|
del_b = gtk.Button('delete sub-widget #3')
|
||||||
|
del_b.connect('clicked', del_cb)
|
||||||
|
tollbarbutton_3 = ToolbarButton(
|
||||||
|
page=del_b,
|
||||||
|
icon_name='activity-journal')
|
||||||
|
toolbar.toolbar.insert(tollbarbutton_3, -1)
|
||||||
|
|
||||||
|
subbar = gtk.Toolbar()
|
||||||
|
subbutton = ToolButton(
|
||||||
|
icon_name='document-send',
|
||||||
|
tooltip='document-send')
|
||||||
|
subbar.insert(subbutton, -1)
|
||||||
|
subbar.show_all()
|
||||||
|
|
||||||
|
tollbarbutton_4 = ToolbarButton(
|
||||||
|
page=subbar,
|
||||||
|
icon_name='document-save')
|
||||||
|
toolbar.toolbar.insert(tollbarbutton_4, -1)
|
||||||
|
|
||||||
|
window.show_all()
|
||||||
|
gtk.main()
|
2
m4/.gitignore
vendored
2
m4/.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
intltool.m4
|
intltool.m4
|
||||||
|
libtool.m4
|
||||||
|
lt*.m4
|
||||||
|
14
src/sugar/__init__.py
Normal file
14
src/sugar/__init__.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the
|
||||||
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
@ -1,10 +1,11 @@
|
|||||||
sugardir = $(pythondir)/sugar/activity
|
sugardir = $(pythondir)/sugar/activity
|
||||||
sugar_PYTHON = \
|
sugar_PYTHON = \
|
||||||
__init__.py \
|
__init__.py \
|
||||||
activity.py \
|
activity.py \
|
||||||
activityfactory.py \
|
activityfactory.py \
|
||||||
activityhandle.py \
|
activityhandle.py \
|
||||||
activityservice.py \
|
activityservice.py \
|
||||||
bundlebuilder.py \
|
bundlebuilder.py \
|
||||||
main.py \
|
main.py \
|
||||||
namingalert.py
|
namingalert.py \
|
||||||
|
widgets.py
|
||||||
|
@ -67,16 +67,15 @@ from sugar.activity.activityservice import ActivityService
|
|||||||
from sugar.activity.namingalert import NamingAlert
|
from sugar.activity.namingalert import NamingAlert
|
||||||
from sugar.graphics import style
|
from sugar.graphics import style
|
||||||
from sugar.graphics.window import Window
|
from sugar.graphics.window import Window
|
||||||
from sugar.graphics.toolbox import Toolbox
|
|
||||||
from sugar.graphics.toolbutton import ToolButton
|
|
||||||
from sugar.graphics.toolcombobox import ToolComboBox
|
|
||||||
from sugar.graphics.alert import Alert
|
from sugar.graphics.alert import Alert
|
||||||
from sugar.graphics.icon import Icon
|
from sugar.graphics.icon import Icon
|
||||||
from sugar.graphics.xocolor import XoColor
|
|
||||||
from sugar.datastore import datastore
|
from sugar.datastore import datastore
|
||||||
from sugar.session import XSMPClient
|
from sugar.session import XSMPClient
|
||||||
from sugar import wm
|
from sugar import wm
|
||||||
|
|
||||||
|
# support deprecated imports
|
||||||
|
from sugar.activity.widgets import ActivityToolbar, EditToolbar, ActivityToolbox
|
||||||
|
|
||||||
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
|
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
|
||||||
|
|
||||||
SCOPE_PRIVATE = "private"
|
SCOPE_PRIVATE = "private"
|
||||||
@ -87,226 +86,6 @@ J_DBUS_SERVICE = 'org.laptop.Journal'
|
|||||||
J_DBUS_PATH = '/org/laptop/Journal'
|
J_DBUS_PATH = '/org/laptop/Journal'
|
||||||
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
J_DBUS_INTERFACE = 'org.laptop.Journal'
|
||||||
|
|
||||||
class ActivityToolbar(gtk.Toolbar):
|
|
||||||
"""The Activity toolbar with the Journal entry title, sharing,
|
|
||||||
Keep and Stop buttons
|
|
||||||
|
|
||||||
All activities should have this toolbar. It is easiest to add it to your
|
|
||||||
Activity by using the ActivityToolbox.
|
|
||||||
"""
|
|
||||||
def __init__(self, activity):
|
|
||||||
gtk.Toolbar.__init__(self)
|
|
||||||
|
|
||||||
self._activity = activity
|
|
||||||
self._updating_share = False
|
|
||||||
|
|
||||||
activity.connect('shared', self.__activity_shared_cb)
|
|
||||||
activity.connect('joined', self.__activity_shared_cb)
|
|
||||||
activity.connect('notify::max_participants',
|
|
||||||
self.__max_participants_changed_cb)
|
|
||||||
|
|
||||||
if activity.metadata:
|
|
||||||
self.title = gtk.Entry()
|
|
||||||
self.title.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
|
|
||||||
self.title.set_text(activity.metadata['title'])
|
|
||||||
self.title.connect('changed', self.__title_changed_cb)
|
|
||||||
self._add_widget(self.title)
|
|
||||||
|
|
||||||
activity.metadata.connect('updated', self.__jobject_updated_cb)
|
|
||||||
|
|
||||||
separator = gtk.SeparatorToolItem()
|
|
||||||
separator.props.draw = False
|
|
||||||
separator.set_expand(True)
|
|
||||||
self.insert(separator, -1)
|
|
||||||
separator.show()
|
|
||||||
|
|
||||||
self.share = ToolComboBox(label_text=_('Share with:'))
|
|
||||||
self.share.combo.connect('changed', self.__share_changed_cb)
|
|
||||||
self.share.combo.append_item(SCOPE_PRIVATE, _('Private'), 'zoom-home')
|
|
||||||
self.share.combo.append_item(SCOPE_NEIGHBORHOOD, _('My Neighborhood'),
|
|
||||||
'zoom-neighborhood')
|
|
||||||
self.insert(self.share, -1)
|
|
||||||
self.share.show()
|
|
||||||
|
|
||||||
self._update_share()
|
|
||||||
|
|
||||||
self.keep = ToolButton(tooltip=_('Keep'))
|
|
||||||
client = gconf.client_get_default()
|
|
||||||
color = XoColor(client.get_string('/desktop/sugar/user/color'))
|
|
||||||
keep_icon = Icon(icon_name='document-save', xo_color=color)
|
|
||||||
self.keep.set_icon_widget(keep_icon)
|
|
||||||
keep_icon.show()
|
|
||||||
self.keep.props.accelerator = '<Ctrl>S'
|
|
||||||
self.keep.connect('clicked', self.__keep_clicked_cb)
|
|
||||||
self.insert(self.keep, -1)
|
|
||||||
self.keep.show()
|
|
||||||
|
|
||||||
self.stop = ToolButton('activity-stop', tooltip=_('Stop'))
|
|
||||||
self.stop.props.accelerator = '<Ctrl>Q'
|
|
||||||
self.stop.connect('clicked', self.__stop_clicked_cb)
|
|
||||||
self.insert(self.stop, -1)
|
|
||||||
self.stop.show()
|
|
||||||
|
|
||||||
self._update_title_sid = None
|
|
||||||
|
|
||||||
def _update_share(self):
|
|
||||||
self._updating_share = True
|
|
||||||
|
|
||||||
if self._activity.props.max_participants == 1:
|
|
||||||
self.share.hide()
|
|
||||||
|
|
||||||
if self._activity.get_shared():
|
|
||||||
self.share.set_sensitive(False)
|
|
||||||
self.share.combo.set_active(1)
|
|
||||||
else:
|
|
||||||
self.share.set_sensitive(True)
|
|
||||||
self.share.combo.set_active(0)
|
|
||||||
|
|
||||||
self._updating_share = False
|
|
||||||
|
|
||||||
def __share_changed_cb(self, combo):
|
|
||||||
if self._updating_share:
|
|
||||||
return
|
|
||||||
|
|
||||||
model = self.share.combo.get_model()
|
|
||||||
it = self.share.combo.get_active_iter()
|
|
||||||
(scope, ) = model.get(it, 0)
|
|
||||||
if scope == SCOPE_NEIGHBORHOOD:
|
|
||||||
self._activity.share()
|
|
||||||
|
|
||||||
def __keep_clicked_cb(self, button):
|
|
||||||
self._activity.copy()
|
|
||||||
|
|
||||||
def __stop_clicked_cb(self, button):
|
|
||||||
self._activity.close()
|
|
||||||
|
|
||||||
def __jobject_updated_cb(self, jobject):
|
|
||||||
self.title.set_text(jobject['title'])
|
|
||||||
|
|
||||||
def __title_changed_cb(self, entry):
|
|
||||||
if not self._update_title_sid:
|
|
||||||
self._update_title_sid = gobject.timeout_add_seconds(
|
|
||||||
1, self.__update_title_cb)
|
|
||||||
|
|
||||||
def __update_title_cb(self):
|
|
||||||
title = self.title.get_text()
|
|
||||||
|
|
||||||
self._activity.metadata['title'] = title
|
|
||||||
self._activity.metadata['title_set_by_user'] = '1'
|
|
||||||
self._activity.save()
|
|
||||||
|
|
||||||
shared_activity = self._activity.get_shared_activity()
|
|
||||||
if shared_activity:
|
|
||||||
shared_activity.props.name = title
|
|
||||||
|
|
||||||
self._update_title_sid = None
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _add_widget(self, widget, expand=False):
|
|
||||||
tool_item = gtk.ToolItem()
|
|
||||||
tool_item.set_expand(expand)
|
|
||||||
|
|
||||||
tool_item.add(widget)
|
|
||||||
widget.show()
|
|
||||||
|
|
||||||
self.insert(tool_item, -1)
|
|
||||||
tool_item.show()
|
|
||||||
|
|
||||||
def __activity_shared_cb(self, activity):
|
|
||||||
self._update_share()
|
|
||||||
|
|
||||||
def __max_participants_changed_cb(self, activity, pspec):
|
|
||||||
self._update_share()
|
|
||||||
|
|
||||||
class EditToolbar(gtk.Toolbar):
|
|
||||||
"""Provides the standard edit toolbar for Activities.
|
|
||||||
|
|
||||||
Members:
|
|
||||||
undo -- the undo button
|
|
||||||
redo -- the redo button
|
|
||||||
copy -- the copy button
|
|
||||||
paste -- the paste button
|
|
||||||
separator -- A separator between undo/redo and copy/paste
|
|
||||||
|
|
||||||
This class only provides the 'edit' buttons in a standard layout,
|
|
||||||
your activity will need to either hide buttons which make no sense for your
|
|
||||||
Activity, or you need to connect the button events to your own callbacks:
|
|
||||||
|
|
||||||
## Example from Read.activity:
|
|
||||||
# Create the edit toolbar:
|
|
||||||
self._edit_toolbar = EditToolbar(self._view)
|
|
||||||
# Hide undo and redo, they're not needed
|
|
||||||
self._edit_toolbar.undo.props.visible = False
|
|
||||||
self._edit_toolbar.redo.props.visible = False
|
|
||||||
# Hide the separator too:
|
|
||||||
self._edit_toolbar.separator.props.visible = False
|
|
||||||
|
|
||||||
# As long as nothing is selected, copy needs to be insensitive:
|
|
||||||
self._edit_toolbar.copy.set_sensitive(False)
|
|
||||||
# When the user clicks the button, call _edit_toolbar_copy_cb()
|
|
||||||
self._edit_toolbar.copy.connect('clicked', self._edit_toolbar_copy_cb)
|
|
||||||
|
|
||||||
# Add the edit toolbar:
|
|
||||||
toolbox.add_toolbar(_('Edit'), self._edit_toolbar)
|
|
||||||
# And make it visible:
|
|
||||||
self._edit_toolbar.show()
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
gtk.Toolbar.__init__(self)
|
|
||||||
|
|
||||||
self.undo = ToolButton('edit-undo')
|
|
||||||
self.undo.set_tooltip(_('Undo'))
|
|
||||||
self.insert(self.undo, -1)
|
|
||||||
self.undo.show()
|
|
||||||
|
|
||||||
self.redo = ToolButton('edit-redo')
|
|
||||||
self.redo.set_tooltip(_('Redo'))
|
|
||||||
self.insert(self.redo, -1)
|
|
||||||
self.redo.show()
|
|
||||||
|
|
||||||
self.separator = gtk.SeparatorToolItem()
|
|
||||||
self.separator.set_draw(True)
|
|
||||||
self.insert(self.separator, -1)
|
|
||||||
self.separator.show()
|
|
||||||
|
|
||||||
self.copy = ToolButton('edit-copy')
|
|
||||||
self.copy.set_tooltip(_('Copy'))
|
|
||||||
self.insert(self.copy, -1)
|
|
||||||
self.copy.show()
|
|
||||||
|
|
||||||
self.paste = ToolButton('edit-paste')
|
|
||||||
self.paste.set_tooltip(_('Paste'))
|
|
||||||
self.insert(self.paste, -1)
|
|
||||||
self.paste.show()
|
|
||||||
|
|
||||||
class ActivityToolbox(Toolbox):
|
|
||||||
"""Creates the Toolbox for the Activity
|
|
||||||
|
|
||||||
By default, the toolbox contains only the ActivityToolbar. After creating
|
|
||||||
the toolbox, you can add your activity specific toolbars, for example the
|
|
||||||
EditToolbar.
|
|
||||||
|
|
||||||
To add the ActivityToolbox to your Activity in MyActivity.__init__() do:
|
|
||||||
|
|
||||||
# Create the Toolbar with the ActivityToolbar:
|
|
||||||
toolbox = activity.ActivityToolbox(self)
|
|
||||||
... your code, inserting all other toolbars you need, like EditToolbar
|
|
||||||
|
|
||||||
# Add the toolbox to the activity frame:
|
|
||||||
self.set_toolbox(toolbox)
|
|
||||||
# And make it visible:
|
|
||||||
toolbox.show()
|
|
||||||
"""
|
|
||||||
def __init__(self, activity):
|
|
||||||
Toolbox.__init__(self)
|
|
||||||
|
|
||||||
self._activity_toolbar = ActivityToolbar(activity)
|
|
||||||
self.add_toolbar(_('Activity'), self._activity_toolbar)
|
|
||||||
self._activity_toolbar.show()
|
|
||||||
|
|
||||||
def get_activity_toolbar(self):
|
|
||||||
return self._activity_toolbar
|
|
||||||
|
|
||||||
class _ActivitySession(gobject.GObject):
|
class _ActivitySession(gobject.GObject):
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'quit-requested': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
|
'quit-requested': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
|
||||||
|
297
src/sugar/activity/widgets.py
Normal file
297
src/sugar/activity/widgets.py
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
# Copyright (C) 2009, Aleksey Lim
|
||||||
|
#
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the
|
||||||
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
import gettext
|
||||||
|
import gconf
|
||||||
|
|
||||||
|
from sugar.graphics.toolbutton import ToolButton
|
||||||
|
from sugar.graphics.toolbarbox import ToolbarButton
|
||||||
|
from sugar.graphics.radiopalette import RadioPalette, RadioMenuButton
|
||||||
|
from sugar.graphics.radiotoolbutton import RadioToolButton
|
||||||
|
from sugar.graphics.toolbox import Toolbox
|
||||||
|
from sugar.graphics.xocolor import XoColor
|
||||||
|
from sugar.graphics.icon import Icon
|
||||||
|
from sugar.bundle.activitybundle import ActivityBundle
|
||||||
|
|
||||||
|
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
|
||||||
|
|
||||||
|
class ActivityToolbarButton(ToolbarButton):
|
||||||
|
def __init__(self, activity, **kwargs):
|
||||||
|
toolbar = ActivityToolbar(activity)
|
||||||
|
toolbar.stop.hide()
|
||||||
|
|
||||||
|
ToolbarButton.__init__(self, page=toolbar, **kwargs)
|
||||||
|
|
||||||
|
from sugar.activity.activity import get_bundle_path
|
||||||
|
bundle = ActivityBundle(get_bundle_path())
|
||||||
|
|
||||||
|
client = gconf.client_get_default()
|
||||||
|
color = XoColor(client.get_string('/desktop/sugar/user/color'))
|
||||||
|
icon = Icon(file=bundle.get_icon(), xo_color=color)
|
||||||
|
icon.show()
|
||||||
|
self.set_icon_widget(icon)
|
||||||
|
|
||||||
|
class StopButton(ToolButton):
|
||||||
|
def __init__(self, activity, **kwargs):
|
||||||
|
ToolButton.__init__(self, 'activity-stop', **kwargs)
|
||||||
|
self.props.tooltip = _('Stop')
|
||||||
|
self.props.accelerator = '<Ctrl>Q'
|
||||||
|
self.connect('clicked', self.__stop_button_clicked_cb, activity)
|
||||||
|
|
||||||
|
def __stop_button_clicked_cb(self, button, activity):
|
||||||
|
activity.close()
|
||||||
|
|
||||||
|
class UndoButton(ToolButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
ToolButton.__init__(self, 'edit-undo', **kwargs)
|
||||||
|
self.props.tooltip = _('Undo')
|
||||||
|
self.props.accelerator = '<Ctrl>Q'
|
||||||
|
|
||||||
|
class RedoButton(ToolButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
ToolButton.__init__(self, 'edit-redo', **kwargs)
|
||||||
|
self.props.tooltip = _('Redo')
|
||||||
|
|
||||||
|
class CopyButton(ToolButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
ToolButton.__init__(self, 'edit-copy', **kwargs)
|
||||||
|
self.props.tooltip = _('Copy')
|
||||||
|
|
||||||
|
class PasteButton(ToolButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
ToolButton.__init__(self, 'edit-paste', **kwargs)
|
||||||
|
self.props.tooltip = _('Paste')
|
||||||
|
|
||||||
|
class ShareButton(RadioMenuButton):
|
||||||
|
def __init__(self, activity, **kwargs):
|
||||||
|
palette = RadioPalette()
|
||||||
|
|
||||||
|
self.private = RadioToolButton(
|
||||||
|
icon_name='zoom-home')
|
||||||
|
palette.append(self.private, _('Private'))
|
||||||
|
|
||||||
|
self.neighborhood = RadioToolButton(
|
||||||
|
icon_name='zoom-neighborhood',
|
||||||
|
group=self.private)
|
||||||
|
self._neighborhood_handle = self.neighborhood.connect(
|
||||||
|
'clicked', self.__neighborhood_clicked_cb, activity)
|
||||||
|
palette.append(self.neighborhood, _('My Neighborhood'))
|
||||||
|
|
||||||
|
activity.connect('shared', self.__update_share_cb)
|
||||||
|
activity.connect('joined', self.__update_share_cb)
|
||||||
|
|
||||||
|
RadioMenuButton.__init__(self, **kwargs)
|
||||||
|
self.props.palette = palette
|
||||||
|
|
||||||
|
def __neighborhood_clicked_cb(self, button, activity):
|
||||||
|
activity.share()
|
||||||
|
|
||||||
|
def __update_share_cb(self, activity):
|
||||||
|
self.neighborhood.handler_block(self._neighborhood_handle)
|
||||||
|
try:
|
||||||
|
if activity.get_shared():
|
||||||
|
self.private.props.sensitive = False
|
||||||
|
self.neighborhood.props.sensitive = False
|
||||||
|
self.neighborhood.props.active = True
|
||||||
|
else:
|
||||||
|
self.private.props.sensitive = True
|
||||||
|
self.neighborhood.props.sensitive = True
|
||||||
|
self.private.props.active = True
|
||||||
|
finally:
|
||||||
|
self.neighborhood.handler_unblock(self._neighborhood_handle)
|
||||||
|
|
||||||
|
class KeepButton(ToolButton):
|
||||||
|
def __init__(self, activity, **kwargs):
|
||||||
|
ToolButton.__init__(self, **kwargs)
|
||||||
|
self.props.tooltip = _('Keep')
|
||||||
|
self.props.accelerator = '<Ctrl>S'
|
||||||
|
|
||||||
|
client = gconf.client_get_default()
|
||||||
|
color = XoColor(client.get_string('/desktop/sugar/user/color'))
|
||||||
|
keep_icon = Icon(icon_name='document-save', xo_color=color)
|
||||||
|
keep_icon.show()
|
||||||
|
|
||||||
|
self.set_icon_widget(keep_icon)
|
||||||
|
self.connect('clicked', self.__keep_button_clicked_cb, activity)
|
||||||
|
|
||||||
|
def __keep_button_clicked_cb(self, button, activity):
|
||||||
|
activity.copy()
|
||||||
|
|
||||||
|
class TitleEntry(gtk.ToolItem):
|
||||||
|
def __init__(self, activity, **kwargs):
|
||||||
|
gtk.ToolItem.__init__(self)
|
||||||
|
self.set_expand(False)
|
||||||
|
self._update_title_sid = None
|
||||||
|
|
||||||
|
self.entry = gtk.Entry(**kwargs)
|
||||||
|
self.entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1)
|
||||||
|
self.entry.set_text(activity.metadata['title'])
|
||||||
|
self.entry.connect('changed', self.__title_changed_cb, activity)
|
||||||
|
self.entry.show()
|
||||||
|
self.add(self.entry)
|
||||||
|
|
||||||
|
activity.metadata.connect('updated', self.__jobject_updated_cb)
|
||||||
|
|
||||||
|
def modify_bg(self, state, color):
|
||||||
|
gtk.ToolItem.modify_bg(self, state, color)
|
||||||
|
if state == gtk.STATE_NORMAL:
|
||||||
|
self.entry.modify_bg(gtk.STATE_INSENSITIVE, color)
|
||||||
|
|
||||||
|
def __jobject_updated_cb(self, jobject):
|
||||||
|
self.entry.set_text(jobject['title'])
|
||||||
|
|
||||||
|
def __title_changed_cb(self, entry, activity):
|
||||||
|
if not self._update_title_sid:
|
||||||
|
self._update_title_sid = gobject.timeout_add_seconds(
|
||||||
|
1, self.__update_title_cb, activity)
|
||||||
|
|
||||||
|
def __update_title_cb(self, activity):
|
||||||
|
title = self.entry.get_text()
|
||||||
|
|
||||||
|
activity.metadata['title'] = title
|
||||||
|
activity.metadata['title_set_by_user'] = '1'
|
||||||
|
activity.save()
|
||||||
|
|
||||||
|
shared_activity = activity.get_shared_activity()
|
||||||
|
if shared_activity is None:
|
||||||
|
shared_activity.props.name = title
|
||||||
|
|
||||||
|
self._update_title_sid = None
|
||||||
|
return False
|
||||||
|
|
||||||
|
class ActivityToolbar(gtk.Toolbar):
|
||||||
|
"""The Activity toolbar with the Journal entry title, sharing,
|
||||||
|
Keep and Stop buttons
|
||||||
|
|
||||||
|
All activities should have this toolbar. It is easiest to add it to your
|
||||||
|
Activity by using the ActivityToolbox.
|
||||||
|
"""
|
||||||
|
def __init__(self, activity):
|
||||||
|
gtk.Toolbar.__init__(self)
|
||||||
|
|
||||||
|
self._activity = activity
|
||||||
|
|
||||||
|
if activity.metadata:
|
||||||
|
title_button = TitleEntry(activity)
|
||||||
|
title_button.show()
|
||||||
|
self.insert(title_button, -1)
|
||||||
|
self.title = title_button.entry
|
||||||
|
|
||||||
|
separator = gtk.SeparatorToolItem()
|
||||||
|
separator.props.draw = False
|
||||||
|
separator.set_expand(True)
|
||||||
|
self.insert(separator, -1)
|
||||||
|
separator.show()
|
||||||
|
|
||||||
|
self.share = ShareButton(activity)
|
||||||
|
self.share.show()
|
||||||
|
self.insert(self.share, -1)
|
||||||
|
|
||||||
|
self.keep = KeepButton(activity)
|
||||||
|
self.insert(self.keep, -1)
|
||||||
|
self.keep.show()
|
||||||
|
|
||||||
|
self.stop = StopButton(activity)
|
||||||
|
self.insert(self.stop, -1)
|
||||||
|
self.stop.show()
|
||||||
|
|
||||||
|
class EditToolbar(gtk.Toolbar):
|
||||||
|
"""Provides the standard edit toolbar for Activities.
|
||||||
|
|
||||||
|
Members:
|
||||||
|
undo -- the undo button
|
||||||
|
redo -- the redo button
|
||||||
|
copy -- the copy button
|
||||||
|
paste -- the paste button
|
||||||
|
separator -- A separator between undo/redo and copy/paste
|
||||||
|
|
||||||
|
This class only provides the 'edit' buttons in a standard layout,
|
||||||
|
your activity will need to either hide buttons which make no sense for your
|
||||||
|
Activity, or you need to connect the button events to your own callbacks:
|
||||||
|
|
||||||
|
## Example from Read.activity:
|
||||||
|
# Create the edit toolbar:
|
||||||
|
self._edit_toolbar = EditToolbar(self._view)
|
||||||
|
# Hide undo and redo, they're not needed
|
||||||
|
self._edit_toolbar.undo.props.visible = False
|
||||||
|
self._edit_toolbar.redo.props.visible = False
|
||||||
|
# Hide the separator too:
|
||||||
|
self._edit_toolbar.separator.props.visible = False
|
||||||
|
|
||||||
|
# As long as nothing is selected, copy needs to be insensitive:
|
||||||
|
self._edit_toolbar.copy.set_sensitive(False)
|
||||||
|
# When the user clicks the button, call _edit_toolbar_copy_cb()
|
||||||
|
self._edit_toolbar.copy.connect('clicked', self._edit_toolbar_copy_cb)
|
||||||
|
|
||||||
|
# Add the edit toolbar:
|
||||||
|
toolbox.add_toolbar(_('Edit'), self._edit_toolbar)
|
||||||
|
# And make it visible:
|
||||||
|
self._edit_toolbar.show()
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
gtk.Toolbar.__init__(self)
|
||||||
|
|
||||||
|
self.undo = UndoButton()
|
||||||
|
self.insert(self.undo, -1)
|
||||||
|
self.undo.show()
|
||||||
|
|
||||||
|
self.redo = RedoButton()
|
||||||
|
self.insert(self.redo, -1)
|
||||||
|
self.redo.show()
|
||||||
|
|
||||||
|
self.separator = gtk.SeparatorToolItem()
|
||||||
|
self.separator.set_draw(True)
|
||||||
|
self.insert(self.separator, -1)
|
||||||
|
self.separator.show()
|
||||||
|
|
||||||
|
self.copy = CopyButton()
|
||||||
|
self.insert(self.copy, -1)
|
||||||
|
self.copy.show()
|
||||||
|
|
||||||
|
self.paste = PasteButton()
|
||||||
|
self.insert(self.paste, -1)
|
||||||
|
self.paste.show()
|
||||||
|
|
||||||
|
class ActivityToolbox(Toolbox):
|
||||||
|
"""Creates the Toolbox for the Activity
|
||||||
|
|
||||||
|
By default, the toolbox contains only the ActivityToolbar. After creating
|
||||||
|
the toolbox, you can add your activity specific toolbars, for example the
|
||||||
|
EditToolbar.
|
||||||
|
|
||||||
|
To add the ActivityToolbox to your Activity in MyActivity.__init__() do:
|
||||||
|
|
||||||
|
# Create the Toolbar with the ActivityToolbar:
|
||||||
|
toolbox = activity.ActivityToolbox(self)
|
||||||
|
... your code, inserting all other toolbars you need, like EditToolbar
|
||||||
|
|
||||||
|
# Add the toolbox to the activity frame:
|
||||||
|
self.set_toolbox(toolbox)
|
||||||
|
# And make it visible:
|
||||||
|
toolbox.show()
|
||||||
|
"""
|
||||||
|
def __init__(self, activity):
|
||||||
|
Toolbox.__init__(self)
|
||||||
|
|
||||||
|
self._activity_toolbar = ActivityToolbar(activity)
|
||||||
|
self.add_toolbar(_('Activity'), self._activity_toolbar)
|
||||||
|
self._activity_toolbar.show()
|
||||||
|
|
||||||
|
def get_activity_toolbar(self):
|
||||||
|
return self._activity_toolbar
|
@ -1,27 +1,29 @@
|
|||||||
sugardir = $(pythondir)/sugar/graphics
|
sugardir = $(pythondir)/sugar/graphics
|
||||||
sugar_PYTHON = \
|
sugar_PYTHON = \
|
||||||
__init__.py \
|
alert.py \
|
||||||
alert.py \
|
animator.py \
|
||||||
animator.py \
|
canvastextview.py \
|
||||||
canvastextview.py \
|
colorbutton.py \
|
||||||
combobox.py \
|
combobox.py \
|
||||||
colorbutton.py \
|
entry.py \
|
||||||
entry.py \
|
iconentry.py \
|
||||||
icon.py \
|
icon.py \
|
||||||
iconentry.py \
|
__init__.py \
|
||||||
menuitem.py \
|
menuitem.py \
|
||||||
notebook.py \
|
notebook.py \
|
||||||
objectchooser.py \
|
objectchooser.py \
|
||||||
radiotoolbutton.py \
|
palettegroup.py \
|
||||||
palette.py \
|
palette.py \
|
||||||
palettegroup.py \
|
panel.py \
|
||||||
panel.py \
|
radiopalette.py \
|
||||||
roundbox.py \
|
radiotoolbutton.py \
|
||||||
style.py \
|
roundbox.py \
|
||||||
toggletoolbutton.py \
|
style.py \
|
||||||
toolbox.py \
|
toggletoolbutton.py \
|
||||||
toolbutton.py \
|
toolbarbox.py \
|
||||||
toolcombobox.py \
|
toolbox.py \
|
||||||
tray.py \
|
toolbutton.py \
|
||||||
window.py \
|
toolcombobox.py \
|
||||||
|
tray.py \
|
||||||
|
window.py \
|
||||||
xocolor.py
|
xocolor.py
|
||||||
|
@ -127,11 +127,11 @@ class MouseSpeedDetector(gobject.GObject):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class Palette(gtk.Window):
|
class PaletteWindow(gtk.Window):
|
||||||
PRIMARY = 0
|
PRIMARY = 0
|
||||||
SECONDARY = 1
|
SECONDARY = 1
|
||||||
|
|
||||||
__gtype_name__ = 'SugarPalette'
|
__gtype_name__ = 'SugarPaletteWindow'
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'popup' : (gobject.SIGNAL_RUN_FIRST,
|
'popup' : (gobject.SIGNAL_RUN_FIRST,
|
||||||
@ -142,18 +142,291 @@ class Palette(gtk.Window):
|
|||||||
gobject.TYPE_NONE, ([]))
|
gobject.TYPE_NONE, ([]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self._group_id = None
|
||||||
|
self._invoker = None
|
||||||
|
self._invoker_hids = []
|
||||||
|
self._cursor_x = 0
|
||||||
|
self._cursor_y = 0
|
||||||
|
self._alignment = None
|
||||||
|
self._up = False
|
||||||
|
self._old_alloc = None
|
||||||
|
self._palette_state = self.PRIMARY
|
||||||
|
|
||||||
|
self._popup_anim = animator.Animator(.5, 10)
|
||||||
|
self._popup_anim.add(_PopupAnimation(self))
|
||||||
|
|
||||||
|
self._secondary_anim = animator.Animator(2.0, 10)
|
||||||
|
self._secondary_anim.add(_SecondaryAnimation(self))
|
||||||
|
|
||||||
|
self._popdown_anim = animator.Animator(0.6, 10)
|
||||||
|
self._popdown_anim.add(_PopdownAnimation(self))
|
||||||
|
|
||||||
|
gobject.GObject.__init__(self, **kwargs)
|
||||||
|
|
||||||
|
self.set_decorated(False)
|
||||||
|
self.set_resizable(False)
|
||||||
|
# Just assume xthickness and ythickness are the same
|
||||||
|
self.set_border_width(self.get_style().xthickness)
|
||||||
|
|
||||||
|
accel_group = gtk.AccelGroup()
|
||||||
|
self.set_data('sugar-accel-group', accel_group)
|
||||||
|
self.add_accel_group(accel_group)
|
||||||
|
|
||||||
|
self.set_group_id("default")
|
||||||
|
|
||||||
|
self.connect('show', self.__show_cb)
|
||||||
|
self.connect('hide', self.__hide_cb)
|
||||||
|
self.connect('realize', self.__realize_cb)
|
||||||
|
self.connect('destroy', self.__destroy_cb)
|
||||||
|
self.connect('enter-notify-event', self.__enter_notify_event_cb)
|
||||||
|
self.connect('leave-notify-event', self.__leave_notify_event_cb)
|
||||||
|
|
||||||
|
self._mouse_detector = MouseSpeedDetector(self, 200, 5)
|
||||||
|
self._mouse_detector.connect('motion-slow', self._mouse_slow_cb)
|
||||||
|
|
||||||
|
def __destroy_cb(self, palette):
|
||||||
|
self.set_group_id(None)
|
||||||
|
|
||||||
|
def set_invoker(self, invoker):
|
||||||
|
for hid in self._invoker_hids[:]:
|
||||||
|
self._invoker.disconnect(hid)
|
||||||
|
self._invoker_hids.remove(hid)
|
||||||
|
|
||||||
|
self._invoker = invoker
|
||||||
|
if invoker is not None:
|
||||||
|
self._invoker_hids.append(self._invoker.connect(
|
||||||
|
'mouse-enter', self._invoker_mouse_enter_cb))
|
||||||
|
self._invoker_hids.append(self._invoker.connect(
|
||||||
|
'mouse-leave', self._invoker_mouse_leave_cb))
|
||||||
|
self._invoker_hids.append(self._invoker.connect(
|
||||||
|
'right-click', self._invoker_right_click_cb))
|
||||||
|
|
||||||
|
logging.debug(' Invoker set to %r' % self._invoker)
|
||||||
|
|
||||||
|
def get_invoker(self):
|
||||||
|
return self._invoker
|
||||||
|
|
||||||
|
invoker = gobject.property(type=object,
|
||||||
|
getter=get_invoker,
|
||||||
|
setter=set_invoker)
|
||||||
|
|
||||||
|
def __realize_cb(self, widget):
|
||||||
|
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
|
||||||
|
|
||||||
|
def _mouse_slow_cb(self, widget):
|
||||||
|
self._mouse_detector.stop()
|
||||||
|
self._palette_do_popup()
|
||||||
|
|
||||||
|
def _palette_do_popup(self):
|
||||||
|
immediate = False
|
||||||
|
|
||||||
|
if self.is_up():
|
||||||
|
self._popdown_anim.stop()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._group_id:
|
||||||
|
group = palettegroup.get_group(self._group_id)
|
||||||
|
if group and group.is_up():
|
||||||
|
immediate = True
|
||||||
|
group.popdown()
|
||||||
|
|
||||||
|
self.popup(immediate=immediate)
|
||||||
|
|
||||||
|
def is_up(self):
|
||||||
|
return self._up
|
||||||
|
|
||||||
|
def set_group_id(self, group_id):
|
||||||
|
if self._group_id:
|
||||||
|
group = palettegroup.get_group(self._group_id)
|
||||||
|
group.remove(self)
|
||||||
|
if group_id:
|
||||||
|
self._group_id = group_id
|
||||||
|
group = palettegroup.get_group(group_id)
|
||||||
|
group.add(self)
|
||||||
|
|
||||||
|
def get_group_id(self):
|
||||||
|
return self._group_id
|
||||||
|
|
||||||
|
group_id = gobject.property(type=str,
|
||||||
|
getter=get_group_id,
|
||||||
|
setter=set_group_id)
|
||||||
|
|
||||||
|
def do_size_request(self, requisition):
|
||||||
|
gtk.Window.do_size_request(self, requisition)
|
||||||
|
requisition.width = max(requisition.width, style.GRID_CELL_SIZE * 2)
|
||||||
|
|
||||||
|
def do_size_allocate(self, allocation):
|
||||||
|
gtk.Window.do_size_allocate(self, allocation)
|
||||||
|
|
||||||
|
if self._old_alloc is None or \
|
||||||
|
self._old_alloc.x != allocation.x or \
|
||||||
|
self._old_alloc.y != allocation.y or \
|
||||||
|
self._old_alloc.width != allocation.width or \
|
||||||
|
self._old_alloc.height != allocation.height:
|
||||||
|
self.queue_draw()
|
||||||
|
|
||||||
|
# We need to store old allocation because when size_allocate
|
||||||
|
# is called widget.allocation is already updated.
|
||||||
|
# gtk.Window resizing is different from normal containers:
|
||||||
|
# the X window is resized, widget.allocation is updated from
|
||||||
|
# the configure request handler and finally size_allocate is called.
|
||||||
|
self._old_alloc = allocation
|
||||||
|
|
||||||
|
def do_expose_event(self, event):
|
||||||
|
# We want to draw a border with a beautiful gap
|
||||||
|
if self._invoker is not None and self._invoker.has_rectangle_gap():
|
||||||
|
invoker = self._invoker.get_rect()
|
||||||
|
palette = self.get_rect()
|
||||||
|
|
||||||
|
gap = _calculate_gap(palette, invoker)
|
||||||
|
else:
|
||||||
|
gap = False
|
||||||
|
|
||||||
|
allocation = self.get_allocation()
|
||||||
|
wstyle = self.get_style()
|
||||||
|
|
||||||
|
if gap:
|
||||||
|
wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT,
|
||||||
|
gtk.SHADOW_IN, event.area, self, "palette",
|
||||||
|
0, 0, allocation.width, allocation.height,
|
||||||
|
gap[0], gap[1], gap[2])
|
||||||
|
else:
|
||||||
|
wstyle.paint_box(event.window, gtk.STATE_PRELIGHT,
|
||||||
|
gtk.SHADOW_IN, event.area, self, "palette",
|
||||||
|
0, 0, allocation.width, allocation.height)
|
||||||
|
|
||||||
|
# Fall trough to the container expose handler.
|
||||||
|
# (Leaving out the window expose handler which redraws everything)
|
||||||
|
gtk.Bin.do_expose_event(self, event)
|
||||||
|
|
||||||
|
def update_position(self):
|
||||||
|
logging.debug(' update_position 1 %r %r' % (self._invoker, self._alignment))
|
||||||
|
invoker = self._invoker
|
||||||
|
if invoker is None or self._alignment is None:
|
||||||
|
logging.error('Cannot update the palette position.')
|
||||||
|
return
|
||||||
|
|
||||||
|
rect = self.size_request()
|
||||||
|
position = invoker.get_position_for_alignment(self._alignment, rect)
|
||||||
|
if position is None:
|
||||||
|
position = invoker.get_position(rect)
|
||||||
|
|
||||||
|
logging.debug(' update_position %r %r' % (position.x, position.y))
|
||||||
|
self.move(position.x, position.y)
|
||||||
|
|
||||||
|
def get_full_size_request(self):
|
||||||
|
return self.size_request()
|
||||||
|
|
||||||
|
def popup(self, immediate=False):
|
||||||
|
if self._invoker is not None:
|
||||||
|
full_size_request = self.get_full_size_request()
|
||||||
|
self._alignment = self._invoker.get_alignment(full_size_request)
|
||||||
|
|
||||||
|
self.update_position()
|
||||||
|
self.set_transient_for(self._invoker.get_toplevel())
|
||||||
|
|
||||||
|
self._popdown_anim.stop()
|
||||||
|
|
||||||
|
if not immediate:
|
||||||
|
self._popup_anim.start()
|
||||||
|
else:
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def popdown(self, immediate=False):
|
||||||
|
logging.debug('Palette.popdown immediate %r' % immediate)
|
||||||
|
self._popup_anim.stop()
|
||||||
|
|
||||||
|
self._mouse_detector.stop()
|
||||||
|
|
||||||
|
if not immediate:
|
||||||
|
self._popdown_anim.start()
|
||||||
|
else:
|
||||||
|
self.hide()
|
||||||
|
|
||||||
|
def on_invoker_enter(self):
|
||||||
|
self._mouse_detector.start()
|
||||||
|
|
||||||
|
def on_invoker_leave(self):
|
||||||
|
self._mouse_detector.stop()
|
||||||
|
self.popdown()
|
||||||
|
|
||||||
|
def on_enter(self, event):
|
||||||
|
self._popdown_anim.stop()
|
||||||
|
self._secondary_anim.start()
|
||||||
|
|
||||||
|
def on_leave(self, event):
|
||||||
|
self.popdown()
|
||||||
|
|
||||||
|
def _invoker_mouse_enter_cb(self, invoker):
|
||||||
|
self.on_invoker_enter()
|
||||||
|
|
||||||
|
def _invoker_mouse_leave_cb(self, invoker):
|
||||||
|
self.on_invoker_leave()
|
||||||
|
|
||||||
|
def _invoker_right_click_cb(self, invoker):
|
||||||
|
self.popup(immediate=True)
|
||||||
|
|
||||||
|
def __enter_notify_event_cb(self, widget, event):
|
||||||
|
if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
|
||||||
|
event.mode == gtk.gdk.CROSSING_NORMAL:
|
||||||
|
self.on_enter(event)
|
||||||
|
|
||||||
|
def __leave_notify_event_cb(self, widget, event):
|
||||||
|
if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
|
||||||
|
event.mode == gtk.gdk.CROSSING_NORMAL:
|
||||||
|
self.on_leave(event)
|
||||||
|
|
||||||
|
def __show_cb(self, widget):
|
||||||
|
self._invoker.notify_popup()
|
||||||
|
|
||||||
|
self._up = True
|
||||||
|
self.emit('popup')
|
||||||
|
|
||||||
|
def __hide_cb(self, widget):
|
||||||
|
logging.debug('__hide_cb')
|
||||||
|
self._secondary_anim.stop()
|
||||||
|
|
||||||
|
if self._invoker:
|
||||||
|
self._invoker.notify_popdown()
|
||||||
|
|
||||||
|
self._up = False
|
||||||
|
self.emit('popdown')
|
||||||
|
|
||||||
|
def get_rect(self):
|
||||||
|
win_x, win_y = self.window.get_origin()
|
||||||
|
rectangle = self.get_allocation()
|
||||||
|
|
||||||
|
x = win_x + rectangle.x
|
||||||
|
y = win_y + rectangle.y
|
||||||
|
width = rectangle.width
|
||||||
|
height = rectangle.height
|
||||||
|
|
||||||
|
return gtk.gdk.Rectangle(x, y, width, height)
|
||||||
|
|
||||||
|
def get_palette_state(self):
|
||||||
|
return self._palette_state
|
||||||
|
|
||||||
|
def _set_palette_state(self, state):
|
||||||
|
self._palette_state = state
|
||||||
|
|
||||||
|
def set_palette_state(self, state):
|
||||||
|
self._set_palette_state(state)
|
||||||
|
|
||||||
|
palette_state = property(get_palette_state)
|
||||||
|
|
||||||
|
class Palette(PaletteWindow):
|
||||||
|
__gtype_name__ = 'SugarPalette'
|
||||||
|
|
||||||
# DEPRECATED: label is passed with the primary-text property, accel_path
|
# DEPRECATED: label is passed with the primary-text property, accel_path
|
||||||
# is set via the invoker property, and menu_after_content is not used
|
# is set via the invoker property, and menu_after_content is not used
|
||||||
def __init__(self, label=None, accel_path=None, menu_after_content=False,
|
def __init__(self, label=None, accel_path=None, menu_after_content=False,
|
||||||
text_maxlen=60, **kwargs):
|
text_maxlen=60, **kwargs):
|
||||||
|
|
||||||
self.palette_state = self.PRIMARY
|
|
||||||
|
|
||||||
self._primary_text = None
|
self._primary_text = None
|
||||||
self._secondary_text = None
|
self._secondary_text = None
|
||||||
self._icon = None
|
self._icon = None
|
||||||
self._icon_visible = True
|
self._icon_visible = True
|
||||||
self._group_id = None
|
|
||||||
|
|
||||||
palette_box = gtk.VBox()
|
palette_box = gtk.VBox()
|
||||||
|
|
||||||
@ -200,49 +473,18 @@ class Palette(gtk.Window):
|
|||||||
|
|
||||||
self._menu_content_separator = gtk.HSeparator()
|
self._menu_content_separator = gtk.HSeparator()
|
||||||
|
|
||||||
self._popup_anim = animator.Animator(.5, 10)
|
|
||||||
self._popup_anim.add(_PopupAnimation(self))
|
|
||||||
|
|
||||||
self._secondary_anim = animator.Animator(2.0, 10)
|
self._secondary_anim = animator.Animator(2.0, 10)
|
||||||
self._secondary_anim.add(_SecondaryAnimation(self))
|
self._secondary_anim.add(_SecondaryAnimation(self))
|
||||||
|
|
||||||
self._popdown_anim = animator.Animator(0.6, 10)
|
|
||||||
self._popdown_anim.add(_PopdownAnimation(self))
|
|
||||||
|
|
||||||
# we init after initializing all of our containers
|
# we init after initializing all of our containers
|
||||||
gobject.GObject.__init__(self, **kwargs)
|
PaletteWindow.__init__(self, **kwargs)
|
||||||
|
|
||||||
self.set_decorated(False)
|
|
||||||
self.set_resizable(False)
|
|
||||||
# Just assume xthickness and ythickness are the same
|
|
||||||
self.set_border_width(self.get_style().xthickness)
|
|
||||||
|
|
||||||
accel_group = gtk.AccelGroup()
|
|
||||||
self.set_data('sugar-accel-group', accel_group)
|
|
||||||
self.add_accel_group(accel_group)
|
|
||||||
|
|
||||||
primary_box.set_size_request(-1, style.GRID_CELL_SIZE
|
primary_box.set_size_request(-1, style.GRID_CELL_SIZE
|
||||||
- 2 * self.get_border_width())
|
- 2 * self.get_border_width())
|
||||||
|
|
||||||
|
|
||||||
self.connect('show', self.__show_cb)
|
|
||||||
self.connect('hide', self.__hide_cb)
|
|
||||||
self.connect('realize', self.__realize_cb)
|
|
||||||
self.connect('destroy', self.__destroy_cb)
|
|
||||||
|
|
||||||
self._alignment = None
|
|
||||||
self._old_alloc = None
|
|
||||||
self._full_request = [0, 0]
|
self._full_request = [0, 0]
|
||||||
self._cursor_x = 0
|
|
||||||
self._cursor_y = 0
|
|
||||||
self._invoker = None
|
|
||||||
self._group_id = None
|
|
||||||
self._up = False
|
|
||||||
self._menu_box = None
|
self._menu_box = None
|
||||||
self._content = None
|
self._content = None
|
||||||
self._invoker_hids = []
|
|
||||||
|
|
||||||
self.set_group_id("default")
|
|
||||||
|
|
||||||
# we set these for backward compatibility
|
# we set these for backward compatibility
|
||||||
if label is not None:
|
if label is not None:
|
||||||
@ -263,22 +505,64 @@ class Palette(gtk.Window):
|
|||||||
self.menu = _Menu(self)
|
self.menu = _Menu(self)
|
||||||
self.menu.connect('item-inserted', self.__menu_item_inserted_cb)
|
self.menu.connect('item-inserted', self.__menu_item_inserted_cb)
|
||||||
|
|
||||||
self.connect('enter-notify-event', self.__enter_notify_event_cb)
|
self.connect('realize', self.__realize_cb)
|
||||||
self.connect('leave-notify-event', self.__leave_notify_event_cb)
|
self.connect('show', self.__show_cb)
|
||||||
|
self.connect('hide', self.__hide_cb)
|
||||||
|
self.connect('notify::invoker', self.__notify_invoker_cb)
|
||||||
|
self.connect('destroy', self.__destroy_cb)
|
||||||
|
|
||||||
self._mouse_detector = MouseSpeedDetector(self, 200, 5)
|
def _invoker_right_click_cb(self, invoker):
|
||||||
self._mouse_detector.connect('motion-slow', self._mouse_slow_cb)
|
self.popup(immediate=True, state=self.SECONDARY)
|
||||||
|
|
||||||
|
def do_style_set(self, previous_style):
|
||||||
|
# Prevent a warning from pygtk
|
||||||
|
if previous_style is not None:
|
||||||
|
gtk.Window.do_style_set(self, previous_style)
|
||||||
|
self.set_border_width(self.get_style().xthickness)
|
||||||
|
|
||||||
def __menu_item_inserted_cb(self, menu):
|
def __menu_item_inserted_cb(self, menu):
|
||||||
self._update_separators()
|
self._update_separators()
|
||||||
|
|
||||||
def __destroy_cb(self, palette):
|
def __destroy_cb(self, palette):
|
||||||
self.set_group_id(None)
|
|
||||||
|
|
||||||
# Break the reference cycle. It looks like the gc is not able to free
|
# Break the reference cycle. It looks like the gc is not able to free
|
||||||
# it, possibly because gtk.Menu memory handling is very special.
|
# it, possibly because gtk.Menu memory handling is very special.
|
||||||
self.menu = None
|
self.menu = None
|
||||||
|
|
||||||
|
def __show_cb(self, widget):
|
||||||
|
self.menu.set_active(True)
|
||||||
|
|
||||||
|
def __hide_cb(self, widget):
|
||||||
|
logging.debug('__hide_cb')
|
||||||
|
self.menu.set_active(False)
|
||||||
|
|
||||||
|
def __notify_invoker_cb(self, palette, pspec):
|
||||||
|
invoker = self.props.invoker
|
||||||
|
if invoker is not None and hasattr(invoker.props, 'widget'):
|
||||||
|
logging.debug(('Setup widget', invoker.props.widget))
|
||||||
|
self._update_accel_widget()
|
||||||
|
self._invoker.connect('notify::widget',
|
||||||
|
self.__invoker_widget_changed_cb)
|
||||||
|
|
||||||
|
def __invoker_widget_changed_cb(self, invoker, spec):
|
||||||
|
self._update_accel_widget()
|
||||||
|
|
||||||
|
def get_full_size_request(self):
|
||||||
|
return self._full_request
|
||||||
|
|
||||||
|
def popup(self, immediate=False, state=None):
|
||||||
|
logging.debug('Palette.popup immediate %r' % immediate)
|
||||||
|
|
||||||
|
if self._invoker is not None:
|
||||||
|
self._update_full_request()
|
||||||
|
|
||||||
|
PaletteWindow.popup(self, immediate)
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
state = self.PRIMARY
|
||||||
|
self.set_palette_state(state)
|
||||||
|
|
||||||
|
self._secondary_anim.start()
|
||||||
|
|
||||||
def _add_menu(self):
|
def _add_menu(self):
|
||||||
self._menu_box = gtk.VBox()
|
self._menu_box = gtk.VBox()
|
||||||
self._secondary_box.pack_start(self._menu_box)
|
self._secondary_box.pack_start(self._menu_box)
|
||||||
@ -290,52 +574,6 @@ class Palette(gtk.Window):
|
|||||||
self._content.set_border_width(style.DEFAULT_SPACING)
|
self._content.set_border_width(style.DEFAULT_SPACING)
|
||||||
self._secondary_box.pack_start(self._content)
|
self._secondary_box.pack_start(self._content)
|
||||||
|
|
||||||
def do_style_set(self, previous_style):
|
|
||||||
# Prevent a warning from pygtk
|
|
||||||
if previous_style is not None:
|
|
||||||
gtk.Window.do_style_set(self, previous_style)
|
|
||||||
self.set_border_width(self.get_style().xthickness)
|
|
||||||
|
|
||||||
def is_up(self):
|
|
||||||
return self._up
|
|
||||||
|
|
||||||
def get_rect(self):
|
|
||||||
win_x, win_y = self.window.get_origin()
|
|
||||||
rectangle = self.get_allocation()
|
|
||||||
|
|
||||||
x = win_x + rectangle.x
|
|
||||||
y = win_y + rectangle.y
|
|
||||||
width = rectangle.width
|
|
||||||
height = rectangle.height
|
|
||||||
|
|
||||||
return gtk.gdk.Rectangle(x, y, width, height)
|
|
||||||
|
|
||||||
def set_invoker(self, invoker):
|
|
||||||
for hid in self._invoker_hids[:]:
|
|
||||||
self._invoker.disconnect(hid)
|
|
||||||
self._invoker_hids.remove(hid)
|
|
||||||
|
|
||||||
self._invoker = invoker
|
|
||||||
if invoker is not None:
|
|
||||||
self._invoker_hids.append(self._invoker.connect(
|
|
||||||
'mouse-enter', self._invoker_mouse_enter_cb))
|
|
||||||
self._invoker_hids.append(self._invoker.connect(
|
|
||||||
'mouse-leave', self._invoker_mouse_leave_cb))
|
|
||||||
self._invoker_hids.append(self._invoker.connect(
|
|
||||||
'right-click', self._invoker_right_click_cb))
|
|
||||||
if hasattr(invoker.props, 'widget'):
|
|
||||||
self._update_accel_widget()
|
|
||||||
logging.debug(('Setup widget', invoker.props.widget))
|
|
||||||
self._invoker_hids.append(self._invoker.connect(
|
|
||||||
'notify::widget', self._invoker_widget_changed_cb))
|
|
||||||
|
|
||||||
def get_invoker(self):
|
|
||||||
return self._invoker
|
|
||||||
|
|
||||||
invoker = gobject.property(type=object,
|
|
||||||
getter=get_invoker,
|
|
||||||
setter=set_invoker)
|
|
||||||
|
|
||||||
def _update_accel_widget(self):
|
def _update_accel_widget(self):
|
||||||
assert self.props.invoker is not None
|
assert self.props.invoker is not None
|
||||||
self._label.props.accel_widget = self.props.invoker.props.widget
|
self._label.props.accel_widget = self.props.invoker.props.widget
|
||||||
@ -438,24 +676,8 @@ class Palette(gtk.Window):
|
|||||||
self._update_accept_focus()
|
self._update_accept_focus()
|
||||||
self._update_separators()
|
self._update_separators()
|
||||||
|
|
||||||
def set_group_id(self, group_id):
|
|
||||||
if self._group_id:
|
|
||||||
group = palettegroup.get_group(self._group_id)
|
|
||||||
group.remove(self)
|
|
||||||
if group_id:
|
|
||||||
self._group_id = group_id
|
|
||||||
group = palettegroup.get_group(group_id)
|
|
||||||
group.add(self)
|
|
||||||
|
|
||||||
def get_group_id(self):
|
|
||||||
return self._group_id
|
|
||||||
|
|
||||||
group_id = gobject.property(type=str,
|
|
||||||
getter=get_group_id,
|
|
||||||
setter=set_group_id)
|
|
||||||
|
|
||||||
def do_size_request(self, requisition):
|
def do_size_request(self, requisition):
|
||||||
gtk.Window.do_size_request(self, requisition)
|
PaletteWindow.do_size_request(self, requisition)
|
||||||
|
|
||||||
# gtk.AccelLabel request doesn't include the accelerator.
|
# gtk.AccelLabel request doesn't include the accelerator.
|
||||||
label_width = self._label_alignment.size_request()[0] + \
|
label_width = self._label_alignment.size_request()[0] + \
|
||||||
@ -463,54 +685,9 @@ class Palette(gtk.Window):
|
|||||||
2 * self.get_border_width()
|
2 * self.get_border_width()
|
||||||
|
|
||||||
requisition.width = max(requisition.width,
|
requisition.width = max(requisition.width,
|
||||||
style.GRID_CELL_SIZE * 2,
|
|
||||||
label_width,
|
label_width,
|
||||||
self._full_request[0])
|
self._full_request[0])
|
||||||
|
|
||||||
def do_size_allocate(self, allocation):
|
|
||||||
gtk.Window.do_size_allocate(self, allocation)
|
|
||||||
|
|
||||||
if self._old_alloc is None or \
|
|
||||||
self._old_alloc.x != allocation.x or \
|
|
||||||
self._old_alloc.y != allocation.y or \
|
|
||||||
self._old_alloc.width != allocation.width or \
|
|
||||||
self._old_alloc.height != allocation.height:
|
|
||||||
self.queue_draw()
|
|
||||||
|
|
||||||
# We need to store old allocation because when size_allocate
|
|
||||||
# is called widget.allocation is already updated.
|
|
||||||
# gtk.Window resizing is different from normal containers:
|
|
||||||
# the X window is resized, widget.allocation is updated from
|
|
||||||
# the configure request handler and finally size_allocate is called.
|
|
||||||
self._old_alloc = allocation
|
|
||||||
|
|
||||||
def do_expose_event(self, event):
|
|
||||||
# We want to draw a border with a beautiful gap
|
|
||||||
if self._invoker is not None and self._invoker.has_rectangle_gap():
|
|
||||||
invoker = self._invoker.get_rect()
|
|
||||||
palette = self.get_rect()
|
|
||||||
|
|
||||||
gap = _calculate_gap(palette, invoker)
|
|
||||||
else:
|
|
||||||
gap = False
|
|
||||||
|
|
||||||
allocation = self.get_allocation()
|
|
||||||
wstyle = self.get_style()
|
|
||||||
|
|
||||||
if gap:
|
|
||||||
wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT,
|
|
||||||
gtk.SHADOW_IN, event.area, self, "palette",
|
|
||||||
0, 0, allocation.width, allocation.height,
|
|
||||||
gap[0], gap[1], gap[2])
|
|
||||||
else:
|
|
||||||
wstyle.paint_box(event.window, gtk.STATE_PRELIGHT,
|
|
||||||
gtk.SHADOW_IN, event.area, self, "palette",
|
|
||||||
0, 0, allocation.width, allocation.height)
|
|
||||||
|
|
||||||
# Fall trough to the container expose handler.
|
|
||||||
# (Leaving out the window expose handler which redraws everything)
|
|
||||||
gtk.Bin.do_expose_event(self, event)
|
|
||||||
|
|
||||||
def _update_separators(self):
|
def _update_separators(self):
|
||||||
visible = len(self.menu.get_children()) > 0 or \
|
visible = len(self.menu.get_children()) > 0 or \
|
||||||
len(self._content.get_children()) > 0
|
len(self._content.get_children()) > 0
|
||||||
@ -526,68 +703,21 @@ class Palette(gtk.Window):
|
|||||||
self.window.set_accept_focus(accept_focus)
|
self.window.set_accept_focus(accept_focus)
|
||||||
|
|
||||||
def __realize_cb(self, widget):
|
def __realize_cb(self, widget):
|
||||||
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
|
|
||||||
self._update_accept_focus()
|
self._update_accept_focus()
|
||||||
|
|
||||||
def _update_full_request(self):
|
def _update_full_request(self):
|
||||||
if self.palette_state == self.PRIMARY:
|
if self._palette_state == self.PRIMARY:
|
||||||
self.menu.embed(self._menu_box)
|
self.menu.embed(self._menu_box)
|
||||||
self._secondary_box.show()
|
self._secondary_box.show()
|
||||||
|
|
||||||
self._full_request = self.size_request()
|
self._full_request = self.size_request()
|
||||||
|
|
||||||
if self.palette_state == self.PRIMARY:
|
if self._palette_state == self.PRIMARY:
|
||||||
self.menu.unembed()
|
self.menu.unembed()
|
||||||
self._secondary_box.hide()
|
self._secondary_box.hide()
|
||||||
|
|
||||||
def _update_position(self):
|
def _set_palette_state(self, state):
|
||||||
invoker = self._invoker
|
if self._palette_state == state:
|
||||||
if invoker is None or self._alignment is None:
|
|
||||||
logging.error('Cannot update the palette position.')
|
|
||||||
return
|
|
||||||
|
|
||||||
rect = self.size_request()
|
|
||||||
position = invoker.get_position_for_alignment(self._alignment, rect)
|
|
||||||
if position is None:
|
|
||||||
position = invoker.get_position(rect)
|
|
||||||
|
|
||||||
self.move(position.x, position.y)
|
|
||||||
|
|
||||||
def popup(self, immediate=False, state=None):
|
|
||||||
logging.debug('Palette.popup immediate %r' % immediate)
|
|
||||||
|
|
||||||
if state is None:
|
|
||||||
state = self.PRIMARY
|
|
||||||
self.set_state(state)
|
|
||||||
|
|
||||||
if self._invoker is not None:
|
|
||||||
self._update_full_request()
|
|
||||||
self._alignment = self._invoker.get_alignment(self._full_request)
|
|
||||||
self._update_position()
|
|
||||||
self.set_transient_for(self._invoker.get_toplevel())
|
|
||||||
|
|
||||||
self._popdown_anim.stop()
|
|
||||||
|
|
||||||
if not immediate:
|
|
||||||
self._popup_anim.start()
|
|
||||||
else:
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
self._secondary_anim.start()
|
|
||||||
|
|
||||||
def popdown(self, immediate=False):
|
|
||||||
logging.debug('Palette.popdown immediate %r' % immediate)
|
|
||||||
self._popup_anim.stop()
|
|
||||||
|
|
||||||
self._mouse_detector.stop()
|
|
||||||
|
|
||||||
if not immediate:
|
|
||||||
self._popdown_anim.start()
|
|
||||||
else:
|
|
||||||
self.hide()
|
|
||||||
|
|
||||||
def set_state(self, state):
|
|
||||||
if self.palette_state == state:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if state == self.PRIMARY:
|
if state == self.PRIMARY:
|
||||||
@ -596,73 +726,9 @@ class Palette(gtk.Window):
|
|||||||
elif state == self.SECONDARY:
|
elif state == self.SECONDARY:
|
||||||
self.menu.embed(self._menu_box)
|
self.menu.embed(self._menu_box)
|
||||||
self._secondary_box.show()
|
self._secondary_box.show()
|
||||||
self._update_position()
|
self.update_position()
|
||||||
|
|
||||||
self.palette_state = state
|
|
||||||
|
|
||||||
def _mouse_slow_cb(self, widget):
|
|
||||||
self._mouse_detector.stop()
|
|
||||||
self._palette_do_popup()
|
|
||||||
|
|
||||||
def _palette_do_popup(self):
|
|
||||||
immediate = False
|
|
||||||
|
|
||||||
if self.is_up():
|
|
||||||
self._popdown_anim.stop()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self._group_id:
|
|
||||||
group = palettegroup.get_group(self._group_id)
|
|
||||||
if group and group.is_up():
|
|
||||||
immediate = True
|
|
||||||
group.popdown()
|
|
||||||
|
|
||||||
self.popup(immediate=immediate)
|
|
||||||
|
|
||||||
def _invoker_widget_changed_cb(self, invoker, spec):
|
|
||||||
self._update_accel_widget()
|
|
||||||
|
|
||||||
def _invoker_mouse_enter_cb(self, invoker):
|
|
||||||
self._mouse_detector.start()
|
|
||||||
|
|
||||||
def _invoker_mouse_leave_cb(self, invoker):
|
|
||||||
self._mouse_detector.stop()
|
|
||||||
self.popdown()
|
|
||||||
|
|
||||||
def _invoker_right_click_cb(self, invoker):
|
|
||||||
self.popup(immediate=True, state=self.SECONDARY)
|
|
||||||
|
|
||||||
def __enter_notify_event_cb(self, widget, event):
|
|
||||||
if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
|
|
||||||
event.mode == gtk.gdk.CROSSING_NORMAL:
|
|
||||||
self._popdown_anim.stop()
|
|
||||||
self._secondary_anim.start()
|
|
||||||
|
|
||||||
def __leave_notify_event_cb(self, widget, event):
|
|
||||||
if event.detail != gtk.gdk.NOTIFY_INFERIOR and \
|
|
||||||
event.mode == gtk.gdk.CROSSING_NORMAL:
|
|
||||||
self.popdown()
|
|
||||||
|
|
||||||
def __show_cb(self, widget):
|
|
||||||
self.menu.set_active(True)
|
|
||||||
|
|
||||||
self._invoker.notify_popup()
|
|
||||||
|
|
||||||
self._up = True
|
|
||||||
self.emit('popup')
|
|
||||||
|
|
||||||
def __hide_cb(self, widget):
|
|
||||||
logging.debug('__hide_cb')
|
|
||||||
self.menu.set_active(False)
|
|
||||||
|
|
||||||
self._secondary_anim.stop()
|
|
||||||
|
|
||||||
if self._invoker:
|
|
||||||
self._invoker.notify_popdown()
|
|
||||||
|
|
||||||
self._up = False
|
|
||||||
self.emit('popdown')
|
|
||||||
|
|
||||||
|
self._palette_state = state
|
||||||
|
|
||||||
class PaletteActionBar(gtk.HButtonBox):
|
class PaletteActionBar(gtk.HButtonBox):
|
||||||
def add_action(self, label, icon_name=None):
|
def add_action(self, label, icon_name=None):
|
||||||
@ -728,7 +794,7 @@ class _SecondaryAnimation(animator.Animation):
|
|||||||
|
|
||||||
def next_frame(self, current):
|
def next_frame(self, current):
|
||||||
if current == 1.0:
|
if current == 1.0:
|
||||||
self._palette.set_state(Palette.SECONDARY)
|
self._palette.set_palette_state(Palette.SECONDARY)
|
||||||
|
|
||||||
class _PopdownAnimation(animator.Animation):
|
class _PopdownAnimation(animator.Animation):
|
||||||
def __init__(self, palette):
|
def __init__(self, palette):
|
||||||
|
98
src/sugar/graphics/radiopalette.py
Normal file
98
src/sugar/graphics/radiopalette.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# Copyright (C) 2009, Aleksey Lim
|
||||||
|
#
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the
|
||||||
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
import gtk
|
||||||
|
|
||||||
|
from sugar.graphics import style
|
||||||
|
from sugar.graphics.toolbutton import ToolButton
|
||||||
|
from sugar.graphics.palette import Palette
|
||||||
|
|
||||||
|
class RadioMenuButton(ToolButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
ToolButton.__init__(self, **kwargs)
|
||||||
|
self.selected_button = None
|
||||||
|
|
||||||
|
if self.props.palette:
|
||||||
|
self.__palette_cb(None, None)
|
||||||
|
|
||||||
|
self.connect('notify::palette', self.__palette_cb)
|
||||||
|
|
||||||
|
def __palette_cb(self, widget, pspec):
|
||||||
|
if not isinstance(self.props.palette, RadioPalette):
|
||||||
|
return
|
||||||
|
self.props.palette.update_button()
|
||||||
|
|
||||||
|
def do_clicked(self):
|
||||||
|
if self.palette is None:
|
||||||
|
return
|
||||||
|
if self.palette.is_up() and \
|
||||||
|
self.palette.palette_state == Palette.SECONDARY:
|
||||||
|
self.palette.popdown(immediate=True)
|
||||||
|
else:
|
||||||
|
self.palette.popup(immediate=True, state=Palette.SECONDARY)
|
||||||
|
|
||||||
|
class RadioToolsButton(RadioMenuButton):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
RadioMenuButton.__init__(self, **kwargs)
|
||||||
|
|
||||||
|
def do_clicked(self):
|
||||||
|
if not self.selected_button:
|
||||||
|
return
|
||||||
|
self.selected_button.emit('clicked')
|
||||||
|
|
||||||
|
class RadioPalette(Palette):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
Palette.__init__(self, **kwargs)
|
||||||
|
|
||||||
|
self.button_box = gtk.HBox()
|
||||||
|
self.button_box.show()
|
||||||
|
self.set_content(self.button_box)
|
||||||
|
|
||||||
|
def append(self, button, label):
|
||||||
|
children = self.button_box.get_children()
|
||||||
|
|
||||||
|
if button.palette is not None:
|
||||||
|
raise RuntimeError("Palette's button should not have sub-palettes")
|
||||||
|
|
||||||
|
button.show()
|
||||||
|
button.connect('clicked', self.__clicked_cb)
|
||||||
|
self.button_box.pack_start(button, fill=False)
|
||||||
|
button.palette_label = label
|
||||||
|
|
||||||
|
if not children:
|
||||||
|
self.__clicked_cb(button)
|
||||||
|
|
||||||
|
def update_button(self):
|
||||||
|
for i in self.button_box.get_children():
|
||||||
|
self.__clicked_cb(i)
|
||||||
|
|
||||||
|
def __clicked_cb(self, button):
|
||||||
|
if not button.get_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set_primary_text(button.palette_label)
|
||||||
|
self.popdown(immediate=True)
|
||||||
|
|
||||||
|
if self.invoker is not None:
|
||||||
|
parent = self.invoker.parent
|
||||||
|
else:
|
||||||
|
parent = None
|
||||||
|
if not isinstance(parent, RadioMenuButton):
|
||||||
|
return
|
||||||
|
|
||||||
|
parent.set_icon(button.props.icon_name)
|
||||||
|
parent.selected_button = button
|
@ -28,7 +28,7 @@ import logging
|
|||||||
import gtk
|
import gtk
|
||||||
import pango
|
import pango
|
||||||
|
|
||||||
_FOCUS_LINE_WIDTH = 2
|
FOCUS_LINE_WIDTH = 2
|
||||||
_TAB_CURVATURE = 1
|
_TAB_CURVATURE = 1
|
||||||
|
|
||||||
def _compute_zoom_factor():
|
def _compute_zoom_factor():
|
||||||
@ -115,8 +115,8 @@ FONT_BOLD_H = zoom(24)
|
|||||||
|
|
||||||
TOOLBOX_SEPARATOR_HEIGHT = zoom(9)
|
TOOLBOX_SEPARATOR_HEIGHT = zoom(9)
|
||||||
TOOLBOX_HORIZONTAL_PADDING = zoom(75)
|
TOOLBOX_HORIZONTAL_PADDING = zoom(75)
|
||||||
TOOLBOX_TAB_VBORDER = int((zoom(36) - FONT_NORMAL_H - _FOCUS_LINE_WIDTH) / 2)
|
TOOLBOX_TAB_VBORDER = int((zoom(36) - FONT_NORMAL_H - FOCUS_LINE_WIDTH) / 2)
|
||||||
TOOLBOX_TAB_HBORDER = zoom(15) - _FOCUS_LINE_WIDTH - _TAB_CURVATURE
|
TOOLBOX_TAB_HBORDER = zoom(15) - FOCUS_LINE_WIDTH - _TAB_CURVATURE
|
||||||
TOOLBOX_TAB_LABEL_WIDTH = zoom(150 - 15 * 2)
|
TOOLBOX_TAB_LABEL_WIDTH = zoom(150 - 15 * 2)
|
||||||
|
|
||||||
COLOR_BLACK = Color('#000000')
|
COLOR_BLACK = Color('#000000')
|
||||||
@ -131,3 +131,5 @@ COLOR_INACTIVE_STROKE = Color('#757575')
|
|||||||
COLOR_TEXT_FIELD_GREY = Color('#E5E5E5')
|
COLOR_TEXT_FIELD_GREY = Color('#E5E5E5')
|
||||||
|
|
||||||
PALETTE_CURSOR_DISTANCE = zoom(10)
|
PALETTE_CURSOR_DISTANCE = zoom(10)
|
||||||
|
|
||||||
|
TOOLBAR_ARROW_SIZE = zoom(24)
|
||||||
|
284
src/sugar/graphics/toolbarbox.py
Normal file
284
src/sugar/graphics/toolbarbox.py
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
# Copyright (C) 2009, Aleksey Lim
|
||||||
|
#
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the
|
||||||
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from sugar.graphics import style
|
||||||
|
from sugar.graphics.palette import PaletteWindow, ToolInvoker
|
||||||
|
from sugar.graphics.toolbutton import ToolButton
|
||||||
|
from sugar.graphics import palettegroup
|
||||||
|
|
||||||
|
class ToolbarButton(ToolButton):
|
||||||
|
def __init__(self, page=None, **kwargs):
|
||||||
|
ToolButton.__init__(self, **kwargs)
|
||||||
|
|
||||||
|
self.set_page(page)
|
||||||
|
|
||||||
|
self.connect('clicked',
|
||||||
|
lambda widget: self.set_expanded(not self.is_expanded()))
|
||||||
|
|
||||||
|
def get_toolbar_box(self):
|
||||||
|
if not hasattr(self.parent, 'owner'):
|
||||||
|
return None
|
||||||
|
return self.parent.owner
|
||||||
|
|
||||||
|
toolbar_box = property(get_toolbar_box)
|
||||||
|
|
||||||
|
def get_page(self):
|
||||||
|
if self.page_widget is None:
|
||||||
|
return None
|
||||||
|
return self.page_widget.child.child
|
||||||
|
|
||||||
|
def set_page(self, page):
|
||||||
|
if page is None:
|
||||||
|
self.page_widget = None
|
||||||
|
return
|
||||||
|
self.page_widget = _embody_page(_Box, page)
|
||||||
|
self.page_widget.toolbar_button = self
|
||||||
|
page.show()
|
||||||
|
if self.props.palette is None:
|
||||||
|
self.props.palette = _ToolbarPalette(invoker=ToolInvoker(self))
|
||||||
|
self.props.palette.toolbar_button = self
|
||||||
|
self._move_page_to_palette()
|
||||||
|
|
||||||
|
page = gobject.property(type=object, getter=get_page, setter=set_page)
|
||||||
|
|
||||||
|
def _move_page_to_palette(self):
|
||||||
|
if self.page_widget is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.toolbar_box is not None and \
|
||||||
|
self.page_widget in self.toolbar_box.get_children():
|
||||||
|
self.toolbar_box.remove(self.page_widget)
|
||||||
|
|
||||||
|
if isinstance(self.props.palette, _ToolbarPalette):
|
||||||
|
self.props.palette.add(self.page_widget)
|
||||||
|
|
||||||
|
def is_expanded(self):
|
||||||
|
return self.toolbar_box is not None and self.page_widget is not None \
|
||||||
|
and self.toolbar_box.expanded_button == self
|
||||||
|
|
||||||
|
def popdown(self):
|
||||||
|
self.props.palette.popdown(immediate=True)
|
||||||
|
|
||||||
|
def set_expanded(self, expanded):
|
||||||
|
self.popdown()
|
||||||
|
|
||||||
|
box = self.toolbar_box
|
||||||
|
|
||||||
|
if box is None or self.page_widget is None or \
|
||||||
|
self.is_expanded() == expanded:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not expanded:
|
||||||
|
box.remove(self.page_widget)
|
||||||
|
box.expanded_button = None
|
||||||
|
self._move_page_to_palette()
|
||||||
|
return
|
||||||
|
|
||||||
|
if box.expanded_button is not None:
|
||||||
|
# need to redraw it to erase arrow
|
||||||
|
expanded_toolitem = box.expanded_button.page_widget.toolbar_button
|
||||||
|
if expanded_toolitem.window is not None:
|
||||||
|
expanded_toolitem.window.invalidate_rect(None, True)
|
||||||
|
box.expanded_button.set_expanded(False)
|
||||||
|
|
||||||
|
if self.page_widget.parent is not None:
|
||||||
|
self.props.palette.remove(self.page_widget)
|
||||||
|
|
||||||
|
self.modify_bg(gtk.STATE_NORMAL, box.background)
|
||||||
|
_setup_page(self.page_widget, box.background, box.props.padding)
|
||||||
|
box.pack_start(self.page_widget)
|
||||||
|
box.expanded_button = self
|
||||||
|
|
||||||
|
def do_expose_event(self, event):
|
||||||
|
if not self.is_expanded() or self.props.palette is not None and \
|
||||||
|
self.props.palette.is_up():
|
||||||
|
ToolButton.do_expose_event(self, event)
|
||||||
|
_paint_arrow(self, event, gtk.ARROW_DOWN)
|
||||||
|
return
|
||||||
|
|
||||||
|
alloc = self.allocation
|
||||||
|
|
||||||
|
self.get_style().paint_box(event.window,
|
||||||
|
gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self,
|
||||||
|
'palette-invoker', alloc.x, 0,
|
||||||
|
alloc.width, alloc.height + style.FOCUS_LINE_WIDTH)
|
||||||
|
|
||||||
|
if self.child.state != gtk.STATE_PRELIGHT:
|
||||||
|
self.get_style().paint_box(event.window,
|
||||||
|
gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None,
|
||||||
|
alloc.x + style.FOCUS_LINE_WIDTH, style.FOCUS_LINE_WIDTH,
|
||||||
|
alloc.width - style.FOCUS_LINE_WIDTH * 2, alloc.height)
|
||||||
|
|
||||||
|
gtk.ToolButton.do_expose_event(self, event)
|
||||||
|
_paint_arrow(self, event, gtk.ARROW_UP)
|
||||||
|
|
||||||
|
class ToolbarBox(gtk.VBox):
|
||||||
|
def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING):
|
||||||
|
gtk.VBox.__init__(self)
|
||||||
|
self.expanded_button = None
|
||||||
|
self.background = None
|
||||||
|
|
||||||
|
self._toolbar = gtk.Toolbar()
|
||||||
|
self._toolbar.owner = self
|
||||||
|
self._toolbar.connect('remove', self.__remove_cb)
|
||||||
|
|
||||||
|
top_widget = _embody_page(gtk.EventBox, self._toolbar)
|
||||||
|
self.pack_start(top_widget)
|
||||||
|
|
||||||
|
self.props.padding = padding
|
||||||
|
self.modify_bg(gtk.STATE_NORMAL,
|
||||||
|
style.COLOR_TOOLBAR_GREY.get_gdk_color())
|
||||||
|
|
||||||
|
def __remove_cb(self, sender, button):
|
||||||
|
if not isinstance(button, ToolbarButton):
|
||||||
|
return
|
||||||
|
button.popdown()
|
||||||
|
if self.expanded_button == button:
|
||||||
|
self.remove(button.page_widget)
|
||||||
|
self.expanded_button = None
|
||||||
|
|
||||||
|
def get_toolbar(self):
|
||||||
|
return self._toolbar
|
||||||
|
|
||||||
|
toolbar = property(get_toolbar)
|
||||||
|
|
||||||
|
def get_padding(self):
|
||||||
|
return self.toolbar.parent.props.left_padding
|
||||||
|
|
||||||
|
def set_padding(self, pad):
|
||||||
|
self.toolbar.parent.set_padding(0, 0, pad, pad)
|
||||||
|
|
||||||
|
padding = gobject.property(type=object,
|
||||||
|
getter=get_padding, setter=set_padding)
|
||||||
|
|
||||||
|
def modify_bg(self, state, color):
|
||||||
|
if state == gtk.STATE_NORMAL:
|
||||||
|
self.background = color
|
||||||
|
self.toolbar.parent.parent.modify_bg(state, color)
|
||||||
|
self.toolbar.modify_bg(state, color)
|
||||||
|
|
||||||
|
class _ToolbarPalette(PaletteWindow):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
PaletteWindow.__init__(self, **kwargs)
|
||||||
|
self.toolbar_box = None
|
||||||
|
self.set_border_width(0)
|
||||||
|
self._focus = 0
|
||||||
|
|
||||||
|
group = palettegroup.get_group('default')
|
||||||
|
group.connect('popdown', self.__group_popdown_cb)
|
||||||
|
self.set_group_id('toolbar_box')
|
||||||
|
|
||||||
|
def on_invoker_enter(self):
|
||||||
|
PaletteWindow.on_invoker_enter(self)
|
||||||
|
self._handle_focus(+1)
|
||||||
|
|
||||||
|
def on_invoker_leave(self):
|
||||||
|
PaletteWindow.on_invoker_leave(self)
|
||||||
|
self._handle_focus(-1)
|
||||||
|
|
||||||
|
def on_enter(self, event):
|
||||||
|
PaletteWindow.on_enter(self, event)
|
||||||
|
self._handle_focus(+1)
|
||||||
|
|
||||||
|
def on_leave(self, event):
|
||||||
|
PaletteWindow.on_enter(self, event)
|
||||||
|
self._handle_focus(-1)
|
||||||
|
|
||||||
|
def _handle_focus(self, delta):
|
||||||
|
self._focus += delta
|
||||||
|
if self._focus not in (0, 1):
|
||||||
|
logging.error('_Palette._focus=%s not in (0, 1)' % self._focus)
|
||||||
|
|
||||||
|
if self._focus == 0:
|
||||||
|
group = palettegroup.get_group('default')
|
||||||
|
if not group.is_up():
|
||||||
|
self.popdown()
|
||||||
|
|
||||||
|
def do_size_request(self, requisition):
|
||||||
|
gtk.Window.do_size_request(self, requisition)
|
||||||
|
requisition.width = max(requisition.width,
|
||||||
|
gtk.gdk.screen_width())
|
||||||
|
|
||||||
|
def popup(self, immediate=False):
|
||||||
|
button = self.toolbar_button
|
||||||
|
if button.is_expanded():
|
||||||
|
return
|
||||||
|
box = button.toolbar_box
|
||||||
|
_setup_page(button.page_widget, style.COLOR_BLACK.get_gdk_color(),
|
||||||
|
box.props.padding)
|
||||||
|
PaletteWindow.popup(self, immediate)
|
||||||
|
|
||||||
|
def __group_popdown_cb(self, group):
|
||||||
|
if self._focus == 0:
|
||||||
|
self.popdown(immediate=True)
|
||||||
|
|
||||||
|
class _Box(gtk.EventBox):
|
||||||
|
def __init__(self):
|
||||||
|
gtk.EventBox.__init__(self)
|
||||||
|
self.connect('expose-event', self.do_expose_event)
|
||||||
|
self.set_app_paintable(True)
|
||||||
|
|
||||||
|
def do_expose_event(self, widget, event):
|
||||||
|
alloc = self.toolbar_button.allocation
|
||||||
|
self.get_style().paint_box(event.window,
|
||||||
|
gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self,
|
||||||
|
'palette-invoker', -style.FOCUS_LINE_WIDTH, 0,
|
||||||
|
self.allocation.width + style.FOCUS_LINE_WIDTH * 2,
|
||||||
|
self.allocation.height + style.FOCUS_LINE_WIDTH)
|
||||||
|
self.get_style().paint_box(event.window,
|
||||||
|
gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None,
|
||||||
|
alloc.x + style.FOCUS_LINE_WIDTH, 0,
|
||||||
|
alloc.width - style.FOCUS_LINE_WIDTH * 2,
|
||||||
|
style.FOCUS_LINE_WIDTH)
|
||||||
|
|
||||||
|
def _setup_page(page_widget, color, hpad):
|
||||||
|
vpad = style.FOCUS_LINE_WIDTH
|
||||||
|
page_widget.child.set_padding(vpad, vpad, hpad, hpad)
|
||||||
|
|
||||||
|
page = page_widget.child.child
|
||||||
|
page.modify_bg(gtk.STATE_NORMAL, color)
|
||||||
|
if isinstance(page, gtk.Container):
|
||||||
|
for i in page.get_children():
|
||||||
|
i.modify_bg(gtk.STATE_NORMAL, color)
|
||||||
|
|
||||||
|
page_widget.modify_bg(gtk.STATE_NORMAL, color)
|
||||||
|
page_widget.modify_bg(gtk.STATE_PRELIGHT, color)
|
||||||
|
|
||||||
|
def _embody_page(box_class, widget):
|
||||||
|
widget.show()
|
||||||
|
alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
|
||||||
|
alignment.add(widget)
|
||||||
|
alignment.show()
|
||||||
|
box = box_class()
|
||||||
|
box.modify_bg(gtk.STATE_ACTIVE, style.COLOR_BUTTON_GREY.get_gdk_color())
|
||||||
|
box.add(alignment)
|
||||||
|
box.show()
|
||||||
|
return box
|
||||||
|
|
||||||
|
def _paint_arrow(widget, event, arrow_type):
|
||||||
|
alloc = widget.allocation
|
||||||
|
x = alloc.x + alloc.width / 2 - style.TOOLBAR_ARROW_SIZE / 2
|
||||||
|
y = alloc.y + alloc.height - int(style.TOOLBAR_ARROW_SIZE * .85)
|
||||||
|
|
||||||
|
widget.get_style().paint_arrow(event.window,
|
||||||
|
gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, widget,
|
||||||
|
None, arrow_type, True,
|
||||||
|
x, y, style.TOOLBAR_ARROW_SIZE, style.TOOLBAR_ARROW_SIZE)
|
@ -68,7 +68,6 @@ class ToolButton(gtk.ToolButton):
|
|||||||
if icon_name:
|
if icon_name:
|
||||||
self.set_icon(icon_name)
|
self.set_icon(icon_name)
|
||||||
|
|
||||||
self.connect('clicked', self.__button_clicked_cb)
|
|
||||||
self.get_child().connect('can-activate-accel',
|
self.get_child().connect('can-activate-accel',
|
||||||
self.__button_can_activate_accel_cb)
|
self.__button_can_activate_accel_cb)
|
||||||
|
|
||||||
@ -152,7 +151,6 @@ class ToolButton(gtk.ToolButton):
|
|||||||
|
|
||||||
gtk.ToolButton.do_expose_event(self, event)
|
gtk.ToolButton.do_expose_event(self, event)
|
||||||
|
|
||||||
def __button_clicked_cb(self, widget):
|
def do_clicked(self):
|
||||||
if self.palette:
|
if self.palette:
|
||||||
self.palette.popdown(True)
|
self.palette.popdown(True)
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ STABLE.
|
|||||||
|
|
||||||
import gobject
|
import gobject
|
||||||
import gtk
|
import gtk
|
||||||
|
import logging
|
||||||
|
import warnings
|
||||||
|
|
||||||
from sugar.graphics.icon import Icon
|
from sugar.graphics.icon import Icon
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ class Window(gtk.Window):
|
|||||||
self.connect('window-state-event', self.__window_state_event_cb)
|
self.connect('window-state-event', self.__window_state_event_cb)
|
||||||
self.connect('key-press-event', self.__key_press_cb)
|
self.connect('key-press-event', self.__key_press_cb)
|
||||||
|
|
||||||
self.toolbox = None
|
self.__toolbar_box = None
|
||||||
self._alerts = []
|
self._alerts = []
|
||||||
self._canvas = None
|
self._canvas = None
|
||||||
self.tray = None
|
self.tray = None
|
||||||
@ -125,14 +127,19 @@ class Window(gtk.Window):
|
|||||||
|
|
||||||
canvas = property(get_canvas, set_canvas)
|
canvas = property(get_canvas, set_canvas)
|
||||||
|
|
||||||
def set_toolbox(self, toolbox):
|
def get_toolbar_box(self):
|
||||||
if self.toolbox:
|
return self.__toolbar_box
|
||||||
self._vbox.remove(self.toolbox)
|
|
||||||
|
|
||||||
self._vbox.pack_start(toolbox, False)
|
def set_toolbar_box(self, toolbar_box):
|
||||||
self._vbox.reorder_child(toolbox, 0)
|
if self.__toolbar_box:
|
||||||
|
self._vbox.remove(self.__toolbar_box)
|
||||||
|
|
||||||
self.toolbox = toolbox
|
self._vbox.pack_start(toolbar_box, False)
|
||||||
|
self._vbox.reorder_child(toolbar_box, 0)
|
||||||
|
|
||||||
|
self.__toolbar_box = toolbar_box
|
||||||
|
|
||||||
|
toolbar_box = property(get_toolbar_box, set_toolbar_box)
|
||||||
|
|
||||||
def set_tray(self, tray, position):
|
def set_tray(self, tray, position):
|
||||||
if self.tray:
|
if self.tray:
|
||||||
@ -152,7 +159,7 @@ class Window(gtk.Window):
|
|||||||
self._alerts.append(alert)
|
self._alerts.append(alert)
|
||||||
if len(self._alerts) == 1:
|
if len(self._alerts) == 1:
|
||||||
self._vbox.pack_start(alert, False)
|
self._vbox.pack_start(alert, False)
|
||||||
if self.toolbox is not None:
|
if self.__toolbar_box is not None:
|
||||||
self._vbox.reorder_child(alert, 1)
|
self._vbox.reorder_child(alert, 1)
|
||||||
else:
|
else:
|
||||||
self._vbox.reorder_child(alert, 0)
|
self._vbox.reorder_child(alert, 0)
|
||||||
@ -165,7 +172,7 @@ class Window(gtk.Window):
|
|||||||
self._vbox.remove(alert)
|
self._vbox.remove(alert)
|
||||||
if len(self._alerts) >= 1:
|
if len(self._alerts) >= 1:
|
||||||
self._vbox.pack_start(self._alerts[0], False)
|
self._vbox.pack_start(self._alerts[0], False)
|
||||||
if self.toolbox is not None:
|
if self.__toolbar_box is not None:
|
||||||
self._vbox.reorder_child(self._alerts[0], 1)
|
self._vbox.reorder_child(self._alerts[0], 1)
|
||||||
else:
|
else:
|
||||||
self._vbox.reorder_child(self._alert[0], 0)
|
self._vbox.reorder_child(self._alert[0], 0)
|
||||||
@ -180,8 +187,8 @@ class Window(gtk.Window):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
|
if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
|
||||||
if self.toolbox is not None:
|
if self.__toolbar_box is not None:
|
||||||
self.toolbox.hide()
|
self.__toolbar_box.hide()
|
||||||
if self.tray is not None:
|
if self.tray is not None:
|
||||||
self.tray.hide()
|
self.tray.hide()
|
||||||
|
|
||||||
@ -199,8 +206,8 @@ class Window(gtk.Window):
|
|||||||
self.__unfullscreen_button_timeout_cb)
|
self.__unfullscreen_button_timeout_cb)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.toolbox is not None:
|
if self.__toolbar_box is not None:
|
||||||
self.toolbox.show()
|
self.__toolbar_box.show()
|
||||||
if self.tray is not None:
|
if self.tray is not None:
|
||||||
self.tray.show()
|
self.tray.show()
|
||||||
|
|
||||||
@ -258,3 +265,14 @@ class Window(gtk.Window):
|
|||||||
setter=set_enable_fullscreen_mode,
|
setter=set_enable_fullscreen_mode,
|
||||||
getter=get_enable_fullscreen_mode)
|
getter=get_enable_fullscreen_mode)
|
||||||
|
|
||||||
|
# DEPRECATED
|
||||||
|
|
||||||
|
def set_toolbox(self, toolbar_box):
|
||||||
|
warnings.warn('use toolbar_box instead of toolbox', DeprecationWarning)
|
||||||
|
self.set_toolbar_box(toolbar_box)
|
||||||
|
|
||||||
|
def get_toolbox(self):
|
||||||
|
warnings.warn('use toolbar_box instead of toolbox', DeprecationWarning)
|
||||||
|
return self.__toolbar_box
|
||||||
|
|
||||||
|
toolbox = property(get_toolbox, set_toolbox)
|
||||||
|
Loading…
Reference in New Issue
Block a user