class TextWindow: """ Encapsulates the drawing of a single line of text, with optional rounded corners and an optional "override width", which overides the default width (margins + text width). """ def __init__( self, height, position ): """ Creates the underlying TransparentWindow and Cairo context. Position and height should be in pixels. """ # Use the maximum width that we can, i.e., the desktop width. width, _ = graphics.getDesktopSize() left, top = graphics.getDesktopOffset() xPos, yPos = position self.__window = TransparentWindow(xPos + left, yPos, width, height ) self.__context = self.__window.makeCairoContext() def getHeight( self ): """ LONGTERM TODO: Document this. """ return self.__window.getHeight() def draw( self, document ): """ Draws the text described by document. An updating call; at the end of this method, the displayed window should reflect the drawn content. """ width = document.ragWidth + layout.L_MARGIN + layout.R_MARGIN height = self.__window.getMaxHeight() cr = self.__context # Clear the areas where the corners of the rounded rectangle will be. cr.save() cr.set_source_rgba( 0, 0, 0, 0 ) cr.set_operator( cairo.OPERATOR_SOURCE ) cr.rectangle( width - rounded_rect.CORNER_RADIUS, height - rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS ) cr.rectangle( width - rounded_rect.CORNER_RADIUS, 0, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS ) cr.paint() # Draw the background rounded rectangle. corners = [] if document.roundUpperRight: corners.append( rounded_rect.UPPER_RIGHT ) if document.roundLowerRight: corners.append( rounded_rect.LOWER_RIGHT ) cr.set_source_rgba( *document.background ) rounded_rect.drawRoundedRect( context = cr, rect = ( 0, 0, width, height ), softenedCorners = corners ) cr.fill_preserve() cr.restore() # Next, draw the text. document.draw( layout.L_MARGIN, document.shrinkOffset, self.__context ) width = min( self.__window.getMaxWidth(), width ) height = min( self.__window.getMaxHeight(), height ) self.__window.setSize( width, height ) self.__window.update() def hide( self ): """ Clears the window's surface (making it disappear). """ # LONGTERM TODO: Clearing the surface, i.e., painting it # clear, seems like a potential performance bottleneck. self.__window.setSize( 1, 1 ) # Frankly, I don't know why this works, but after this # function, the resulting window is totally clear. I find it # odd, since the alpha value is not being set. It is a # wierdness of Cairo. -- Andrew self.__context.set_operator (cairo.OPERATOR_CLEAR) self.__context.paint () self.__context.set_operator (cairo.OPERATOR_OVER) self.__window.update()
class TextWindow: """ Encapsulates the drawing of a single line of text, with optional rounded corners and an optional "override width", which overides the default width (margins + text width). """ def __init__(self, height, position): """ Creates the underlying TransparentWindow and Cairo context. Position and height should be in pixels. """ # Use the maximum width that we can, i.e., the desktop width. width, _ = graphics.getDesktopSize() left, top = graphics.getDesktopOffset() xPos, yPos = position self.__window = TransparentWindow(xPos + left, yPos + top, width, height) self.__context = self.__window.makeCairoContext() def getHeight(self): """ LONGTERM TODO: Document this. """ return self.__window.getHeight() def draw(self, document): """ Draws the text described by document. An updating call; at the end of this method, the displayed window should reflect the drawn content. """ width = document.ragWidth + layout.L_MARGIN + layout.R_MARGIN height = self.__window.getMaxHeight() cr = self.__context # Clear the areas where the corners of the rounded rectangle will be. cr.save() cr.set_source_rgba(0, 0, 0, 0) cr.set_operator(cairo.OPERATOR_SOURCE) cr.rectangle(width - rounded_rect.CORNER_RADIUS, height - rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS) cr.rectangle(width - rounded_rect.CORNER_RADIUS, 0, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS) cr.paint() # Draw the background rounded rectangle. corners = [] if document.roundUpperRight: corners.append(rounded_rect.UPPER_RIGHT) if document.roundLowerRight: corners.append(rounded_rect.LOWER_RIGHT) cr.set_source_rgba(*document.background) rounded_rect.drawRoundedRect(context=cr, rect=(0, 0, width, height), softenedCorners=corners) cr.fill_preserve() cr.restore() # Next, draw the text. document.draw(layout.L_MARGIN, document.shrinkOffset, self.__context) width = min(self.__window.getMaxWidth(), width) height = min(self.__window.getMaxHeight(), height) self.__window.setSize(width, height) self.__window.update() def hide(self): """ Clears the window's surface (making it disappear). """ # LONGTERM TODO: Clearing the surface, i.e., painting it # clear, seems like a potential performance bottleneck. self.__window.setSize(1, 1) # Frankly, I don't know why this works, but after this # function, the resulting window is totally clear. I find it # odd, since the alpha value is not being set. It is a # wierdness of Cairo. -- Andrew self.__context.set_operator(cairo.OPERATOR_CLEAR) self.__context.paint() self.__context.set_operator(cairo.OPERATOR_OVER) self.__window.update()
class ParameterSuggestionWindow(object): """ Encapsulates the drawing of a single line of text, with optional rounded corners and an optional "override width", which overides the default width (margins + text width). """ def __init__(self, height, position): """ Creates the underlying TransparentWindow and Cairo context. Position and height should be in pixels. """ # Use the maximum width that we can, i.e., the desktop width. desk_width, desk_height = graphics.getDesktopSize() desk_left, desk_top = graphics.getDesktopOffset() xPos, yPos = position if yPos + height > desk_height: pass self.__window = TransparentWindow( xPos + desk_left, yPos + desk_top, desk_width, desk_height - desk_top - yPos) self.__context = self.__window.makeCairoContext() self.__is_visible = False self.__animatingShow = False self.__animatingHide = False self.__timeSinceDismissal = 0 self.__evtManager = EventManager.get() def getHeight(self): """ LONGTERM TODO: Document this. """ return self.__window.getHeight() def getPosition(self): """ LONGTERM TODO: Document this. """ return Position(self.__window.getX(), self.__window.getY()) def setPosition(self, x, y): """ LONGTERM TODO: Document this. """ self.__window.setPosition(x, y) def draw(self, document, activeIndex): """ Draws the text described by document. An updating call; at the end of this method, the displayed window should reflect the drawn content. """ def _computeWidth(doc): lines = [] for b in doc.blocks: lines.extend(b.lines) if len(lines) == 0: return 0 return max([l.xMax for l in lines]) def _computeHeight(doc): height = 0 for b in doc.blocks: height += b.height # for line in b.lines: # height += line.lineHeight return height width = _computeWidth(document) + layout.L_MARGIN + layout.R_MARGIN width = max(width, 300) height = document.height # _computeHeight(document) cr = self.__context # Clear the areas where the corners of the rounded rectangle will be. cr.save() cr.set_source_rgba(0, 0, 0, 0) cr.set_operator(cairo.OPERATOR_SOURCE) # IGNORE:E1101 @UndefinedVariable cr.rectangle(width - rounded_rect.CORNER_RADIUS, height - rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS) cr.rectangle(width - rounded_rect.CORNER_RADIUS, 0, rounded_rect.CORNER_RADIUS, rounded_rect.CORNER_RADIUS) cr.paint() """ # Draw the background rounded rectangle. corners = [] #corners.append( rounded_rect.UPPER_LEFT ) #if document.roundUpperRight: corners.append( rounded_rect.UPPER_RIGHT ) #if document.roundLowerRight: corners.append( rounded_rect.LOWER_RIGHT ) #if document.roundLowerLeft: corners.append( rounded_rect.LOWER_LEFT ) """ corners = { rounded_rect.UPPER_RIGHT: None, rounded_rect.LOWER_RIGHT: 14, rounded_rect.LOWER_LEFT: None } document.background = xmltextlayout.colorHashToRgba( layout.MAIN_BACKGROUND_COLOR) cr.set_source_rgba(*document.background) rounded_rect.drawRoundedRect(context=cr, rect=(0, 0, width, height), softenedCorners=corners) cr.fill_preserve() cr.set_source_rgba(*xmltextlayout.colorHashToRgba("#404040")) cr.set_line_width(1.0) if activeIndex is not None: bar_left = layout.L_MARGIN - 2 bar_width = width - bar_left - layout.L_MARGIN + 2 bar_height = document.blocks[0].height bar_top = activeIndex * bar_height + document.marginTop rounded_rect.drawRoundedRect(context=cr, rect=( bar_left, bar_top, bar_width, bar_height), softenedCorners=rounded_rect.ALL_CORNERS, radius=2) cr.fill_preserve() # cr.stroke() cr.restore() # Next, draw the text. document.draw(layout.L_MARGIN, document.shrinkOffset, self.__context) width = min(self.__window.getMaxWidth(), width) # height = document.blocks[0].height * len(document.blocks) #layout.PARAMETERSUGGESTION_SCALE[-1]*layout.HEIGHT_FACTOR #height = min( self.__window.getMaxHeight(), height ) #self.__window.setSize( width, height ) if not self.__is_visible and not self.__animatingShow: self.__animatingShow = True self.__animatingHide = False self.__is_visible = True self.__timeSinceDismissal = 0 with suppress(AssertionError): self.__evtManager.registerResponder( self.animationTick, "timer") else: # Just refreshing started = time.time() self.__window.setOpacity(MAX_OPACITY) # print time.time() - started self.__window.update() # print time.time() - started def hide(self, animated=True): """ Clears the window's surface (making it disappear). """ if not self.__is_visible: return if self.__animatingHide or self.__animatingShow: self.__onAnimationFinished() return # LONGTERM TODO: Clearing the surface, i.e., painting it # clear, seems like a potential performance bottleneck. #self.__window.setSize( 1, 1 ) # Frankly, I don't know why this works, but after this # function, the resulting window is totally clear. I find it # odd, since the alpha value is not being set. It is a # wierdness of Cairo. -- Andrew #self.__context.set_operator (cairo.OPERATOR_CLEAR) #self.__context.paint () #self.__context.set_operator (cairo.OPERATOR_OVER) # self.__window.update() if animated: self.__timeSinceDismissal = 0 self.__animatingHide = True self.__animatingShow = False self.__evtManager.registerResponder(self.animationTick, "timer") else: self.__window.hide() self.__animatingHide = False self.__animatingShow = False def animationTick(self, msPassed): """ Called on a timer event to animate the window fadeout """ self.__timeSinceDismissal += msPassed if self.__timeSinceDismissal > ANIMATION_TIME: if self.__animatingShow and self.__is_visible: self.__onAnimationFinished() return timeLeft = ANIMATION_TIME - self.__timeSinceDismissal frac = timeLeft / float(ANIMATION_TIME) opacity = int(MAX_OPACITY * frac) if self.__animatingHide: self.__window.setOpacity(opacity) if opacity == 0: self.__is_visible = False elif self.__animatingShow: self.__is_visible = True self.__window.setOpacity(MAX_OPACITY - opacity) self.__window.update() def __onAnimationFinished(self): self.__evtManager.removeResponder(self.animationTick) if self.__animatingHide: self.__animatingHide = False self.__window.hide() self.__is_visible = False elif self.__animatingShow: self.__animatingShow = False