1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from button import Button
24 from constant import ALIGN_MIDDLE
25 from draw import draw_vlinear, draw_blank_mask
26 from entry import InputEntry
27 from label import Label
28 from locales import _
29 from mask import draw_mask
30 from skin_config import skin_config
31 from theme import ui_theme
32 from titlebar import Titlebar
33 from utils import container_remove_all
34 from window import Window
35 import gobject
36 import gtk
37
38 DIALOG_MASK_SINGLE_PAGE = 0
39 DIALOG_MASK_GLASS_PAGE = 1
40 DIALOG_MASK_MULTIPLE_PAGE = 2
41 DIALOG_MASK_TAB_PAGE = 3
42
72
73 gobject.type_register(DialogLeftButtonBox)
74
104
105 gobject.type_register(DialogRightButtonBox)
106
108 '''
109 Dialog box to standard dialog layout and ui detail.
110
111 If you want build a dialog, you should use this standard.
112
113 @undocumented: draw_mask_single_page
114 @undocumented: draw_mask_glass_page
115 @undocumented: draw_mask_multiple_page
116 @undocumented: draw_mask_tab_page
117 '''
118
119 - def __init__(self,
120 title,
121 default_width=None,
122 default_height=None,
123 mask_type=None,
124 close_callback=None,
125 modal=True,
126 window_hint=gtk.gdk.WINDOW_TYPE_HINT_DIALOG,
127 window_pos=None,
128 skip_taskbar_hint=True,
129 resizable=False):
130 '''
131 Initialize DialogBox class.
132
133 @param title: Dialog title.
134 @param default_width: Width of dialog, default is None.
135 @param default_height: Height of dialog, default is None.
136 @param mask_type: Background mask type, it allow use below type:
137 - DIALOG_MASK_SINGLE_PAGE single mask style, use in single page that background mask include dialog button area.
138 - DIALOG_MASK_GLASS_PAGE glass mask style, similar DIALOG_MASK_SINGLE_PAGE but with different color.
139 - DIALOG_MASK_MULTIPLE_PAGE multiple mask style, use in multiple page that background mask not include dialog button area.
140 - DIALOG_MASK_TAB_PAGE tab mask style, use in preference page that background mask not include button area.
141 '''
142 Window.__init__(self, resizable)
143 self.default_width = default_width
144 self.default_height = default_height
145 self.mask_type = mask_type
146
147 if window_pos:
148 self.set_position(window_pos)
149 self.set_modal(modal)
150 if window_hint:
151 self.set_type_hint(window_hint)
152 self.set_skip_taskbar_hint(skip_taskbar_hint)
153 if self.default_width != None and self.default_height != None:
154 self.set_default_size(self.default_width, self.default_height)
155
156 if not resizable:
157 self.set_geometry_hints(None, self.default_width, self.default_height, -1, -1, -1, -1, -1, -1, -1, -1)
158
159 self.padding_left = 2
160 self.padding_right = 2
161
162 self.titlebar = Titlebar(
163 ["close"],
164 None,
165 title)
166 self.add_move_event(self.titlebar)
167 self.body_box = gtk.VBox()
168 self.body_align = gtk.Alignment()
169 self.body_align.set(0.5, 0.5, 1, 1)
170 self.body_align.set_padding(0, 0, self.padding_left, self.padding_right)
171 self.body_align.add(self.body_box)
172 self.button_box = gtk.HBox()
173 self.left_button_box = DialogLeftButtonBox()
174 self.right_button_box = DialogRightButtonBox()
175
176 self.button_box.pack_start(self.left_button_box, True, True)
177 self.button_box.pack_start(self.right_button_box, True, True)
178
179 self.window_frame.pack_start(self.titlebar, False, False)
180 self.window_frame.pack_start(self.body_align, True, True)
181 self.window_frame.pack_start(self.button_box, False, False)
182
183 if close_callback:
184 self.titlebar.close_button.connect("clicked", lambda w: close_callback())
185 self.connect("destroy", lambda w: close_callback())
186 else:
187 self.titlebar.close_button.connect("clicked", lambda w: self.destroy())
188 self.connect("destroy", lambda w: self.destroy())
189
190 self.draw_mask = self.get_mask_func(self, 1, 1, 0, 1)
191
192 - def get_mask_func(self, widget, padding_left=0, padding_right=0, padding_top=0, padding_bottom=0):
193 '''
194 Get mask function to render background, you can use this function to return \"render function\" to draw your ui to keep same style.
195
196 @param widget: DialogBox widget.
197 @param padding_left: Padding at left side.
198 @param padding_right: Padding at right side.
199 @param padding_top: Padding at top side.
200 @param padding_bottom: Padding at bottom side.
201 '''
202 if self.mask_type == DIALOG_MASK_SINGLE_PAGE:
203 return lambda cr, x, y, w, h: draw_mask(
204 widget, x + padding_left,
205 y + padding_top,
206 w - padding_left - padding_right,
207 h - padding_top - padding_bottom,
208 self.draw_mask_single_page)
209 elif self.mask_type == DIALOG_MASK_GLASS_PAGE:
210 return lambda cr, x, y, w, h: draw_mask(
211 widget, x + padding_left,
212 y + padding_top,
213 w - padding_left - padding_right,
214 h - padding_top - padding_bottom,
215 self.draw_mask_glass_page)
216 elif self.mask_type == DIALOG_MASK_MULTIPLE_PAGE:
217 return lambda cr, x, y, w, h: draw_mask(
218 widget, x + padding_left,
219 y + padding_top,
220 w - padding_left - padding_right,
221 h - padding_top - padding_bottom,
222 self.draw_mask_multiple_page)
223 elif self.mask_type == DIALOG_MASK_TAB_PAGE:
224 return lambda cr, x, y, w, h: draw_mask(
225 widget, x + padding_left,
226 y + padding_top,
227 w - padding_left - padding_right,
228 h - padding_top - padding_bottom,
229 self.draw_mask_tab_page)
230 else:
231 return lambda cr, x, y, w, h: draw_mask(
232 widget, x + padding_left,
233 y + padding_top,
234 w - padding_left - padding_right,
235 h - padding_top - padding_bottom,
236 draw_blank_mask)
237
238 - def draw_mask_single_page(self, cr, x, y, w, h):
239 '''
240 Internal render function for DIALOG_MASK_SINGLE_PAGE type.
241
242 @param cr: Cairo context.
243 @param x: X coordiante of draw area.
244 @param y: Y coordiante of draw area.
245 @param w: Width of draw area.
246 @param h: Height of draw area.
247 '''
248 top_height = 70
249
250 draw_vlinear(
251 cr, x, y, w, top_height,
252 ui_theme.get_shadow_color("mask_single_page_top").get_color_info(),
253 )
254
255 draw_vlinear(
256 cr, x, y + top_height, w, h - top_height,
257 ui_theme.get_shadow_color("mask_single_page_bottom").get_color_info(),
258 )
259
260 - def draw_mask_glass_page(self, cr, x, y, w, h):
261 '''
262 Internal render function for DIALOG_MASK_GLASS_PAGE type.
263
264 @param cr: Cairo context.
265 @param x: X coordiante of draw area.
266 @param y: Y coordiante of draw area.
267 @param w: Width of draw area.
268 @param h: Height of draw area.
269 '''
270 top_height = 70
271
272 draw_vlinear(
273 cr, x, y, w, top_height,
274 ui_theme.get_shadow_color("mask_glass_page_top").get_color_info(),
275 )
276
277 draw_vlinear(
278 cr, x, y + top_height, w, h - top_height,
279 ui_theme.get_shadow_color("mask_glass_page_bottom").get_color_info(),
280 )
281
282 - def draw_mask_multiple_page(self, cr, x, y, w, h):
283 '''
284 Internal render function for DIALOG_MASK_MULTIPLE_PAGE type.
285
286 @param cr: Cairo context.
287 @param x: X coordiante of draw area.
288 @param y: Y coordiante of draw area.
289 @param w: Width of draw area.
290 @param h: Height of draw area.
291 '''
292 titlebar_height = self.titlebar.get_allocation().height
293 button_box_height = self.right_button_box.get_allocation().height
294 dominant_color = skin_config.dominant_color
295
296 draw_vlinear(
297 cr, x, y + titlebar_height, w, h - titlebar_height,
298 ui_theme.get_shadow_color("mask_single_page_bottom").get_color_info(),
299 )
300
301 draw_vlinear(
302 cr, x, y + h - button_box_height, w, button_box_height,
303 [(0, (dominant_color, 1.0)),
304 (1, (dominant_color, 1.0))])
305
306 draw_vlinear(
307 cr, x, y + h - button_box_height, w, button_box_height,
308 ui_theme.get_shadow_color("mask_multiple_page").get_color_info(),
309 )
310
311 - def draw_mask_tab_page(self, cr, x, y, w, h):
312 '''
313 Internal render function for DIALOG_MASK_TAB_PAGE type.
314
315 @param cr: Cairo context.
316 @param x: X coordiante of draw area.
317 @param y: Y coordiante of draw area.
318 @param w: Width of draw area.
319 @param h: Height of draw area.
320 '''
321 button_box_height = self.right_button_box.get_allocation().height
322 dominant_color = skin_config.dominant_color
323
324 draw_vlinear(
325 cr, x, y + h - button_box_height, w, button_box_height,
326 [(0, (dominant_color, 1.0)),
327 (1, (dominant_color, 1.0))])
328
329 draw_vlinear(
330 cr, x, y + h - button_box_height, w, button_box_height,
331 ui_theme.get_shadow_color("mask_multiple_page").get_color_info(),
332 )
333
334 gobject.type_register(DialogBox)
335
337 '''
338 Simple message confirm dialog.
339
340 @undocumented: click_confirm_button
341 @undocumented: click_cancel_button
342 '''
343
344 - def __init__(self,
345 title,
346 message,
347 default_width=330,
348 default_height=145,
349 confirm_callback=None,
350 cancel_callback=None):
351 '''
352 Initialize ConfirmDialog class.
353
354 @param title: Title for confirm dialog.
355 @param message: Confirm message.
356 @param default_width: Dialog width, default is 330 pixel.
357 @param default_height: Dialog height, default is 145 pixel.
358 @param confirm_callback: Callback when user click confirm button.
359 @param cancel_callback: Callback when user click cancel button.
360 '''
361
362 DialogBox.__init__(self, title, default_width, default_height, DIALOG_MASK_SINGLE_PAGE)
363 self.confirm_callback = confirm_callback
364 self.cancel_callback = cancel_callback
365
366 self.label_align = gtk.Alignment()
367 self.label_align.set(0.5, 0.5, 0, 0)
368 self.label_align.set_padding(0, 0, 8, 8)
369 self.label = Label(message, text_x_align=ALIGN_MIDDLE, text_size=11)
370
371 self.confirm_button = Button(_("OK"))
372 self.cancel_button = Button(_("Cancel"))
373
374 self.confirm_button.connect("clicked", lambda w: self.click_confirm_button())
375 self.cancel_button.connect("clicked", lambda w: self.click_cancel_button())
376
377
378 self.body_box.pack_start(self.label_align, True, True)
379 self.label_align.add(self.label)
380
381 self.right_button_box.set_buttons([self.confirm_button, self.cancel_button])
382
391
400
401 gobject.type_register(ConfirmDialog)
402
477
478 gobject.type_register(InputDialog)
479
481 '''
482 Simple dialog to open file.
483 '''
484
485 - def __init__(self, title, parent, ok_callback=None, cancel_callback=None):
486 '''
487 Initialize OpenFileDialog class.
488
489 @param title: Dialog title.
490 @param parent: Parent widget to call open file dialog.
491 @param ok_callback: Callback when user click ok button, this function accept one argument: filename.
492 @param cancel_callback: Callback when user click cancel button, this function accept one argument: filename.
493 '''
494 gtk.FileChooserDialog.__init__(
495 self,
496 title,
497 parent,
498 gtk.FILE_CHOOSER_ACTION_OPEN,
499 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
500 gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT))
501 self.set_default_response(gtk.RESPONSE_ACCEPT)
502 self.set_position(gtk.WIN_POS_CENTER)
503 self.set_local_only(True)
504 response = self.run()
505 filename = self.get_filename()
506 if response == gtk.RESPONSE_ACCEPT:
507 if ok_callback != None:
508 ok_callback(filename)
509 elif response == gtk.RESPONSE_REJECT:
510 if cancel_callback != None:
511 cancel_callback(filename)
512 self.destroy()
513
514 gobject.type_register(OpenFileDialog)
515
517 '''
518 Simple dialog to save file.
519 '''
520
521 - def __init__(self, title, parent, ok_callback=None, cancel_callback=None):
522 '''
523 Initialize SaveFileDialog class.
524
525 @param title: Dialog title.
526 @param parent: Parent widget to call open file dialog.
527 @param ok_callback: Callback when user click ok button, this function accept one argument: filename.
528 @param cancel_callback: Callback when user click cancel button, this function accept one argument: filename.
529 '''
530 gtk.FileChooserDialog.__init__(
531 self,
532 title,
533 parent,
534 gtk.FILE_CHOOSER_ACTION_SAVE,
535 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
536 gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
537 self.set_default_response(gtk.RESPONSE_ACCEPT)
538 self.set_position(gtk.WIN_POS_CENTER)
539 self.set_local_only(True)
540 response = self.run()
541 filename = self.get_filename()
542 if response == gtk.RESPONSE_ACCEPT:
543 if ok_callback != None:
544 ok_callback(filename)
545 elif response == gtk.RESPONSE_REJECT:
546 if cancel_callback != None:
547 cancel_callback(filename)
548 self.destroy()
549
550 gobject.type_register(SaveFileDialog)
551
552
553 if __name__ == '__main__':
554 dialog = ConfirmDialog("确认对话框", "你确定吗?", 200, 100)
555 dialog.show_all()
556
557 gtk.main()
558