1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from constant import DEFAULT_FONT_SIZE, ALIGN_START, DEFAULT_FONT
24 from draw import draw_text, draw_hlinear
25 from keymap import get_keyevent_name
26 from theme import ui_theme
27 from utils import propagate_expose, get_content_size, is_double_click, is_left_button
28 import gtk
29 import pango
30 import pangocairo
31
32 -class Label(gtk.EventBox):
33 '''
34 Label.
35
36 @undocumented: button_press_label
37 @undocumented: button_release_label
38 @undocumented: motion_notify_label
39 @undocumented: key_press_label
40 @undocumented: focus_out_label
41 @undocumented: get_index_at_event
42 @undocumented: get_content_width
43 @undocumented: expose_label
44 @undocumented: draw_label_background
45 @undocumented: draw_label_text
46 @undocumented: update_size
47 '''
48
49 - def __init__(self,
50 text,
51 text_color=None,
52 text_size=DEFAULT_FONT_SIZE,
53 text_x_align=ALIGN_START,
54 label_width=None,
55 enable_gaussian=False,
56 enable_select=True,
57 enable_double_click=True,
58 gaussian_radious=2,
59 border_radious=1,
60 wrap_width=None,
61 ):
62 '''
63 Initialize Label class.
64
65 @param text: Label text.
66 @param text_color: Label text color, default is None.
67 @param text_size: Label text size, default is DEFAULT_FONT_SIZE.
68 @param text_x_align: Horizontal align option, default is ALIGN_START.
69 @param label_width: Label maximum width, default is None.
70 @param enable_gaussian: Default is False, if it is True, color option no effect, default gaussian effect is white text and black shadow.
71 @param enable_select: Default is True, label content can't select if it is False.
72 @param gaussian_radious: Radious of gaussian.
73 @param border_radious: Radious of border.
74 @param wrap_width: Wrap width.
75 '''
76
77 gtk.EventBox.__init__(self)
78 self.set_visible_window(False)
79 self.set_can_focus(True)
80 self.label_width = label_width
81 self.enable_gaussian = enable_gaussian
82 self.enable_select = enable_select
83 self.enable_double_click = enable_double_click
84 self.select_start_index = self.select_end_index = 0
85 self.double_click_flag = False
86 self.left_click_flag = False
87 self.left_click_coordindate = None
88 self.drag_start_index = 0
89 self.drag_end_index = 0
90 self.wrap_width = wrap_width
91
92 self.text = text
93 self.text_size = text_size
94 if text_color == None:
95 self.text_color = ui_theme.get_color("label_text")
96 else:
97 self.text_color = text_color
98 self.text_select_color = ui_theme.get_color("label_select_text")
99 self.text_select_background = ui_theme.get_color("label_select_background")
100
101 if self.enable_gaussian:
102 self.gaussian_radious = gaussian_radious
103 self.border_radious = border_radious
104 self.gaussian_color="#000000"
105 self.border_color="#000000"
106 else:
107 self.gaussian_radious=None
108 self.border_radious=None
109 self.gaussian_color=None
110 self.border_color=None
111
112 self.text_x_align = text_x_align
113
114 self.update_size()
115
116 self.connect("expose-event", self.expose_label)
117 self.connect("button-press-event", self.button_press_label)
118 self.connect("button-release-event", self.button_release_label)
119 self.connect("motion-notify-event", self.motion_notify_label)
120 self.connect("key-press-event", self.key_press_label)
121 self.connect("focus-out-event", self.focus_out_label)
122
123
124 self.keymap = {
125 "Ctrl + c" : self.copy_to_clipboard,
126 }
127
129 '''
130 Copy select text to clipboard.
131 '''
132 if self.select_start_index != self.select_end_index:
133 cut_text = self.text[self.select_start_index:self.select_end_index]
134
135 clipboard = gtk.Clipboard()
136 clipboard.set_text(cut_text)
137
159
173
175 '''
176 Internal callback for `motion-notify-event` signal.
177
178 @param widget: Label widget.
179 @param event: Motion notify event.
180 '''
181 if not self.double_click_flag and self.left_click_flag and self.enable_select:
182 self.drag_end_index = self.get_index_at_event(widget, event)
183
184 self.select_start_index = min(self.drag_start_index, self.drag_end_index)
185 self.select_end_index = max(self.drag_start_index, self.drag_end_index)
186
187 self.queue_draw()
188
190 '''
191 Internal callback for `key-press-event` signal.
192
193 @param widget: Label widget.
194 @param event: Key press event.
195 '''
196 key_name = get_keyevent_name(event)
197
198 if self.keymap.has_key(key_name):
199 self.keymap[key_name]()
200
201 return False
202
204 '''
205 Internal callback for `focus-out-event` signal.
206
207 @param widget: Label widget.
208 @param event: Focus out event.
209 '''
210 if self.select_start_index != self.select_end_index:
211 self.select_start_index = self.select_end_index = 0
212
213 self.queue_draw()
214
216 '''
217 Internal function to get index at event.
218
219 @param widget: Label widget.
220 @param event: gtk.gdk.Event.
221 '''
222 cr = widget.window.cairo_create()
223 context = pangocairo.CairoContext(cr)
224 layout = context.create_layout()
225 layout.set_font_description(pango.FontDescription("%s %s" % (DEFAULT_FONT, self.text_size)))
226 layout.set_text(self.text)
227 (text_width, text_height) = layout.get_pixel_size()
228 if int(event.x) > text_width:
229 return len(self.text)
230 else:
231 (x_index, y_index) = layout.xy_to_index(int(event.x) * pango.SCALE, 0)
232 return x_index
233
234 - def get_content_width(self, content):
235 '''
236 Internal fucntion to get content width.
237 '''
238 (content_width, content_height) = get_content_size(content, self.text_size, wrap_width=self.wrap_width)
239 return content_width
240
242 '''
243 Select all.
244 '''
245 self.select_start_index = 0
246 self.select_end_index = len(self.text)
247
248 self.queue_draw()
249
251 '''
252 Internal callback for `expose-event` signal.
253
254 @param widget: Label widget.
255 @param event: Expose event.
256 '''
257 cr = widget.window.cairo_create()
258 rect = widget.allocation
259
260 self.draw_label_background(cr, rect)
261
262 self.draw_label_text(cr, rect)
263
264 propagate_expose(widget, event)
265
266 return True
267
269 '''
270 Inernal function to draw label background.
271
272 @param cr: Cairo context.
273 @param rect: Draw area.
274 @return: Always return True.
275 '''
276 if self.select_start_index != self.select_end_index:
277 select_start_width = self.get_content_width(self.text[0:self.select_start_index])
278 select_end_width = self.get_content_width(self.text[0:self.select_end_index])
279
280 draw_hlinear(cr,
281 rect.x + select_start_width,
282 rect.y,
283 select_end_width - select_start_width,
284 rect.height,
285 [(0, (self.text_select_background.get_color(), 0)),
286 (0, (self.text_select_background.get_color(), 1))]
287 )
288
289 - def draw_label_text(self, cr, rect):
290 '''
291 Internal fucntion to draw label text.
292
293 @param cr: Cairo context.
294 @param rect: Draw area.
295 '''
296 if self.enable_gaussian:
297 label_color = "#FFFFFF"
298 else:
299 label_color = self.text_color.get_color()
300
301 if not self.get_sensitive():
302 draw_text(cr, self.text,
303 rect.x, rect.y, rect.width, rect.height,
304 self.text_size,
305 ui_theme.get_color("disable_text").get_color(),
306 alignment=self.text_x_align,
307 gaussian_radious=self.gaussian_radious,
308 gaussian_color=self.gaussian_color,
309 border_radious=self.border_radious,
310 border_color=self.border_color,
311 wrap_width=self.wrap_width
312 )
313 elif self.select_start_index == self.select_end_index:
314 draw_text(cr, self.text,
315 rect.x, rect.y, rect.width, rect.height,
316 self.text_size,
317 label_color,
318 alignment=self.text_x_align,
319 gaussian_radious=self.gaussian_radious,
320 gaussian_color=self.gaussian_color,
321 border_radious=self.border_radious,
322 border_color=self.border_color,
323 wrap_width=self.wrap_width
324 )
325 else:
326 select_start_width = self.get_content_width(self.text[0:self.select_start_index])
327 select_end_width = self.get_content_width(self.text[0:self.select_end_index])
328
329
330 if self.text[0:self.select_start_index] != "":
331 draw_text(cr, self.text[0:self.select_start_index],
332 rect.x, rect.y, rect.width, rect.height,
333 self.text_size,
334 label_color,
335 alignment=self.text_x_align,
336 gaussian_radious=self.gaussian_radious,
337 gaussian_color=self.gaussian_color,
338 border_radious=self.border_radious,
339 border_color=self.border_color,
340 wrap_width=self.wrap_width
341 )
342
343
344 if self.text[self.select_start_index:self.select_end_index] != "":
345 draw_text(cr, self.text[self.select_start_index:self.select_end_index],
346 rect.x + select_start_width, rect.y, rect.width, rect.height,
347 self.text_size,
348 self.text_select_color.get_color(),
349 alignment=self.text_x_align,
350 gaussian_radious=self.gaussian_radious,
351 gaussian_color=self.gaussian_color,
352 border_radious=self.border_radious,
353 border_color=self.border_color,
354 wrap_width=self.wrap_width
355 )
356
357
358 if self.text[self.select_end_index::] != "":
359 draw_text(cr, self.text[self.select_end_index::],
360 rect.x + select_end_width, rect.y, rect.width, rect.height,
361 self.text_size,
362 label_color,
363 alignment=self.text_x_align,
364 gaussian_radious=self.gaussian_radious,
365 gaussian_color=self.gaussian_color,
366 border_radious=self.border_radious,
367 border_color=self.border_color,
368 wrap_width=self.wrap_width
369 )
370
371 - def get_text(self):
372 '''
373 Get text of label.
374 '''
375 return self.text
376
377 - def set_text(self, text):
378 '''
379 Set text with given value.
380
381 @param text: Label string.
382 '''
383 self.text = text
384 self.update_size()
385 self.queue_draw()
386
388 '''
389 Internal function to update size.
390 '''
391 if self.label_width == None:
392 (label_width, label_height) = get_content_size(self.text, self.text_size, wrap_width=self.wrap_width)
393 else:
394 (label_width, label_height) = get_content_size(self.text, self.text_size, wrap_width=self.wrap_width)
395 label_width = self.label_width
396
397 if self.enable_gaussian:
398 label_width += self.gaussian_radious * 2
399 label_height += self.gaussian_radious * 2
400
401 self.set_size_request(label_width, label_height)
402