Skip to content
Browse files

First animations and tweaks

Change-Id: I746beb50c7105f5307206c76fcbaf75d7cef9be8
  • Loading branch information...
1 parent 506d34d commit 70fedce7acae41a8ae48b88d712c27cb4da137f4 @tomasz-wiszkowski committed Jan 14, 2013
Showing with 157 additions and 6 deletions.
  1. +84 −0 src/elements/animation.py
  2. +12 −0 src/elements/xfcon_settings.py
  3. +46 −6 src/elements/xfcon_window.py
  4. +15 −0 src/plugins/preferences/view.py
View
84 src/elements/animation.py
@@ -0,0 +1,84 @@
+#
+# Copyright 2012 Tomasz Wiszkowski
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import gobject
+
+class Animation(object):
+ def __init__(self, steps, start, end, interpolator, callback):
+ super(Animation, self).__init__()
+ self.step = 0
+ self.steps = steps
+ self.start_value = start
+ self.end_value = end
+ self.interpolator = interpolator
+ self.callback = callback
+ self.timer = None
+
+ def __del__(self):
+ self.stop()
+
+ def start(self):
+ if (self.timer):
+ return
+ self.timer = gobject.timeout_add(16, self.__on_timer)
+
+ def stop(self):
+ if (self.timer):
+ gobject.source_remove(self.timer)
+ self.timer = None
+
+ def __on_timer(self):
+ self.timer = None
+ progress = 1.0 * self.step / self.steps
+ value = self.interpolator(progress)
+ value = self.start_value + value * (self.end_value - self.start_value)
+ self.callback(value, progress)
+ if (self.step < self.steps):
+ self.step += 1
+ # re-arm timer
+ self.start()
+
+ @classmethod
+ def LinearInterpolator(cls, value):
+ return value
+
+ @classmethod
+ def CubicInterpolator(cls, value):
+ return value ** 3
+
+ @classmethod
+ def QuadraticEaseInOutInterpolator(cls, value):
+ value *= 2
+ if (value < 1.0):
+ return 0.5 * value ** 2
+ else:
+ return 1.0 - 0.5 * (2.0 - value) ** 2
+
+ @classmethod
+ def CubicEaseInOutInterpolator(cls, value):
+ value *= 2
+ if (value < 1.0):
+ return 0.5 * value ** 3
+ else:
+ return 1.0 - 0.5 * (2.0 - value) ** 3
+
+ @classmethod
+ def QuadEaseInOutInterpolator(cls, value):
+ value *= 2
+ if (value < 1.0):
+ return 0.5 * value ** 4
+ else:
+ return 1.0 - 0.5 * (2.0 - value) ** 4
+
View
12 src/elements/xfcon_settings.py
@@ -113,6 +113,12 @@ class XfConSettings(gobject.GObject):
_("Percentage of screen occupied by window."),
20, 100, 80,
gobject.PARAM_READWRITE),
+
+ 'window-animations': (gobject.TYPE_BOOLEAN,
+ _("Window animations."),
+ _("Tick to enable window animations."),
+ False,
+ gobject.PARAM_READWRITE),
}
__properties__ = {}
@@ -145,6 +151,12 @@ def set_window_follows_mouse(self, status):
def get_window_follows_mouse(self):
return self.get_property("window-follows-mouse")
+ def set_window_animations(self, status):
+ self.set_property("window-animations", status)
+
+ def get_window_animations(self):
+ return self.get_property("window-animations")
+
def set_window_width(self, value):
self.set_property("window-width", int(value))
View
52 src/elements/xfcon_window.py
@@ -13,13 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import gobject
import gtk
import os
import pygtk
import pynotify
from Xlib import display
+from elements.animation import Animation
from elements.xfcon_dialogs import XfConDialog
from elements.xfcon_globals import PLUGINS_DIR, APPNAME
from elements.xfcon_notebook import XfConNotebook
@@ -39,10 +41,11 @@ def __init__(self):
self.activate()
self.set_decorated(False)
self.set_gravity(gtk.gdk.GRAVITY_STATIC)
- self.set_keep_above(True)
self.set_skip_pager_hint(True)
self.set_skip_taskbar_hint(True)
self.set_title(APPNAME)
+ self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
+ self.set_keep_above(True)
self.set_urgency_hint(True)
self.set_resizable(False)
self.add_accel_group(XfConKeyBinder.create())
@@ -67,6 +70,8 @@ def __init__(self):
self.connect('set-focus', self.__on_focus_move)
self.last_focus = None
+ self.expose_animation = None
+ self.expose_step = 0.0
self.__import_plugins();
self.__bind_config()
@@ -117,14 +122,16 @@ def __bind_keys(self):
def __apply_config(self):
self.__config_set_window_size()
- def __config_set_window_size(self, *ignore):
- rect = self.__calculate_window_size()
+ def __set_window_size(self, rect):
self.set_geometry_hints(self,
min_width = rect.width, min_height = rect.height,
max_width = rect.width, max_height = rect.height,
base_width = rect.width, base_height = rect.height)
self.move(rect.x, rect.y)
+ def __config_set_window_size(self, *ignore):
+ self.__set_window_size(self.__calculate_window_size())
+
def __on_tab_add(self, *ignore):
return self.__do_create_default_view()
@@ -199,12 +206,45 @@ def __calculate_window_size(self):
return rect
def __on_accel_show_hide(self, *args):
- if not self.get_property('visible'):
- self.show()
+ # Cancel pending timers.
+ if self.expose_animation:
+ self.expose_animation.stop()
+ self.expose_animation = None
+
+ if not self.get_visible():
+ if self.settings.get_window_animations():
+ self.expose_animation = \
+ Animation(30, self.expose_step, 1.0, \
+ Animation.QuadEaseInOutInterpolator, \
+ self.__expose_animation_callback)
+ self.expose_animation.start()
+ else:
+ self.__config_set_window_size()
+ self.expose_step = 1.0
+ self.show()
else:
- self.hide()
+ if self.settings.get_window_animations():
+ self.expose_animation = \
+ Animation(30, self.expose_step, 0.0, \
+ Animation.QuadEaseInOutInterpolator, \
+ self.__expose_animation_callback)
+ self.expose_animation.start()
+ else:
+ self.expose_step = 0.0
+ self.hide()
return True
+ def __expose_animation_callback(self, value, progress):
+ self.expose_step = value
+ rect = self.__calculate_window_size()
+ rect.y -= int((1.0 - value) * rect.height)
+
+ self.__set_window_size(rect)
+ if value == 0.0:
+ self.hide()
+ elif not self.get_visible():
+ self.show()
+
def __on_accel_quit(self, *args):
wants_quit = XfConDialog.question_yes_no(
_("Are you sure to quit?"),
View
15 src/plugins/preferences/view.py
@@ -42,6 +42,15 @@ def __create_screen_settings(self):
follow_mouse_label.set_alignment(0.0, 0.5)
follow_mouse_label.show()
+ # Animate window open / close
+ animate_window = gtk.CheckButton()
+ animate_window.set_active(self.settings.get_window_animations())
+ animate_window.connect("toggled", self.__change_window_animations)
+ animate_window.show()
+ animate_window_label = gtk.Label(_("Animate window"))
+ animate_window_label.set_alignment(0.0, 0.5)
+ animate_window_label.show()
+
# Width of the window
window_width = gtk.SpinButton()
window_width.set_range(20, 100)
@@ -73,6 +82,9 @@ def __create_screen_settings(self):
container.attach(follow_mouse, 0, 1, row, row + 1, 0, 0)
container.attach(follow_mouse_label, 1, 2, row, row + 1)
row += 1
+ container.attach(animate_window, 0, 1, row, row + 1, 0, 0)
+ container.attach(animate_window_label, 1, 2, row, row + 1)
+ row += 1
container.attach(window_width, 0, 1, row, row + 1, 0, 0)
container.attach(window_width_label, 1, 2, row, row + 1)
row += 1
@@ -89,6 +101,9 @@ def __create_screen_settings(self):
def __change_follow_mouse(self, box, *args):
self.settings.set_window_follows_mouse(box.get_active())
+ def __change_window_animations(self, box, *args):
+ self.settings.set_window_animations(box.get_active())
+
def __change_window_width(self, spinner, *args):
self.settings.set_window_width(spinner.get_value())

0 comments on commit 70fedce

Please sign in to comment.
Something went wrong with that request. Please try again.