Package dtk :: Package ui :: Module osd_tooltip

Source Code for Module dtk.ui.osd_tooltip

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # Copyright (C) 2011 ~ 2012 Deepin, Inc. 
  5  #               2011 ~ 2012 Wang Yong 
  6  #  
  7  # Author:     Wang Yong <lazycat.manatee@gmail.com> 
  8  # Maintainer: Wang Yong <lazycat.manatee@gmail.com> 
  9  #  
 10  # This program is free software: you can redistribute it and/or modify 
 11  # it under the terms of the GNU General Public License as published by 
 12  # the Free Software Foundation, either version 3 of the License, or 
 13  # any later version. 
 14  #  
 15  # This program is distributed in the hope that it will be useful, 
 16  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 18  # GNU General Public License for more details. 
 19  #  
 20  # You should have received a copy of the GNU General Public License 
 21  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 22   
 23  from animation import Animation 
 24  from constant import DEFAULT_FONT 
 25  from draw import draw_text 
 26  from theme import ui_theme 
 27  import cairo 
 28  import gobject 
 29  import gtk 
 30  from utils import (remove_signal_id, remove_timeout_id, get_content_size) 
 31   
32 -class OSDTooltip(gtk.Window):
33 ''' 34 OSD tooltip. 35 36 @undocumented: realize_osd_tooltip 37 @undocumented: show_osd_tooltip 38 @undocumented: expose_osd_tooltip 39 @undocumented: handle_configure_event 40 ''' 41
42 - def __init__(self, 43 monitor_widget, 44 text_font=DEFAULT_FONT, 45 text_size=18, 46 offset_x=0, 47 offset_y=0, 48 text_color=ui_theme.get_color("osd_tooltip_text"), 49 border_color=ui_theme.get_color("osd_tooltip_border"), 50 border_radious=1):
51 ''' 52 Initialize OSDTooltip class. 53 54 @param monitor_widget: Widget to monitor event. 55 @param text_font: Text font, default is DEFAULT_FONT. 56 @param text_size: Text size, default is 18. 57 @param offset_x: Offset X coordinate relative to monitor widget. 58 @param offset_y: Offset Y coordinate relative to monitor widget. 59 @param text_color: Text color. 60 @param border_color: Border color. 61 @param border_radious: Border radious. 62 ''' 63 # Init. 64 gtk.Window.__init__(self, gtk.WINDOW_POPUP) 65 self.monitor_widget = monitor_widget 66 self.text = "" 67 self.text_size = text_size 68 self.text_font = text_font 69 self.offset_x = offset_x 70 self.offset_y = offset_y 71 self.text_color = text_color 72 self.border_color = border_color 73 self.border_radious = border_radious 74 self.monitor_window = None 75 self.monitor_window_x = None 76 self.monitor_window_y = None 77 self.monitor_window_width = None 78 self.monitor_window_height = None 79 self.start_hide_delay = 5000 # milliseconds 80 self.hide_time = 500 # milliseconds 81 82 # Init callback id. 83 self.configure_event_callback_id = None 84 self.destroy_callback_id = None 85 self.start_hide_callback_id = None 86 self.focus_out_callback_id = None 87 88 # Init window. 89 self.set_decorated(False) 90 self.set_skip_taskbar_hint(True) 91 self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) # keeep above 92 self.set_colormap(gtk.gdk.Screen().get_rgba_colormap()) 93 self.add_events(gtk.gdk.ALL_EVENTS_MASK) 94 self.set_accept_focus(False) # make Alt+Space menu can't response 95 96 # Connect signal. 97 self.connect("expose-event", self.expose_osd_tooltip) 98 self.connect("realize", self.realize_osd_tooltip) 99 self.connect("show", self.show_osd_tooltip)
100
101 - def realize_osd_tooltip(self, widget):
102 ''' 103 Internal function to realize OSD tooltip. 104 105 @param widget: OSDTooltip widget. 106 ''' 107 # Make all event passthrough osd tooltip. 108 self.window.input_shape_combine_region(gtk.gdk.Region(), 0, 0) 109 110 # Avoid osd tooltip (popup window) show at (0, 0) first. 111 self.move(-1000000, -1000000) 112 113 # Never draw background. 114 self.window.set_back_pixmap(None, False)
115
116 - def show_osd_tooltip(self, widget):
117 ''' 118 Internal function to show osd tooltip. 119 120 @param widget: OSD tooltip widget. 121 ''' 122 self.move(self.tooltip_x, self.tooltip_y) 123 self.resize(self.tooltip_width, self.tooltip_height)
124
125 - def expose_osd_tooltip(self, widget, event):
126 ''' 127 Internal function to expose osd tooltip. 128 129 @param widget: OSD tooltip widget. 130 @param event: Expose event. 131 ''' 132 # Update window size. 133 self.move(self.tooltip_x, self.tooltip_y) 134 self.resize(self.tooltip_width, self.tooltip_height) 135 136 # Init. 137 cr = widget.window.cairo_create() 138 rect = widget.allocation 139 140 # Clear color to transparent window. 141 cr.set_source_rgba(0.0, 0.0, 0.0, 0.0) 142 cr.set_operator(cairo.OPERATOR_SOURCE) 143 cr.paint() 144 145 # Draw font. 146 draw_text(cr, self.text, 147 rect.x, rect.y, rect.width, rect.height, 148 self.text_size, 149 self.text_color.get_color(), 150 border_radious=self.border_radious, 151 border_color=self.border_color.get_color()) 152 153 return True
154
155 - def show(self, text):
156 ''' 157 Show. 158 159 @param text: OSD tooltip text. 160 ''' 161 # Remove callback.j 162 remove_signal_id(self.configure_event_callback_id) 163 remove_signal_id(self.destroy_callback_id) 164 remove_signal_id(self.focus_out_callback_id) 165 remove_timeout_id(self.start_hide_callback_id) 166 167 # Update text. 168 self.text = text 169 170 # Get tooltip size. 171 (tooltip_width, tooltip_height) = get_content_size( 172 self.text, 173 self.text_size + self.border_radious * 2, 174 self.text_font) 175 self.tooltip_width = tooltip_width * 2 176 self.tooltip_height = tooltip_height 177 178 # Move tooltip to given position. 179 (monitor_x, monitor_y) = self.monitor_widget.window.get_origin() 180 self.tooltip_x = monitor_x + self.offset_x 181 self.tooltip_y = monitor_y + self.offset_y 182 183 # Monitor configure-event signal. 184 self.monitor_window = self.monitor_widget.get_toplevel() 185 configure_event_handler_id = self.monitor_window.connect("configure-event", self.handle_configure_event) 186 self.configure_event_callback_id = (self.monitor_window, configure_event_handler_id) 187 destroy_handler_id = self.monitor_window.connect("destroy", lambda w: self.hide_immediately()) 188 self.destroy_callback_id = (self.monitor_window, destroy_handler_id) 189 focus_out_handler_id = self.monitor_window.connect("focus-out-event", lambda w, e: self.hide_immediately()) 190 self.focus_out_callback_id = (self.monitor_window, focus_out_handler_id) 191 192 # Save monitor window position. 193 rect = self.monitor_window.allocation 194 (monitor_window_x, monitor_window_y) = self.monitor_window.window.get_origin() 195 monitor_window_width, monitor_window_height = rect.width, rect.height 196 self.monitor_window_x = monitor_window_x 197 self.monitor_window_y = monitor_window_y 198 self.monitor_window_width = monitor_window_width 199 self.monitor_window_height = monitor_window_height 200 201 # Show. 202 self.set_opacity(1) 203 self.show_all() 204 205 self.start_hide_callback_id = gobject.timeout_add( 206 self.start_hide_delay, 207 lambda : Animation(self, "opacity", self.hide_time, [1, 0], 208 stop_callback=self.hide_immediately).start()) 209 210 self.queue_draw() # make sure redraw
211
212 - def hide_immediately(self):
213 ''' 214 Hide immediately. 215 ''' 216 # Remove callback. 217 remove_signal_id(self.configure_event_callback_id) 218 remove_signal_id(self.destroy_callback_id) 219 remove_signal_id(self.focus_out_callback_id) 220 remove_timeout_id(self.start_hide_callback_id) 221 222 self.hide_all()
223
224 - def handle_configure_event(self, widget, event):
225 ''' 226 Internal function to handle configure event. 227 ''' 228 # Init. 229 rect = widget.allocation 230 (monitor_window_x, monitor_window_y) = widget.window.get_origin() 231 monitor_window_width, monitor_window_height = rect.width, rect.height 232 233 if (self.monitor_window_x != monitor_window_x 234 or self.monitor_window_y != monitor_window_y 235 or self.monitor_window_width != monitor_window_width 236 or self.monitor_window_height != monitor_window_height): 237 238 self.monitor_window_x = monitor_window_x 239 self.monitor_window_y = monitor_window_y 240 self.monitor_window_width = monitor_window_width 241 self.monitor_window_height = monitor_window_height 242 243 self.hide_immediately()
244
245 - def change_style(self, text_font, text_size):
246 ''' 247 Change OSD tooltip style. 248 249 @param text_font: OSD tooltip text font. 250 @param text_size: OSD tooltip text size. 251 ''' 252 self.text_font = text_font 253 self.text_size = text_size 254 255 self.queue_draw()
256 257 gobject.type_register(OSDTooltip) 258