From 63c93e4f2da2a5f8935835da876d118bdc99c495 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 07 Jul 2006 14:37:52 +0000 Subject: Rewrite the wm, implement smarter sliding, "merge" presence window and chat, activate by F1 --- (limited to 'shell') diff --git a/shell/ActivityContainer.py b/shell/ActivityContainer.py index 7b058e6..85c954a 100644 --- a/shell/ActivityContainer.py +++ b/shell/ActivityContainer.py @@ -72,30 +72,22 @@ class ActivityContainer(dbus.service.Object): self._presence_window = PresenceWindow(self) self._presence_window.set_transient_for(self.window) - self._presence_window.set_decorated(False) - self._presence_window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) - self._presence_window.set_skip_taskbar_hint(True) wm = WindowManager(self._presence_window) - - wm.set_width(170, WindowManager.ABSOLUTE) - wm.set_height(1.0, WindowManager.SCREEN_RELATIVE) - wm.set_position(WindowManager.LEFT) - wm.manage() + wm.set_type(WindowManager.TYPE_POPUP) + wm.set_animation(WindowManager.ANIMATION_SLIDE_IN) + wm.set_geometry(0.02, 0.1, 0.25, 0.9) + wm.set_key(gtk.keysyms.F1) self._chat_window = ChatWindow() self._chat_window.set_transient_for(self.window) - self._chat_window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) - self._chat_window.set_decorated(False) - self._chat_window.set_skip_taskbar_hint(True) self._chat_wm = WindowManager(self._chat_window) - - self._chat_wm.set_width(420, WindowManager.ABSOLUTE) - self._chat_wm.set_height(380, WindowManager.ABSOLUTE) - self._chat_wm.set_position(WindowManager.TOP) - self._chat_wm.manage() - + self._chat_wm.set_animation(WindowManager.ANIMATION_SLIDE_IN) + self._chat_wm.set_type(WindowManager.TYPE_POPUP) + self._chat_wm.set_geometry(0.28, 0.1, 0.5, 0.9) + self._chat_wm.set_key(gtk.keysyms.F1) + self._mesh_chat = MeshChat() def show(self): @@ -111,9 +103,6 @@ class ActivityContainer(dbus.service.Object): else: self._chat_window.set_chat(self._mesh_chat) - # For some reason the substitution screw up window position - self._chat_wm.update() - def notebook_tab_changed(self, notebook, page, page_number): new_activity = notebook.get_nth_page(page_number).get_data("sugar-activity") diff --git a/shell/ConsoleLogger.py b/shell/ConsoleLogger.py index 9065dbd..c9c968f 100644 --- a/shell/ConsoleLogger.py +++ b/shell/ConsoleLogger.py @@ -13,9 +13,6 @@ class ConsoleLogger(dbus.service.Object): self._window = gtk.Window() self._window.set_title("Console") - self._window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) - self._window.set_decorated(False) - self._window.set_skip_taskbar_hint(True) self._window.connect("delete_event", lambda w, e: w.hide_on_delete()) self._nb = gtk.Notebook() @@ -24,12 +21,9 @@ class ConsoleLogger(dbus.service.Object): self._consoles = {} - console_wm = WindowManager(self._window) - - console_wm.set_width(0.7, WindowManager.SCREEN_RELATIVE) - console_wm.set_height(0.9, WindowManager.SCREEN_RELATIVE) - console_wm.set_position(WindowManager.BOTTOM) - console_wm.manage() + console_wm = WindowManager(self._window) + console_wm.set_type(WindowManager.TYPE_POPUP) + console_wm.set_geometry(0.1, 0.1, 0.8, 0.8) def _create_console(self, application): sw = gtk.ScrolledWindow() diff --git a/shell/Shell.py b/shell/Shell.py index 6cdbff9..025ec80 100755 --- a/shell/Shell.py +++ b/shell/Shell.py @@ -29,11 +29,7 @@ class Shell(gobject.GObject): activity_container.show() wm = WindowManager(activity_container.window) - wm.set_width(640, WindowManager.ABSOLUTE) - wm.set_height(480, WindowManager.ABSOLUTE) - wm.set_position(WindowManager.CENTER) wm.show() - wm.manage() def __activity_container_destroy_cb(self, activity_container): self.emit('close') diff --git a/shell/WindowManager.py b/shell/WindowManager.py index 9fb8410..9856768 100644 --- a/shell/WindowManager.py +++ b/shell/WindowManager.py @@ -1,169 +1,204 @@ -import pygtk -pygtk.require('2.0') +import time +import logging + import gtk import gobject -SM_SPACE_PROPORTIONAL = 0 -SM_STEP = 1 +DEFAULT_WIDTH = 640 +DEFAULT_HEIGHT = 480 + +SLIDING_TIME = 0.8 + +class SlidingHelper: + IN = 0 + OUT = 1 + + def __init__(self, manager, direction): + self._direction = direction + self._cur_time = time.time() + self._target_time = self._cur_time + SLIDING_TIME + self._manager = manager + self._start = True + self._end = False + + (x, y, width, height) = manager.get_geometry() + self._orig_y = y + if direction == SlidingHelper.IN: + self._target_y = y + manager.set_geometry(x, y - height, width, height) + else: + self._target_y = y - height + + def get_direction(self): + return self._direction + + def is_start(self): + return self._start -SLIDING_TIMEOUT = 50 -SLIDING_MODE = SM_SPACE_PROPORTIONAL + def is_end(self): + return self._end -#SLIDING_TIMEOUT = 10 -#SLIDING_MODE = SM_STEP -#SLIDING_STEP = 0.05 + def get_next_y(self): + self._start = False + + (x, y, width, height) = self._manager.get_geometry() + + old_time = self._cur_time + self._cur_time = time.time() + remaining = self._target_time - self._cur_time + + if remaining <= 0: + self._end = True + y = self._orig_y + else: + approx_time_step = float(self._cur_time - old_time) + approx_n_steps = remaining / approx_time_step + step = (self._target_y - y) / approx_n_steps + y += step + + return y class WindowManager: __managers_list = [] - CENTER = 0 - LEFT = 1 - RIGHT = 2 - TOP = 3 - BOTTOM = 4 - - ABSOLUTE = 0 - SCREEN_RELATIVE = 1 - + TYPE_ACTIVITY = 0 + TYPE_POPUP = 1 + + ANIMATION_NONE = 0 + ANIMATION_SLIDE_IN = 1 + def __init__(self, window): self._window = window - self._sliding_pos = 0 + self._window_type = WindowManager.TYPE_ACTIVITY + self._animation = WindowManager.ANIMATION_NONE + self._key = 0 + self._animating = False - WindowManager.__managers_list.append(self) - window.connect("key-press-event", self.__key_press_event_cb) + WindowManager.__managers_list.append(self) + def __key_press_event_cb(self, window, event): - manager = None - - if event.keyval == gtk.keysyms.Left and \ - event.state & gtk.gdk.CONTROL_MASK: - for wm in WindowManager.__managers_list: - if wm._position == WindowManager.LEFT: - manager = wm - - if event.keyval == gtk.keysyms.Up and \ - event.state & gtk.gdk.CONTROL_MASK: - for wm in WindowManager.__managers_list: - if wm._position == WindowManager.TOP: - manager = wm - - if event.keyval == gtk.keysyms.Down and \ - event.state & gtk.gdk.CONTROL_MASK: - for wm in WindowManager.__managers_list: - if wm._position == WindowManager.BOTTOM: - manager = wm - - if manager and manager._window.get_property('visible'): - manager.slide_window_out() - elif manager: - manager.slide_window_in() + # FIXME we should fix this to work also while animating + if self._animating: + return False - def set_width(self, width, width_type): + for manager in WindowManager.__managers_list: + if event.keyval == manager._key: + if manager._window.get_property('visible'): + manager.hide() + else: + manager.show() + + def get_geometry(self): + return (self._x, self._y, self._width, self._height) + + def set_geometry(self, x, y, width, height): + if self._window_type == WindowManager.TYPE_ACTIVITY: + logging.error('The geometry will be ignored for activity windows') + + self._x = x + self._y = y self._width = width - self._width_type = width_type - - def set_height(self, height, height_type): self._height = height - self._height_type = height_type + + def set_animation(self, animation): + self._animation = animation - def set_position(self, position): - self._position = position + def set_type(self, window_type): + self._window_type = window_type - def _update_size(self): - screen_width = self._window.get_screen().get_width() - screen_height = self._window.get_screen().get_height() - - if self._width_type is WindowManager.ABSOLUTE: - width = self._width - elif self._width_type is WindowManager.SCREEN_RELATIVE: - width = int(screen_width * self._width) - - if self._height_type is WindowManager.ABSOLUTE: - height = self._height - elif self._height_type is WindowManager.SCREEN_RELATIVE: - height = int(screen_height * self._height) - - self._real_width = width - self._real_height = height - - self._window.set_size_request(self._real_width, - self._real_height) + def set_key(self, key): + self._key = key - def _update_position(self): - screen_width = self._window.get_screen().get_width() - screen_height = self._window.get_screen().get_height() + def show(self): + self._update_hints() + self._update_size() + + if self._animation == WindowManager.ANIMATION_SLIDE_IN: + self._slide_in() + else: + self._update_position() + self._window.show() + + def hide(self): + if self._animation == WindowManager.ANIMATION_SLIDE_IN: + self._slide_out() + else: + self._window.hide() + + def _get_screen_dimensions(self): + screen_width = DEFAULT_WIDTH + screen_height = DEFAULT_HEIGHT - width = self._real_width - height = self._real_height + for manager in WindowManager.__managers_list: + if manager._window_type == WindowManager.TYPE_ACTIVITY: + screen_width = manager._window.allocation.width + screen_height = manager._window.allocation.height - if self._position is WindowManager.CENTER: - self._x = int((screen_width - width) / 2) - self._y = int((screen_height - height) / 2) - elif self._position is WindowManager.LEFT: - self._x = - int((1.0 - self._sliding_pos) * width) - self._y = int((screen_height - height) / 2) - elif self._position is WindowManager.TOP: - self._x = int(screen_width - width - 10) - self._y = - int((1.0 - self._sliding_pos) * height) - elif self._position is WindowManager.BOTTOM: - self._x = int((screen_width - width) / 2) - self._y = screen_height - int(self._sliding_pos * height) - - self._window.move(self._x, self._y) + return (screen_width, screen_height) - def __slide_in_timeout_cb(self): - if self._sliding_pos == 0: - self._window.show() + def _get_screen_position(self): + result = (0, 0) + for manager in WindowManager.__managers_list: + if manager._window_type == WindowManager.TYPE_ACTIVITY: + result = manager._window.get_position() + + return result - if SLIDING_MODE == SM_SPACE_PROPORTIONAL: - space_to_go = 1.0 - self._sliding_pos - self._sliding_pos += (space_to_go / 2) - else: - self._sliding_pos += SLIDING_STEP + def _transform_position(self): + (screen_width, screen_height) = self._get_screen_dimensions() + (screen_x, screen_y) = self._get_screen_position() + + x = int(screen_width * self._x) + screen_x + y = int(screen_height * self._y) + screen_y + + return (x, y) - if self._sliding_pos > .999: - self._sliding_pos = 1.0 + def _transform_dimensions(self): + (screen_width, screen_height) = self._get_screen_dimensions() + + width = int(screen_width * self._width) + height = int(screen_height * self._height) + + return (width, height) - self._update_position() + def _update_hints(self): + if self._window_type == WindowManager.TYPE_POPUP: + self._window.set_decorated(False) + self._window.set_skip_taskbar_hint(True) - if self._sliding_pos == 1.0: - return False + def _update_size(self): + if self._window_type == WindowManager.TYPE_ACTIVITY: + self._window.resize(DEFAULT_WIDTH, DEFAULT_HEIGHT) else: - return True + (width, height) = self._transform_dimensions() + self._window.resize(width, height) - def __slide_out_timeout_cb(self): - if SLIDING_MODE == SM_SPACE_PROPORTIONAL: - space_to_go = self._sliding_pos - self._sliding_pos -= (space_to_go / 2) - else: - self._sliding_pos -= SLIDING_STEP + def _update_position(self): + if self._window_type == WindowManager.TYPE_POPUP: + (x, y) = self._transform_position() + self._window.move(x, y) - if self._sliding_pos < .001: - self._sliding_pos = 0 + def __slide_timeout_cb(self, helper): + start = helper.is_start() + self._y = helper.get_next_y() self._update_position() - - if self._sliding_pos == 0: + + if start and helper.get_direction() == SlidingHelper.IN: + self._window.show() + elif helper.is_end() and helper.get_direction() == SlidingHelper.OUT: self._window.hide() - return False - else: - return True - def slide_window_in(self): - self._sliding_pos = 0 - gobject.timeout_add(SLIDING_TIMEOUT, self.__slide_in_timeout_cb) - - def slide_window_out(self): - self._sliding_pos = 1.0 - gobject.timeout_add(SLIDING_TIMEOUT, self.__slide_out_timeout_cb) - - def show(self): - self._window.show() + self._animating = not helper.is_end() + + return not helper.is_end() - def update(self): - self._update_position() - - def manage(self): - self._update_size() - self._update_position() + def _slide_in(self): + helper = SlidingHelper(self, SlidingHelper.IN) + gobject.idle_add(self.__slide_timeout_cb, helper) + + def _slide_out(self): + helper = SlidingHelper(self, SlidingHelper.OUT) + gobject.idle_add(self.__slide_timeout_cb, helper) -- cgit v0.9.1