comparison browser_side/panels.py @ 291:89818bca1a33

browser_side: set the ideal width for the blog post update dialog
author souliane <souliane@mailoo.org>
date Tue, 10 Dec 2013 13:04:51 +0100
parents 20a9aedc60b5
children 1a5dc08c2749
comparison
equal deleted inserted replaced
290:3216c8d5432b 291:89818bca1a33
32 from pyjamas.ui.HTML import HTML 32 from pyjamas.ui.HTML import HTML
33 from pyjamas.ui.Image import Image 33 from pyjamas.ui.Image import Image
34 from pyjamas.ui.PopupPanel import PopupPanel 34 from pyjamas.ui.PopupPanel import PopupPanel
35 from pyjamas.ui.StackPanel import StackPanel 35 from pyjamas.ui.StackPanel import StackPanel
36 from pyjamas.ui.ClickListener import ClickHandler 36 from pyjamas.ui.ClickListener import ClickHandler
37 from pyjamas.ui.FlowPanel import FlowPanel
37 from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_UP, KEY_DOWN, KeyboardHandler 38 from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_UP, KEY_DOWN, KeyboardHandler
38 from pyjamas.ui.Event import BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT 39 from pyjamas.ui.Event import BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT
39 from pyjamas.ui.MouseListener import MouseHandler 40 from pyjamas.ui.MouseListener import MouseHandler
40 from pyjamas.Timer import Timer 41 from pyjamas.Timer import Timer
41 from pyjamas import DOM 42 from pyjamas import DOM
343 _datetime = datetime.fromtimestamp(mblog_entry.timestamp) 344 _datetime = datetime.fromtimestamp(mblog_entry.timestamp)
344 self.comments = mblog_entry.comments 345 self.comments = mblog_entry.comments
345 self.pub_data = (mblog_entry.hash[0], mblog_entry.hash[1], mblog_entry.id) 346 self.pub_data = (mblog_entry.hash[0], mblog_entry.hash[1], mblog_entry.id)
346 347
347 self.editable_content = (mblog_entry.xhtml, const._SYNTAX_XHTML) if mblog_entry.xhtml else (mblog_entry.content, None) 348 self.editable_content = (mblog_entry.xhtml, const._SYNTAX_XHTML) if mblog_entry.xhtml else (mblog_entry.content, None)
348 self.panel = HTMLPanel(""" 349
349 <div class='mb_entry_header'><span class='mb_entry_author'>%(author)s</span> on <span class='mb_entry_timestamp'>%(timestamp)s</span></div> 350 self.panel = FlowPanel()
350 <div class='mb_entry_delete_update'> 351 self.panel.setStyleName('mb_entry')
351 <div id="id_delete"></div> 352 header = HTMLPanel("""<div class='mb_entry_header'>
352 <div id="id_update"></div> 353 <span class='mb_entry_author'>%(author)s</span>
353 </div> 354 <span>on</span>
354 <div class="mb_entry_avatar" id='id_avatar'></div> 355 <span class='mb_entry_timestamp'>%(timestamp)s</span>
355 <div class="mb_entry_dialog" id='id_entry_dialog'></div> 356 </div>""" % {'author': html_sanitize(self.author), 'timestamp': _datetime})
356 </div> 357 self.panel.add(header)
357 """ % {"author": html_sanitize(self.author), 358
358 "timestamp": _datetime 359 if self.author == blog_panel.host.whoami.bare:
359 }) 360 entry_delete_update = VerticalPanel()
361 entry_delete_update.setStyleName('mb_entry_delete_update')
362 self.delete_label = Label(u"✗")
363 self.delete_label.setTitle("Delete this message")
364 self.update_label = Label(u"✍")
365 self.update_label.setTitle("Edit this message")
366 entry_delete_update.add(self.delete_label)
367 entry_delete_update.add(self.update_label)
368 self.delete_label.addClickListener(self)
369 self.update_label.addClickListener(self)
370 self.panel.add(entry_delete_update)
371 else:
372 self.update_label = self.delete_label = None
373
374 entry_avatar = SimplePanel()
375 entry_avatar.setStyleName('mb_entry_avatar')
360 self.avatar = Image(blog_panel.host.getAvatar(self.author)) 376 self.avatar = Image(blog_panel.host.getAvatar(self.author))
361 self.panel.add(self.avatar, "id_avatar") 377 entry_avatar.add(self.avatar)
378 self.panel.add(entry_avatar)
379
380 self.entry_dialog = SimplePanel()
381 self.entry_dialog.setStyleName('mb_entry_dialog')
362 body = addURLToText(html_sanitize(mblog_entry.content)) if not mblog_entry.xhtml else mblog_entry.xhtml 382 body = addURLToText(html_sanitize(mblog_entry.content)) if not mblog_entry.xhtml else mblog_entry.xhtml
363 self.bubble = HTML(body) 383 self.bubble = HTML(body)
364 self.bubble.setStyleName("bubble") 384 self.bubble.setStyleName("bubble")
365 self.panel.add(self.bubble, "id_entry_dialog") 385 self.entry_dialog.add(self.bubble)
366 self.panel.setStyleName('mb_entry') 386 self.panel.add(self.entry_dialog)
367 if self.author == blog_panel.host.whoami.bare: 387
368 self.delete_label = Label(u"✗")
369 self.delete_label.setTitle("Delete this message")
370 self.panel.add(self.delete_label, "id_delete")
371 self.update_label = Label(u"✍")
372 self.update_label.setTitle("Edit this message")
373 self.panel.add(self.update_label, "id_update")
374 self.delete_label.addClickListener(self)
375 self.update_label.addClickListener(self)
376 else:
377 self.modify_label = self.delete_label = None
378 self.editbox = None 388 self.editbox = None
379 self.add(self.panel) 389 self.add(self.panel)
380 ClickHandler.__init__(self) 390 ClickHandler.__init__(self)
381 self.addClickListener(self) 391 self.addClickListener(self)
392
393 def onWindowResized(self, width=None, height=None):
394 """The listener is active when the text is being modified"""
395 left = self.avatar.getAbsoluteLeft() + self.avatar.getOffsetWidth()
396 right = self.delete_label.getAbsoluteLeft()
397 ideal_width = right - left - 60
398 self.entry_dialog.setWidth("%spx" % ideal_width)
382 399
383 def updateAvatar(self, new_avatar): 400 def updateAvatar(self, new_avatar):
384 """Change the avatar of the entry 401 """Change the avatar of the entry
385 @param new_avatar: path to the new image""" 402 @param new_avatar: path to the new image"""
386 self.avatar.setUrl(new_avatar) 403 self.avatar.setUrl(new_avatar)
408 425
409 def updateContent(self, cancel=False): 426 def updateContent(self, cancel=False):
410 """Send the new content to the backend""" 427 """Send the new content to the backend"""
411 if not self.editbox or not self.editbox.getVisible(): 428 if not self.editbox or not self.editbox.getVisible():
412 return 429 return
413 self.panel.remove(self.edit_panel) 430 Window.removeWindowResizeListener(self)
414 self.panel.add(self.bubble, "id_entry_dialog") 431 self.entry_dialog.setWidth("auto")
432 self.entry_dialog.remove(self.edit_panel)
433 self.entry_dialog.add(self.bubble)
415 new_text = self.editbox.getText().strip() 434 new_text = self.editbox.getText().strip()
416 self.edit_panel = self.editbox = None 435 self.edit_panel = self.editbox = None
417 if cancel or new_text == self.editable_content[0] or new_text == "": 436 if cancel or new_text == self.editable_content[0] or new_text == "":
418 return 437 return
419 self.editable_content[0] = new_text 438 self.editable_content[0] = new_text
432 self.editbox.setText(text) 451 self.editbox.setText(text)
433 panel = SimplePanel() 452 panel = SimplePanel()
434 panel.add(container) 453 panel.add(container)
435 panel.setStyleName("bubble") 454 panel.setStyleName("bubble")
436 panel.addStyleName('bubble-editbox') 455 panel.addStyleName('bubble-editbox')
437 self.bubble.removeFromParent() 456 Window.addWindowResizeListener(self)
438 self.panel.add(panel, "id_entry_dialog") 457 self.onWindowResized()
458 self.entry_dialog.remove(self.bubble)
459 self.entry_dialog.add(panel)
439 self.editbox.setFocus(True) 460 self.editbox.setFocus(True)
440 self.editbox.setSelectionRange(len(text), 0) 461 self.editbox.setSelectionRange(len(text), 0)
441 self.edit_panel = panel 462 self.edit_panel = panel
442 self.editable_content = (text, container.format if isinstance(container, richtext.RichTextEditor) else None) 463 self.editable_content = (text, container.format if isinstance(container, richtext.RichTextEditor) else None)
443 464
446 467
447 def cb(result): 468 def cb(result):
448 self.updateContent(result == richtext.CANCEL) 469 self.updateContent(result == richtext.CANCEL)
449 470
450 editor = richtext.RichTextEditor(self._blog_panel.host, self.panel, cb, options=options) 471 editor = richtext.RichTextEditor(self._blog_panel.host, self.panel, cb, options=options)
472 editor.setWidth('100%')
451 editor.setVisible(True) # needed to build the toolbar 473 editor.setVisible(True) # needed to build the toolbar
452 self.editbox = editor.textarea 474 self.editbox = editor.textarea
453 self._blog_panel.host.bridge.call('syntaxConvert', lambda d: setOriginalText(d, editor), 475 self._blog_panel.host.bridge.call('syntaxConvert', lambda d: setOriginalText(d, editor),
454 self.editable_content[0], self.editable_content[1]) 476 self.editable_content[0], self.editable_content[1])
455 else: 477 else: