class HTMLDialog(DialogBox): def __init__(self, name, html): DialogBox.__init__(self) self.setText(name) closeButton = Button("Close", self) htp = HTMLPanel(html) self.sp = ScrollPanel(htp) dock = DockPanel() dock.setSpacing(4) dock.add(closeButton, DockPanel.SOUTH) dock.add(self.sp, DockPanel.CENTER) dock.setCellHorizontalAlignment(closeButton, HasAlignment.ALIGN_RIGHT) dock.setCellWidth(self.sp, "100%") dock.setWidth("100%") self.setWidget(dock) def setWidth(self, width): DialogBox.setWidth(self, "%dpx" % width) self.sp.setWidth("%dpx" % (width-20)) def setHeight(self, height): DialogBox.setHeight(self, "%dpx" % height) self.sp.setHeight("%dpx" % (height-65)) def onClick(self, sender): self.hide()
class HTMLDialog(DialogBox): def __init__(self, name, html): DialogBox.__init__(self) self.setText(name) closeButton = Button("Close", self) htp = HTMLPanel(html) self.sp = ScrollPanel(htp) dock = DockPanel() dock.setSpacing(4) dock.add(closeButton, DockPanel.SOUTH) dock.add(self.sp, DockPanel.CENTER) dock.setCellHorizontalAlignment(closeButton, HasAlignment.ALIGN_RIGHT) dock.setCellWidth(self.sp, "100%") dock.setWidth("100%") self.setWidget(dock) def setWidth(self, width): DialogBox.setWidth(self, "%dpx" % width) self.sp.setWidth("%dpx" % (width - 20)) def setHeight(self, height): DialogBox.setHeight(self, "%dpx" % height) self.sp.setHeight("%dpx" % (height - 65)) def onClick(self, sender): self.hide()
class SinkList(Composite): def __init__(self): Composite.__init__(self) self.vp_list = VerticalPanel() self.sinks = [] self.selectedSink = -1 self.sp = ScrollPanel(self.vp_list) self.sp.setWidth("24em") self.initWidget(self.sp) self.setStyleName("ks-List") self.resize(Window.getClientWidth(), Window.getClientHeight()) def resize(self, width, height): self.sp.setHeight("%dpx" % (height - 70)) def addSink(self, info): name = info.getName() link = Hyperlink(name, False, name) link.setStyleName("ks-SinkItem") self.vp_list.add(link) self.sinks.append(info) def find(self, sinkName): for info in self.sinks: if info.getName() == sinkName: return info return None def setSinkSelection(self, name): if self.selectedSink <> -1: self.vp_list.getWidget( self.selectedSink).removeStyleName("ks-SinkItem-selected") for i in range(len(self.sinks)): info = self.sinks[i] if (info.getName() == name): self.selectedSink = i widget = self.vp_list.getWidget(self.selectedSink) widget.addStyleName("ks-SinkItem-selected") return
class SinkList(Composite): def __init__(self): Composite.__init__(self) self.vp_list=VerticalPanel() self.sinks=[] self.selectedSink=-1 self.sp = ScrollPanel(self.vp_list) self.sp.setWidth("14em") self.initWidget(self.sp) self.setStyleName("ks-List") self.resize(Window.getClientWidth(), Window.getClientHeight()) def resize(self, width, height): self.sp.setHeight("%dpx" % (height - 70)) def addSink(self, info): name = info.getName() link = Hyperlink(name, False, TargetHistoryToken=name) link.setStyleName("ks-SinkItem") self.vp_list.add(link) self.sinks.append(info) def find(self, sinkName): for info in self.sinks: if info.getName()==sinkName: return info return None def setSinkSelection(self, name): if self.selectedSink <> -1: self.vp_list.getWidget(self.selectedSink).removeStyleName("ks-SinkItem-selected") for i in range(len(self.sinks)): info = self.sinks[i] if (info.getName()==name): self.selectedSink = i widget=self.vp_list.getWidget(self.selectedSink) widget.addStyleName("ks-SinkItem-selected") return
class SplitPanel(AbsolutePanel, MouseHandler, EventGenerator): """ Provides the SplitPanel baseclass functionality A SplitPanel is an AbsolutePanel containing an HTMLTable with three cells. The first cell holds the first ScrollPanel, while the center cell holds a Splitter, and the last cell holds the other ScrollPanel. """ def __init__(self, vertical=False, **kwargs): # set defaults if not 'StyleName' in kwargs: if vertical: # vertical split panel kwargs['StyleName'] = "gwt-VerticalSplitPanel" else: kwargs['StyleName'] = "gwt-HorizontalSplitPanel" # splitter drag state vars self._drag_start = None self._pos = "50%" # orientation self._vertical = vertical # now init the bases AbsolutePanel.__init__(self, **kwargs) MouseHandler.__init__(self) # add our event support? self.addListenedEvent("Resize") # create the top/left widget container self._container1 = ScrollPanel() # create the bottom/right widget container self._container2 = ScrollPanel() # create the splitter self._splitter = SplitPanelSplitter(self) # add splitter handling self._splitter.addMouseListener(self) # add mouse event handling self.addMouseListener(self) # add the parts AbsolutePanel.add(self, self._container1, 0, 0) AbsolutePanel.add(self, self._splitter, 0, 0) AbsolutePanel.add(self, self._container2, 0, 0) # set the layout if vertical: # vertical split panel self._splitter.setStyleName("vsplitter") self._splitter.setWidth("100%") self._container1.setWidth("100%") self._container2.setWidth("100%") # set drag cursor DOM.setStyleAttribute(self._splitter.getElement(), "cursor", "n-resize") else: # horizontal split panel self._splitter.setStyleName("hsplitter") self._splitter.setHeight("100%") self._container1.setHeight("100%") self._container2.setHeight("100%") # set drag cursor DOM.setStyleAttribute(self._splitter.getElement(), "cursor", "e-resize") def onAttach(self): AbsolutePanel.onAttach(self) self.setSplitPosition() # fixup the container 2 size and position def _finalizePositions(self, pos=None): finalized = False if self._vertical: if pos is None: pos = self._container1.getOffsetHeight() space = self.getOffsetHeight() sz = self._splitter.getOffsetHeight() if space > 0 and sz > 0 and pos > 0: # limit pos if pos > space - sz: pos = space - sz self._container1.setHeight(pos) self.setWidgetPosition(self._splitter, 0, pos) self.setWidgetPosition(self._container2, 0, pos + sz) self._container2.setHeight(space - (pos + sz)) finalized = True else: if pos is None: pos = self._container1.getOffsetWidth() space = self.getOffsetWidth() sz = self._splitter.getOffsetWidth() if space > 0 and sz > 0 and pos > 0: # limit pos if pos > space - sz: pos = space - sz self._container1.setWidth(pos) self.setWidgetPosition(self._splitter, pos, 0) self.setWidgetPosition(self._container2, pos + sz, 0) self._container2.setWidth(space - (pos + sz)) finalized = True if finalized: self.dispatchResizeEvent(self, pos) return finalized # end a drag operation def _stopDragging(self): if self._drag_start is not None: # we are no longer dragging self._drag_start = None # deactivate the transparent overlay GlassWidget.hide() # don't let a mouse-up become a click event DOM.eventCancelBubble(DOM.eventGetCurrentEvent(), True) def _isDragging(self): return self._drag_start is not None # start a drag operation (called by splitter) def startSplitterDrag(self, x, y): if self._drag_start is None: # remember where on the slider we are dragging if self._vertical: self._drag_start = y else: self._drag_start = x # activate the transparent overlay to keep mouse events flowing to # the splitter (and to us) even if the mouse leaves the splitter GlassWidget.show(self) # add handlers for mouse events to support dragging the slider # NOTE: the x,y positioni s relative to the splitter def onMouseMove(self, sender, x, y): # if dragging, then use current mouse position # to reset splitter position if not self._isDragging(): return # remove the offset into the splitter # where we started dragging if self._vertical: self._pos = y - self._drag_start else: self._pos = x - self._drag_start # apply limit if self._pos < 1: self._pos = 1 # apply new position self.setSplitPosition() def onMouseUp(self, sender, x, y): ev = DOM.eventGetCurrentEvent() # ignore right-button ups if DOM.eventGetButton(ev) != Event.BUTTON_LEFT: return DOM.eventPreventDefault(ev) # if we are dragging if self._isDragging(): # stop dragging on mouse up self._stopDragging() # called when we start dragging def onMouseGlassEnter(self, sender): pass # called when we drag out of the window # (NOT called when we just stop dragging) def onMouseGlassLeave(self, sender): # we left the window, so stop dragging self._stopDragging() # # Start the inherited 'public' API # # specify splitter position in pix OR percentage # if pixels (number) specified, we can make change now # otherwise, we have to set the offset as specified, then # 'fixup' the remaining space after rendering def setSplitPosition(self, pos=None): if pos is not None: # remember last pos set self._pos = pos else: pos = self._pos if pos < 1: pos = 1 self._pos = pos # change adjustable dimension if self._vertical: self._container1.setHeight(pos) else: self._container1.setWidth(pos) # if pix are given, we can try to finalize the positions finalized = False if isinstance(pos, int): finalized = self._finalizePositions(pos) # if needed, queue callback to finalize if not finalized: DeferredCommand.add(self._finalizePositions) def getWidget(self, index): if index == 0: return self._container1.getWidget() return self._container2.getWidget() def setWidget(self, index, widget): if index == 0: return self._container1.setWidget(widget) return self._container2.setWidget(widget) # Adds a widget to a pane def add(self, widget): if self.getWidget(0) == None: self.setWidget(0, widget) elif self.getWidget(1) == None: self.setWidget(1, widget) else: console.error("SimplePanel can only contain one child widget") # Removes a child widget. def remove(self, widget): if self.getWidget(0) == widget: self._container1.remove(widget) elif self.getWidget(1) == widget: self._container2.remove(widget) else: AbsolutePanel.remove(self, widget) # Gets the content element for the given index. def getElement(self, index=None): if index is None: return AbsolutePanel.getElement(self) return self.getWidget(index).getElement() # Gets the widget in the pane at end of the line direction for the layout def getEndOfLineWidget(self): return self.getWidget(1) # Gets the element that is acting as the splitter. def getSplitElement(self): return self._splitter.getElement() # Gets the widget in the pane at the start of line direction for the layout def getStartOfLineWidget(self): return self.getWidget(0) # Indicates whether the split panel is being resized. def isResizing(self): return False # Sets the widget in the pane at the end of line direction for the layout def setEndOfLineWidget(self, widget): self.setWidget(1, widget) def setStartOfLineWidget(self, widget): self.setWidget(0, widget)
class Bookreader: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): section = Window.getLocation().getSearchVar("section") if not section: self.loadChapters() else: loadSection(section) def loadChapters(self): self.curInfo = '' self.curSink = None self.description = HTML() self.sink_list = SinkList() self.panel = DockPanel() self.loadSinks() self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") #self.nf = NamedFrame("section") #self.nf.setWidth("100%") #self.nf.setHeight("10000") self.sp = ScrollPanel(self.sinkContainer) #self.sp = VerticalSplitPanel() self.sp.setWidth("100%") self.sp.setHeight("100%") #self.sp.setTopWidget(self.sinkContainer) #self.sp.setBottomWidget(self.nf) #self.sp.setSplitPosition(10000) # deliberately high - max out. vp = VerticalPanel() vp.setWidth("99%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) authors = [("2008, 2009", "Kenneth Casson Leighton", "*****@*****.**")] for years, name, email in authors: authors_html = \ '© %s <a href="mailto:%s">%s</a><br />' %\ (years, email, name) authors_panel = HTML() authors_panel.setStyleName("ks-Authors") authors_panel.setHTML(authors_html[:-6]) left_panel = DockPanel(Height="100%") left_panel.add(self.sink_list, DockPanel.NORTH) left_panel.add(authors_panel, DockPanel.SOUTH) self.description.setStyleName("ks-Intro") self.panel.add(left_panel, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) self.onWindowResized(Window.getClientWidth(), Window.getClientHeight()) def onWindowResized(self, width, height): self.panel.setWidth(width - 20) self.sink_list.resize(width - 20, height - 130) self.sp.setHeight("%dpx" % (height - 130)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink is not None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.sink_list.sp.setScrollPosition(0) self.sink_list.sp.setHorizontalScrollPosition(0) self.description.setHTML(info.getDescription()) if (affectHistory): History().newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("contents.txt", ChapterListLoader(self)) def setChapters(self, chapters): for l in chapters: name = l[0] desc = l[1] self.sink_list.addSink(Chapter.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)
class Bookreader: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): section = Window.getLocation().getSearchVar("section") if not section: self.loadChapters() else: loadSection(section) def loadChapters(self): self.curInfo = '' self.curSink = None self.description = HTML() self.sink_list = SinkList() self.panel = DockPanel() self.loadSinks() self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") #self.nf = NamedFrame("section") #self.nf.setWidth("100%") #self.nf.setHeight("10000") self.sp = ScrollPanel(self.sinkContainer) #self.sp = VerticalSplitPanel() self.sp.setWidth("100%") self.sp.setHeight("100%") #self.sp.setTopWidget(self.sinkContainer) #self.sp.setBottomWidget(self.nf) #self.sp.setSplitPosition(10000) # deliberately high - max out. vp = VerticalPanel() vp.setWidth("99%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) authors = [ ("2008, 2009", "Kenneth Casson Leighton", "*****@*****.**") ] for years, name, email in authors: authors_html = \ '© %s <a href="mailto:%s">%s</a><br />' %\ (years, email, name) authors_panel = HTML() authors_panel.setStyleName("ks-Authors") authors_panel.setHTML(authors_html[:-6]) left_panel = DockPanel(Height="100%") left_panel.add(self.sink_list, DockPanel.NORTH) left_panel.add(authors_panel, DockPanel.SOUTH) self.description.setStyleName("ks-Intro") self.panel.add(left_panel, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) self.onWindowResized(Window.getClientWidth(), Window.getClientHeight()) def onWindowResized(self, width, height): self.panel.setWidth(width-20) self.sink_list.resize(width-20, height-130) self.sp.setHeight("%dpx" % (height-130)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink is not None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.sink_list.sp.setScrollPosition(0) self.sink_list.sp.setHorizontalScrollPosition(0) self.description.setHTML(info.getDescription()) if (affectHistory): History().newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("contents.txt", ChapterListLoader(self)) def setChapters(self, chapters): for l in chapters: name = l[0] desc = l[1] self.sink_list.addSink(Chapter.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)
class InfoDirectory: def onModuleLoad(self): self.remote = InfoServicePython() self.tree_width = 200 self.tp = HorizontalPanel() self.tp.setWidth("%dpx" % (self.tree_width)) self.treeview = Trees() self.treeview.fTree.addTreeListener(self) self.sp = ScrollPanel() self.tp.add(self.treeview) self.sp.add(self.tp) self.sp.setHeight("100%") self.horzpanel1 = HorizontalPanel() self.horzpanel1.setSize("100%", "100%") self.horzpanel1.setBorderWidth(1) self.horzpanel1.setSpacing("10px") self.rp = RightPanel() self.rps = ScrollPanel() self.rps.add(self.rp) self.rps.setWidth("100%") self.rp.setWidth("100%") self.cp1 = CollapserPanel(self) self.cp1.setWidget(self.sp) self.cp1.setHTML(" ") self.midpanel = MidPanel(self) self.cp2 = CollapserPanel(self) self.cp2.setWidget(self.midpanel) self.cp2.setHTML(" ") self.horzpanel1.add(self.cp1) self.horzpanel1.add(self.cp2) self.horzpanel1.add(self.rps) self.cp1.setInitialWidth("%dpx" % self.tree_width) self.cp2.setInitialWidth("200px") RootPanel().add(self.horzpanel1) width = Window.getClientWidth() height = Window.getClientHeight() self.onWindowResized(width, height) Window.addWindowResizeListener(self) def setCollapserWidth(self, widget, width): self.horzpanel1.setCellWidth(widget, width) def onWindowResized(self, width, height): #self.hp.setWidth("%dpx" % (width - self.tree_width)) #self.hp.setHeight("%dpx" % (height - 20)) self.cp1.setHeight("%dpx" % (height - 30)) self.cp2.setHeight("%dpx" % (height - 30)) self.rps.setHeight("%dpx" % (height - 30)) self.horzpanel1.setHeight("%dpx" % (height - 20)) def onTreeItemStateChanged(self, item): if item.isSelected(): self.onTreeItemSelected(item) def onTreeItemSelected(self, item): obj = item.getUserObject() if len(obj.children) != 0: self.clear_mid_panel() return self.remote.get_midpanel_data(obj.root + "/" + obj.text, self) self.cp2.setHTML(obj.text) self.clear_right_panel() def clear_right_panel(self): self.horzpanel1.remove(2) self.horzpanel1.insert(HTML(""), 2) self.rp.setTitle(" ") def clear_mid_panel(self): self.clear_right_panel() #self.horzpanel2.setLeftWidget(HTML("")) def set_mid_panel(self, response): self.midpanel.set_items(response) self.cp2.setWidget(self.midpanel) def select_right_grid(self, location, name): self.horzpanel1.remove(2) self.horzpanel1.insert(self.rps, 2) self.rp.setTitle(name) self.remote.get_rightpanel_datanames(location, self) def get_rightpanel_datasets(self, datasets): self.rp.clear_items() self.rp.setup_panels(datasets) for i in range(len(datasets)): item = datasets[i] fname = item[0] self.remote.get_rightpanel_data(fname, fname, i, self) def fill_right_grid(self, data): index = data.get('index') name = data.get('name') if data.has_key('items'): self.rp.add_items(data.get('items'), name, index) elif data.has_key('html'): self.rp.add_html(data.get('html'), name, index) def onRemoteResponse(self, response, request_info): method = request_info.method if method == "get_midpanel_data": self.set_mid_panel(response) elif method == "get_rightpanel_datanames": self.get_rightpanel_datasets(response) elif method == "get_rightpanel_data": self.fill_right_grid(response) def onRemoteError(self, code, message, request_info): RootPanel().add(HTML("Server Error or Invalid Response: ERROR " + code)) RootPanel().add(HTML(message))
class Slideshow: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): self.curInfo='' self.curSink=None self.description=HTML() self.sink_list=SinkList() self.panel=DockPanel() self.b=Button("load", self) self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") height = Window.getClientHeight() self.sp = ScrollPanel(self.sinkContainer) self.sp.setWidth("100%") self.sp.setHeight("%dpx" % (height-110)) vp=VerticalPanel() vp.setWidth("100%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) self.description.setStyleName("ks-Intro") self.panel.add(self.sink_list, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) #RootPanel().add(self.b) self.loadSinks() def onClick(self, sender): self.loadSinks() def onTimer(self, tid): self.loadSinks() def onWindowResized(self, width, height): #self.sink_list.resize(width, height) self.sp.setHeight("%dpx" % (height-110)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink <> None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.description.setHTML(info.getDescription()) if (affectHistory): History.newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("slides.txt", SlideListLoader(self)) def setSlides(self, slides): for l in slides: name = l[0] desc = l[1] self.sink_list.add(Slide.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)
class Bookreader: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): section = Window.getLocation().getSearchVar("section") if not section: self.loadChapters() else: loadSection(section) def loadChapters(self): self.curInfo = '' self.curSink = None self.description = HTML() self.sink_list = SinkList() self.panel = DockPanel() self.loadSinks() self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") #self.nf = NamedFrame("section") #self.nf.setWidth("100%") #self.nf.setHeight("10000") height = Window.getClientHeight() self.sp = ScrollPanel(self.sinkContainer) #self.sp = VerticalSplitPanel() self.sp.setWidth("100%") self.sp.setHeight("%dpx" % (height - 110)) #self.sp.setTopWidget(self.sinkContainer) #self.sp.setBottomWidget(self.nf) #self.sp.setSplitPosition(10000) # deliberately high - max out. vp = VerticalPanel() vp.setWidth("100%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) self.description.setStyleName("ks-Intro") self.panel.add(self.sink_list, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) def onWindowResized(self, width, height): self.sink_list.resize(width, height) self.sp.setHeight("%dpx" % (height - 110)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink is not None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.description.setHTML(info.getDescription()) if (affectHistory): History().newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("contents.txt", ChapterListLoader(self)) def setChapters(self, chapters): for l in chapters: name = l[0] desc = l[1] self.sink_list.addSink(Chapter.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)
class SplitPanel(AbsolutePanel, MouseHandler, EventGenerator): """ Provides the SplitPanel baseclass functionality A SplitPanel is an AbsolutePanel containing an HTMLTable with three cells. The first cell holds the first ScrollPanel, while the center cell holds a Splitter, and the last cell holds the other ScrollPanel. """ def __init__(self, vertical=False, **kwargs): # set defaults if not 'StyleName' in kwargs: if vertical: # vertical split panel kwargs['StyleName'] = "gwt-VerticalSplitPanel" else: kwargs['StyleName'] = "gwt-HorizontalSplitPanel" # splitter drag state vars self._drag_start = None self._pos = "50%" # orientation self._vertical = vertical # now init the bases AbsolutePanel.__init__(self, **kwargs) MouseHandler.__init__(self) # add our event support? self.addListenedEvent("Resize") # create the top/left widget container self._container1 = ScrollPanel() # create the bottom/right widget container self._container2 = ScrollPanel() # create the splitter self._splitter = SplitPanelSplitter(self) # add splitter handling self._splitter.addMouseListener(self) # add mouse event handling self.addMouseListener(self) # add the parts AbsolutePanel.add(self, self._container1, 0, 0) AbsolutePanel.add(self, self._splitter, 0, 0) AbsolutePanel.add(self, self._container2, 0, 0) # set the layout if vertical: # vertical split panel self._splitter.setStyleName("vsplitter") self._splitter.setWidth("100%") self._container1.setWidth("100%") self._container2.setWidth("100%") # set drag cursor DOM.setStyleAttribute(self._splitter.getElement(), "cursor", "n-resize") else: # horizontal split panel self._splitter.setStyleName("hsplitter") self._splitter.setHeight("100%") self._container1.setHeight("100%") self._container2.setHeight("100%") # set drag cursor DOM.setStyleAttribute(self._splitter.getElement(), "cursor", "e-resize") def onAttach(self): AbsolutePanel.onAttach(self) self.setSplitPosition() # fixup the container 2 size and position def _finalizePositions(self, pos=None): finalized = False if self._vertical: if pos is None: pos = self._container1.getOffsetHeight() space = self.getOffsetHeight() sz = self._splitter.getOffsetHeight() if space > 0 and sz > 0 and pos > 0: # limit pos if pos > space - sz: pos = space - sz self._container1.setHeight(pos) self.setWidgetPosition(self._splitter, 0, pos) self.setWidgetPosition(self._container2, 0, pos + sz) self._container2.setHeight(space - (pos + sz)) finalized = True else: if pos is None: pos = self._container1.getOffsetWidth() space = self.getOffsetWidth() sz = self._splitter.getOffsetWidth() if space > 0 and sz > 0 and pos > 0: # limit pos if pos > space - sz: pos = space - sz self._container1.setWidth(pos) self.setWidgetPosition(self._splitter, pos, 0) self.setWidgetPosition(self._container2, pos + sz, 0) self._container2.setWidth(space - (pos + sz)) finalized = True if finalized: self.dispatchResizeEvent(self, pos) return finalized # end a drag operation def _stopDragging(self): if self._drag_start is not None: # we are no longer dragging self._drag_start = None # deactivate the transparent overlay GlassWidget.hide() # don't let a mouse-up become a click event DOM.eventCancelBubble(DOM.eventGetCurrentEvent(), True) def _isDragging(self): return self._drag_start is not None # start a drag operation (called by splitter) def startSplitterDrag(self, x, y): if self._drag_start is None: # remember where on the slider we are dragging if self._vertical: self._drag_start = y else: self._drag_start = x # activate the transparent overlay to keep mouse events flowing to # the splitter (and to us) even if the mouse leaves the splitter GlassWidget.show(self) # add handlers for mouse events to support dragging the slider # NOTE: the x,y positioni s relative to the splitter def onMouseMove(self, sender, x, y): # if dragging, then use current mouse position # to reset splitter position if not self._isDragging(): return # remove the offset into the splitter # where we started dragging if self._vertical: self._pos = y - self._drag_start else: self._pos = x - self._drag_start # apply limit if self._pos < 1: self._pos = 1 # apply new position self.setSplitPosition() def onMouseUp(self, sender, x, y): ev = DOM.eventGetCurrentEvent() # ignore right-button ups if DOM.eventGetButton(ev) != Event.BUTTON_LEFT: return DOM.eventPreventDefault(ev) # if we are dragging if self._isDragging(): # stop dragging on mouse up self._stopDragging() # called when we start dragging def onMouseGlassEnter(self, sender): pass # called when we drag out of the window # (NOT called when we just stop dragging) def onMouseGlassLeave(self, sender): # we left the window, so stop dragging self._stopDragging() # # Start the inherited 'public' API # # specify splitter position in pix OR percentage # if pixels (number) specified, we can make change now # otherwise, we have to set the offset as specified, then # 'fixup' the remaining space after rendering def setSplitPosition(self, pos=None): if pos is not None: # remember last pos set self._pos = pos else: pos = self._pos if pos < 1: pos = 1 self._pos = pos # change adjustable dimension if self._vertical: self._container1.setHeight(pos) else: self._container1.setWidth(pos) # if pix are given, we can try to finalize the positions finalized = False if isinstance(pos, int): finalized = self._finalizePositions(pos) # if needed, queue callback to finalize if not finalized: queue_Call(self._finalizePositions) def getWidget(self, index): if index == 0: return self._container1.getWidget() return self._container2.getWidget() def setWidget(self, index, widget): if index == 0: return self._container1.setWidget(widget) return self._container2.setWidget(widget) # Adds a widget to a pane def add(self, widget): if self.getWidget(0) == None: self.setWidget(0, widget) elif self.getWidget(1) == None: self.setWidget(1, widget) else: console.error("SimplePanel can only contain one child widget") # Removes a child widget. def remove(self, widget): if self.getWidget(0) == widget: self._container1.remove(widget) elif self.getWidget(1) == widget: self._container2.remove(widget) else: AbsolutePanel.remove(self, widget) # Gets the content element for the given index. def getElement(self, index=None): if index is None: return AbsolutePanel.getElement(self) return self.getWidget(index).getElement() # Gets the widget in the pane at end of the line direction for the layout def getEndOfLineWidget(self): return self.getWidget(1) # Gets the element that is acting as the splitter. def getSplitElement(self): return self._splitter.getElement() # Gets the widget in the pane at the start of line direction for the layout def getStartOfLineWidget(self): return self.getWidget(0) # Indicates whether the split panel is being resized. def isResizing(self): return False # Sets the widget in the pane at the end of line direction for the layout def setEndOfLineWidget(self, widget): self.setWidget(1, widget) def setStartOfLineWidget(self, widget): self.setWidget(0, widget)
class Slideshow: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): self.curInfo = '' self.curSink = None self.description = HTML() self.sink_list = SinkList() self.panel = DockPanel() self.b = Button("load", self) self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") height = Window.getClientHeight() self.sp = ScrollPanel(self.sinkContainer) self.sp.setWidth("100%") self.sp.setHeight("%dpx" % (height - 110)) vp = VerticalPanel() vp.setWidth("100%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) self.description.setStyleName("ks-Intro") self.panel.add(self.sink_list, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) RootPanel().add(self.b) self.loadSinks() def onClick(self, sender): self.loadSinks() def onTimer(self, tid): self.loadSinks() def onWindowResized(self, width, height): self.sink_list.resize(width, height) self.sp.setHeight("%dpx" % (height - 110)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink <> None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.description.setHTML(info.getDescription()) if (affectHistory): History.newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("slides.txt", SlideListLoader(self)) def setSlides(self, slides): for l in slides: name = l[0] desc = l[1] self.sink_list.addSink(Slide.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)
class Bookreader: def onHistoryChanged(self, token): info = self.sink_list.find(token) if info: self.show(info, False) else: self.showInfo() def onModuleLoad(self): section = Window.getLocation().getSearchVar("section") if not section: self.loadChapters() else: loadSection(section) def loadChapters(self): self.curInfo = '' self.curSink = None self.description = HTML() self.sink_list = SinkList() self.panel = DockPanel() self.loadSinks() self.sinkContainer = DockPanel() self.sinkContainer.setStyleName("ks-Sink") #self.nf = NamedFrame("section") #self.nf.setWidth("100%") #self.nf.setHeight("10000") height = Window.getClientHeight() self.sp = ScrollPanel(self.sinkContainer) #self.sp = VerticalSplitPanel() self.sp.setWidth("100%") self.sp.setHeight("%dpx" % (height-110)) #self.sp.setTopWidget(self.sinkContainer) #self.sp.setBottomWidget(self.nf) #self.sp.setSplitPosition(10000) # deliberately high - max out. vp = VerticalPanel() vp.setWidth("100%") vp.setHeight("100%") vp.add(self.description) vp.add(self.sp) self.description.setStyleName("ks-Intro") self.panel.add(self.sink_list, DockPanel.WEST) self.panel.add(vp, DockPanel.CENTER) self.panel.setCellVerticalAlignment(self.sink_list, HasAlignment.ALIGN_TOP) self.panel.setCellWidth(vp, "100%") self.panel.setCellHeight(vp, "100%") Window.addWindowResizeListener(self) History.addHistoryListener(self) RootPanel().add(self.panel) def onWindowResized(self, width, height): self.sink_list.resize(width, height) self.sp.setHeight("%dpx" % (height-110)) def show(self, info, affectHistory): if info == self.curInfo: return self.curInfo = info #Logger.write("showing " + info.getName()) if self.curSink is not None: self.curSink.onHide() #Logger.write("removing " + self.curSink) self.sinkContainer.remove(self.curSink) self.curSink = info.getInstance() self.sink_list.setSinkSelection(info.getName()) self.description.setHTML(info.getDescription()) if (affectHistory): History().newItem(info.getName()) self.sinkContainer.add(self.curSink, DockPanel.CENTER) self.sinkContainer.setCellWidth(self.curSink, "100%") self.sinkContainer.setCellHeight(self.curSink, "100%") self.sinkContainer.setCellVerticalAlignment(self.curSink, HasAlignment.ALIGN_TOP) self.curSink.onShow() def loadSinks(self): HTTPRequest().asyncGet("contents.txt", ChapterListLoader(self)) def setChapters(self, chapters): for l in chapters: name = l[0] desc = l[1] self.sink_list.addSink(Chapter.init(name, desc)) #Show the initial screen. initToken = History.getToken() if len(initToken): self.onHistoryChanged(initToken) else: self.showInfo() def showInfo(self): self.show(self.sink_list.sinks[0], False)