Example #1
0
    def OnPaint(self, otherdc, otherwindow):
        """
            Paints all tabs into the passed DC and a copy of the backgrounds
            into a Bitmap to geneate the SmokeAndMirrors for other window
        """
        size   = self.Size
        bitmap = EmptyBitmap(*size)
        mdc    = MemoryDC()
        tab    = self.tabs[0].states[self.tabs[0].mode][0].GetBitmap(Size(self.tabwidth,self.tabheight))#.Draw(mdc,rect)
        tab    = ImageFromBitmap(tab)
        tab.ConvertAlphaToMask()
        tab    = BitmapFromImage(tab)
        mdc.SelectObject(tab)
        mdc.Brush = WHITE_BRUSH
        mdc.Pen   = TRANSPARENT_PEN
        mdc.DrawRectangle(0, 0, self.tabwidth, self.tabheight)
        mdc.SelectObject(bitmap)

        for i, tabobj in enumerate(self.tabs):
            s = 14 * i
            rect = Rect(s, s, self.tabwidth, self.tabheight)
            mdc.DrawBitmap(tab, s, s, True)
            tabobj.OnPaint(forcedrect = rect, otherdc = otherdc)

        mdc.SelectObject(NullBitmap)
#        otherdc.DrawBitmap(bitmap,0,0,True)
        bitmap.SetMask(Mask(bitmap, BLACK))
        ApplySmokeAndMirrors(otherwindow, bitmap)
Example #2
0
def createCharBitmap(setName, fontName, frgd, bkgd):

    global _cw, _ch

    # create device context
    dc = MemoryDC()
    # set font
    dc.SetFont(_fonts[fontName])
    # get font size
    _cw, _ch = dc.GetTextExtent(' ')
    BitmapSet = {}
    for c in _printableCharSet:
        # create bitmap
        bitmap = Bitmap(_cw, _ch, BITMAP_SCREEN_DEPTH)
        # select bitmap
        dc.SelectObject(bitmap)
        # set background
        dc.SetBackground(_brushes[bkgd])
        # clear bitmap
        dc.Clear()
        # set text color
        dc.SetTextForeground(_colours[frgd])
        # write character
        dc.DrawText(c, 0, 0)
        # record
        BitmapSet[c] = bitmap
    # release bitmap
    dc.SelectObject(NullBitmap)
    # record set
    _printableCharBitmaps[setName] = BitmapSet
    # done
    return
Example #3
0
    def CreateDC(self, loadBackground: bool, w: int, h: int) -> DC:
        """
        Create a DC, load the background on demand.

        @param loadBackground
        @param w : width of the frame.
        @param h :  height of the frame.

        @return DC
        """
        dc = MemoryDC()
        bm = self.__workingBitmap
        # cache the bitmap, to avoid creating a new at each refresh.
        # only recreate it if the size of the window has changed
        if (bm.GetWidth(), bm.GetHeight()) != (w, h):
            bm = self.__workingBitmap = Bitmap(w, h)
        dc.SelectObject(bm)
        if loadBackground:
            self.LoadBackground(dc, w, h)
        else:
            dc.SetBackground(Brush(self.GetBackgroundColour()))
            dc.Clear()
        self.PrepareDC(dc)

        return dc
Example #4
0
    def OnSize(self, event):
        #print ("OnSize", event)
        self.client_width, self.client_height = self.GetClientSize()
        self.inner_height = self.client_height
        self.BackBuffer = wx.Bitmap(self.client_width, self.client_height)
        self.dc_back = MemoryDC()
        self.dc_back.SelectObject(self.BackBuffer)
        #self.ResetHeightEstimate()
        # Estimate Height
        max_idx = self.datamodel.GetApproximateCount()
        if max_idx < 50:
            rowsample = range(max_idx)
        else:
            rowsample = set([
                self.datamodel.GetApproximatePos(random.randrange(0, max_idx))
                for _ in range(50)
            ])
        for pos in rowsample:
            self.heights.add(pos, self.datamodel.Get(pos).height)

        if self.displayed_rows:
            rowpos, y = self.displayed_rows[0].rowpos, self.displayed_rows[0].y
        else:
            rowpos, y = self.datamodel.GetFirstPos(), 0
        self.ScrollToLayout(rowpos, y)
        self.PaintRect(self.GetClientRect(), refresh=True)
        event.Skip()
Example #5
0
 def _BlankScreen(self, w, h, d):
     b = Bitmap(w, h, d)
     dc = MemoryDC()
     dc.SelectObject(b)
     self._clear(dc)
     dc.SelectObject(NullBitmap)
     return b
Example #6
0
    def LoadBackground(self, dc: DC, w: int, h: int):
        """
        Load the background image in the given dc.

        Args:
            dc:
            w:
            h:
        """
        mem = MemoryDC()
        mem.SelectObject(self.__backgroundBitmap)
        dc.Blit(0, 0, w, h, mem, 0, 0)
        mem.SelectObject(NullBitmap)
Example #7
0
def main(default=True):
    app = App()
    screen = ScreenDC()
    size = screen.GetSize()
    if default:
        size = (round(size[0] * 2.5), round(size[1] * 2.5))
    bmp = Bitmap(size[0], size[1])
    mem = MemoryDC(bmp)
    mem.Blit(0, 0, size[0], size[1], screen, 0, 0)
    del mem
    name = '{}.png'.format(str(randrange(1000)))
    fname = os.path.join(os.getcwd(), name)
    bmp.SaveFile(fname, BITMAP_TYPE_PNG)
    return fname
Example #8
0
    def write(self, oglObjects: List[OglClass]):
        """
        Write data

        Args:
            oglObjects:     list of exported objects
        """

        mediator: Mediator = self._ctrl
        mediator.deselectAllShapes()

        imageType: BitmapType     = WxImageFormat.toWxBitMapType(self._imageFormat)

        window:    ScrolledWindow = self._umlFrame
        context:   ClientDC       = ClientDC(window)
        memory:    MemoryDC       = MemoryDC()

        x, y = window.GetSize()
        emptyBitmap: Bitmap = Bitmap(x, y, -1)

        memory.SelectObject(emptyBitmap)
        memory.Blit(source=context, xsrc=0, height=y, xdest=0, ydest=0, ysrc=0, width=x)
        memory.SelectObject(NullBitmap)

        img:       Image = emptyBitmap.ConvertToImage()
        extension: str   = self._imageFormat.__str__()

        filename: str   = f'{self._outputFileName}.{extension}'
        status:   bool  = img.SaveFile(filename, imageType)
        if status is False:
            self.logger.error(f'Error on image write to {filename}')
Example #9
0
    def SaveBackground(self, dc: DC):
        """

        Args:
            dc: The DC to save
        """
        w, h = self.GetSize()
        bb = self.__backgroundBitmap
        if (bb.GetWidth(), bb.GetHeight()) != (w, h):
            bb = self.__backgroundBitmap = Bitmap(w, h)
        mem = MemoryDC()
        mem.SelectObject(bb)

        x, y = self.CalcUnscrolledPosition(0, 0)
        mem.Blit(0, 0, w, h, dc, x, y)

        mem.SelectObject(NullBitmap)
Example #10
0
 def TestText(bmp, text, x, y, name):
     # get reference to bitmap set
     b = _printableCharBitmaps[name]
     # get characters geometry
     cw, ch = b[' '].GetSize()
     # create device context
     dc = MemoryDC()
     # select
     dc.SelectObject(bmp)
     # draw text
     for c in text:
         dc.DrawBitmap(b[c], x * cw, y * ch)
         x += 1
     # release bitmap
     dc.SelectObject(NullBitmap)
     # done
     return
Example #11
0
    def SetText(self, text: str):
        """
        Set the text that the shape displays

        Args:
              text
        """
        self._text = text
        self._width, self._height = MemoryDC().GetTextExtent(text)
Example #12
0
 def __init__(self, rows, colums):
     self.bitmap = Bitmap(colums * _cw, rows * _ch, BITMAP_SCREEN_DEPTH)
     dc = MemoryDC()
     dc.SelectObject(self.bitmap)
     dc.SetBackground(_brushes['bgd'])
     dc.Clear()
     dc.SelectObject(NullBitmap)
     return
Example #13
0
    def onDrawMe(self, event: CommandEvent):

        extension: str = 'png'
        imageType: BitmapType = BITMAP_TYPE_PNG
        window: ScrolledWindow = self._diagramFrame
        context: ClientDC = ClientDC(window)
        memory: MemoryDC = MemoryDC()

        x, y = window.ClientSize
        emptyBitmap: Bitmap = Bitmap(x, y, -1)

        memory.SelectObject(emptyBitmap)
        memory.Blit(source=context, xsrc=0, height=y, xdest=0, ydest=0, ysrc=0, width=x)
        memory.SelectObject(NullBitmap)

        img: Image = emptyBitmap.ConvertToImage()
        filename: str = f'DiagramDump.{extension}'
        status: bool = img.SaveFile(filename, imageType)
Example #14
0
 def ClearBackground(self):
     """
     Clear the background image.
     """
     dc = MemoryDC()
     bb = self.__backgroundBitmap
     w, h = self.GetSize()
     if (bb.GetWidth(), bb.GetHeight()) != (w, h):
         bb = self.__backgroundBitmap = EmptyBitmap(w, h)
     dc.SelectObject(bb)
     dc.SetBackground(Brush(self.GetBackgroundColour()))
     dc.Clear()
     dc.SelectObject(NullBitmap)
Example #15
0
 def OnFacename(self, facename):
     idx = len(self.font_list)
     self.font_list.append(facename)
     w, h = self.GetTextExtentCached(idx)
     self.bitmaps[idx] = wx.Bitmap(w, h)
     dc = MemoryDC()
     dc.SelectObject(self.bitmaps[idx])
     dc.Clear()
     font = self.MakeFont(facename=facename)
     dc.SetFont(font)
     dc.DrawText(facename, 0, 0)
     wx.CallAfter(self.Append, facename, idx)
     return True
Example #16
0
 def createBufferBitmap(self, width, height):
     cw, ch = self.charSize
     self.bmpBuf = Bitmap(
         width * cw,  # bitmap width
         height * ch,  # bitmap heigh
         BITMAP_SCREEN_DEPTH)  # bitmap depth
     dc = MemoryDC()
     dc.SelectObject(self.bmpBuf)
     dc.SetBackground(self.brushes['bkgd'])
     dc.Clear()
     dc.SelectObject(NullBitmap)
     self.Panel.BackgroundBitmap = self.bmpBuf
     self.screenSize = width, height
     return
Example #17
0
    def _get_bitmap(self, bitmap, bitmap_to_draw, x, y, w, h, draw_frame=True):
        bitmap = bitmap.GetSubBitmap(
            Rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight()))

        dc = MemoryDC()
        bdc = BufferedDC(dc)
        bdc.SelectObject(bitmap)
        bdc.DrawBitmap(bitmap_to_draw, x, y)

        if draw_frame:
            # Black rect to support white pages
            bdc.SetPen(BLACK_PEN)
            bdc.SetBrush(TRANSPARENT_BRUSH)
            bdc.DrawRectangle(x, y, w, h)

            # Grey rect to support black pages
            bdc.SetPen(GREY_PEN)
            bdc.SetBrush(TRANSPARENT_BRUSH)
            bdc.DrawRectangle(x + 1, y + 1, w - 2, h - 2)

        bdc.SelectObject(NullBitmap)
        return bitmap
Example #18
0
 def _refresh(self):
     # get geometry
     X, Y = self.scroll
     cw, ch = self.charSize
     sl, sr, st, sb = self._borders
     cl, rw = self.screenSize
     # create device context
     dc = MemoryDC()               
     # select bitmap
     dc.SelectObject(self.bitmapBuffer)
     # clear buffer
     self._clear(dc)
     # draw _borders
     self.drawBorders(dc)
     # draw each lines
     for y, line in enumerate(self.textBuffer[Y:]):
         # check for last visible line
         if y+st >= rw-sb: break
         # get line number
         lineNumber = f'{y+Y:{sl-1}d}'
         # draw number
         for x, c in enumerate(lineNumber):
             # get character position
             u, v = x*cw, (y+st)*ch
             # draw character
             dc.DrawBitmap(self.CS.get(c, 'emp'), u, v)
         # draw line
         # x = 0 # empty line jumps straight to else case
         for x, c in enumerate(line[X:]+'¶'):
             # check for last visible character
             if x+sl >= cl-sr: break
             # check if character selected
             selected = self.isSelected(x+X, y+Y)
             # adjust display style
             style = 'sel' if selected else 'nrm'
             # get screen position
             u, v = (x+sl)*cw, (y+st)*ch
             # draw character
             dc.DrawBitmap(self.CS.get(c, style), u, v)
     # draw cursor
     self.drawCursor(dc)
     # done
     dc.SelectObject(NullBitmap)
     return
Example #19
0
    def SaveBackground(self, dc):
        """
        Save the given dc as the new background image.

        @param DC dc : the dc to save
        """
        w, h = self.GetSize()
        bb = self.__backgroundBitmap
        if (bb.GetWidth(), bb.GetHeight()) != (w, h):
            bb = self.__backgroundBitmap = Bitmap(w, h)
        mem = MemoryDC()
        mem.SelectObject(bb)

        if __version__ > "2.3.2":
            x, y = self.CalcUnscrolledPosition(0, 0)
            mem.Blit(0, 0, w, h, dc, x, y)
        else:
            mem.Blit(0, 0, w, h, dc, 0, 0)
        mem.SelectObject(NullBitmap)
Example #20
0
 def createBufferBitmap(self, width, height):
     # get geometry
     cw, ch = self.charSize
     # create bitmap buffer
     self.bmpBuf = Bitmap(
         width *cw,              # bitmap width
         height*ch,              # bitmap heigh
         BITMAP_SCREEN_DEPTH)    # bitmap depth
     # create device context
     dc = MemoryDC()               
     # select buffer
     dc.SelectObject(self.bmpBuf)
     # set background
     dc.SetBackground(self.brushes['bkgd'])
     # clear buffer
     dc.Clear()
     # release bitmap
     dc.SelectObject(NullBitmap)
     # hook BackgroundBitmap to bitmapBuffer handle
     self.Panel.BackgroundBitmap = self.bmpBuf
     # record geometry
     self.screenSize = width, height
     # done        
     return
Example #21
0
 def OnDrawItem(self, dc, rect, item, flags):
     idx = self.GetClientData(item)
     dc_img = MemoryDC()
     dc_img.SelectObject(self.bitmaps[idx])
     w, h = self.bitmaps[idx].GetWidth(), self.bitmaps[idx].GetHeight()
     dc.Blit(rect.left, rect.top, w, h, dc_img, 0, 0, logicalFunc=wx.AND)
Example #22
0
    def OnRefreshPanel(self, event):
        """
        Refresh dialog box

        """
        import time
        # constants
        backRed: int = 230
        backGreen: int = 255
        backBlue: int = 230  # Background color

        frontRed: int = 64
        frontGreen: int = 0
        frontBlue: int = 64  # Foreground color

        FADE_IN_LENGTH: int = 63
        self.logger.debug(f'Enter OnRefreshPanel')
        # Init memory buffer
        tdc: MemoryDC = MemoryDC()
        tdc.SelectObject(Bitmap(FrameWidth, FrameHeight))
        while not tdc.IsOk():
            time.sleep(0.05)
            tdc = MemoryDC()
            tdc.SelectObject(Bitmap(FrameWidth, FrameHeight))

        tdc.SetTextForeground(Colour(frontRed, frontGreen, frontBlue))
        tdc.SetBackground(
            Brush(Colour(backRed, backGreen, backBlue), BRUSHSTYLE_SOLID))
        tdc.Clear()
        font = tdc.GetFont()
        font.SetFamily(FONTFAMILY_MODERN)
        font.SetPointSize(12)
        tdc.SetFont(font)

        # Fade-in
        position = self.textPosition
        if position < FADE_IN_LENGTH:
            n = float(position) / float(FADE_IN_LENGTH)
            r = backRed - n * (backRed - frontRed)
            g = backGreen - n * (backGreen - frontGreen)
            b = backBlue - n * (backBlue - frontBlue)
            r = int(r)
            g = int(g)
            b = int(b)
            tdc.SetTextForeground(Colour(r, g, b))

        # Display text
        for j in range(1, len(self._textToShow)):
            # Draw text ?
            if position > FADE_IN_LENGTH:
                y = y0 + j * dy - (position - FADE_IN_LENGTH)
                if -dy < y < FrameHeight:
                    tdc.DrawText(self._textToShow[j], x0, y)
            else:  # Draw initial screen with fade in
                y = y0 + j * dy
                if -dy < y < FrameHeight:
                    tdc.DrawText(self._textToShow[j], x0, y)

        # Show memory dc to current dc (blit)
        dc = PaintDC(self._panel)
        dc.Blit(0, 0, FrameWidth, FrameHeight, tdc, 0, 0)
        tdc.SelectObject(NullBitmap)
        self.logger.debug(f'Exit OnRefreshPanel')
Example #23
0
 def createCharBitmaps(self):
     dc = MemoryDC()
     dc.SetFont(self.fonts['monospace'])
     cw, ch = dc.GetTextExtent(' ')
     self.charSize = cw, ch
     self.normalChars = {}
     for c in self.charSet:
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         dc.SelectObject(bitmap)
         dc.SetBackground(self.brushes['bkgd'])
         dc.Clear()
         dc.SetTextForeground(Colour(230, 230, 230))
         dc.DrawText(c, 0, 0)
         self.normalChars[c] = bitmap
     self.selectedChars = {}
     for c in self.charSet:
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         dc.SelectObject(bitmap)
         dc.SetBackground(Brush(Colour(70, 80, 90)))
         dc.Clear()
         dc.SetTextForeground(Colour(160, 160, 180))
         if c == ' ': dc.DrawText(c, 0, 0)
         else: dc.DrawText(c, 0, 0)
         self.selectedChars[c] = bitmap
     self.numberChars = {}
     for c in ' 0123456789':
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         dc.SelectObject(bitmap)
         dc.SetBackground(self.brushes['bkgd'])
         dc.Clear()
         dc.SetTextForeground(Colour(150, 150, 200))
         dc.DrawText(c, 0, 0)
         self.numberChars[c] = bitmap
     dc.SelectObject(NullBitmap)
     return
Example #24
0
    def refreshBuffer(self):
        # get geometry
        X, Y = self.scroll
        cw, ch = self.charSize
        sl, sr, st, sb = 5, 15, 5, 5
        cl, rw = self.screenSize
        # create device context
        dc = MemoryDC()
        # select
        dc.SelectObject(self.bitmapBuffer)
        # set background
        dc.SetBackground(self.brushes['bkgd'])
        # and clear buffer
        dc.Clear()
        # draw margins
        x3, x4 = 0 * cw, cl * cw
        x1, y1 = (sl - 0.5) * cw, (st - 0.5) * ch
        x2, y2 = (cl - sr + 0.5) * cw, (rw - sb + 0.5) * ch
        dc.SetPen(self.pens['margin'])
        dc.DrawLine(x1, y1, x1, y2)
        dc.DrawLine(x2, y1, x2, y2)
        dc.DrawLine(x3, y1, x4, y1)
        dc.DrawLine(x3, y2, x4, y2)

        # get block geometry
        r1, c1 = self.blockBegin
        r2, c2 = self.blockEnd
        block = False

        # draw text
        x, y = 0, 0
        for line in self.characterBuffer[Y:]:
            # draw line number
            self.drawText(dc, f'{y+Y:4d}', 0, y + st, self.numberChars)
            # the line is outside of the block
            if y + Y < r1 or y + Y > r2:
                self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
                # done
                y += 1
                if y + st >= rw - sb: break
                continue
            # block is inside if the line
            if r1 == r2:
                # draw normal text
                # self.drawText(dc, line[X:], x+sl, y+st, self.normalChars)
                # # block has size zero
                # if c1 == c2:
                #     # done
                #     y += 1
                #     if y+st >= rw-sb: break
                #     continue
                # block has finite size
                self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
                self.drawText(dc, line[X:c2], x + sl, y + st,
                              self.selectedChars)
                self.drawText(dc, line[X:c1], x + sl, y + st, self.normalChars)
                # done
                y += 1
                if y + st >= rw - sb: break
                continue
            # line at the start of the block
            if y + Y == r1:
                self.drawText(dc, line[X:], x + sl, y + st, self.selectedChars)
                self.drawText(dc, line[X:c1], x + sl, y + st, self.normalChars)
                # done
                y += 1
                if y + st >= rw - sb: break
                continue
            # line at the end of the block
            if y + Y == r2:
                self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
                self.drawText(dc, line[X:c2], x + sl, y + st,
                              self.selectedChars)
                # done
                y += 1
                if y + st >= rw - sb: break
                continue
            # line in the middle of the block
            self.drawText(dc, line[X:], x + sl, y + st, self.selectedChars)
            y += 1
            if y + st >= rw - sb: break

        # draw cursor
        x, y = self.cursor
        x1, y1, y2 = (x + sl) * cw, (y + st) * ch, (y + st + 1) * ch - 1
        dc.SetPen(self.pens['cursor'])
        dc.DrawLine(x1, y1, x1, y2)

        # done
        dc.SelectObject(NullBitmap)
        return
Example #25
0
    def Start(self):

        # define colors
        self.colours = {}
        self.colours['bkgd'] = Colour(52, 61, 70)
        self.colours['text'] = Colour(255, 255, 255)
        self.colours['numb'] = Colour(160, 160, 160)
        self.colours['sepr'] = Colour(200, 120, 120)
        self.colours['selbgd'] = Colour(92, 101, 110)
        self.colours['seltxt'] = Colour(255, 255, 255)

        # brushes
        self.brushes = {}
        # normal background
        b = Brush()
        b.SetStyle(BRUSHSTYLE_SOLID)
        b.SetColour(self.colours['bkgd'])
        self.brushes['bkgd'] = b

        # selected background
        b = Brush()
        b.SetStyle(BRUSHSTYLE_SOLID)
        b.SetColour(self.colours['selbgd'])
        self.brushes['selbgd'] = b

        # pens
        self.pens = {}
        p = Pen()
        p.SetColour(self.colours['sepr'])
        p.SetWidth(1)
        p.SetStyle(PENSTYLE_SOLID)
        self.pens['sepr'] = p

        # create device context to work on bitmaps
        dc = MemoryDC()

        # define font
        self.fonts = {}
        f = Font()
        f.SetFamily(FONTFAMILY_ROMAN)
        f.SetFaceName("Monospace")
        f.SetEncoding(FONTENCODING_DEFAULT)
        f.SetStyle(FONTSTYLE_NORMAL)
        f.SetWeight(FONTWEIGHT_NORMAL)
        f.SetUnderlined(False)
        f.SetPointSize(10)
        self.fonts['monospace'] = f

        # select font
        f = 'monospace'

        # get font size
        dc.SetFont(self.fonts[f])
        w, h = dc.GetTextExtent(' ')

        # build character dictionary
        self.rawChars = {}
        # standard printable ascii table
        for c in range(32, 126):
            self.rawChars[chr(c)] = None
        # extra characters (UK)
        self.rawChars['£'] = None
        # save character size
        self.rawChars['Size'] = w, h

        # set background color
        dc.SetBackground(self.brushes['bkgd'])

        # build characters bitmaps
        for C in self.rawChars.keys():
            if C == 'Size': continue
            # instanciate character bitmap
            self.rawChars[C] = Bitmap(w, h, BITMAP_SCREEN_DEPTH)
            # select bitmap
            dc.SelectObject(self.rawChars[C])
            # clear bitmap
            dc.Clear()
            # set text color
            dc.SetTextForeground(self.colours['text'])
            # draw character shape and color
            dc.DrawText(C, 0, 0)
        # done
        dc.SelectObject(NullBitmap)

        # build selected dictionary
        self.selChars = {}
        # standard printable ascii table
        for c in range(32, 126):
            self.selChars[chr(c)] = None
        # extra characters (UK)
        self.selChars['£'] = None
        # save character size
        self.selChars['Size'] = w, h

        # set background color
        dc.SetBackground(self.brushes['selbgd'])

        # build selected bitmaps
        for C in self.selChars.keys():
            if C == 'Size': continue
            # instanciate character bitmap
            self.selChars[C] = Bitmap(w, h, BITMAP_SCREEN_DEPTH)
            # select bitmap
            dc.SelectObject(self.selChars[C])
            # clear bitmap
            dc.Clear()
            # set text color
            dc.SetTextForeground(self.colours['seltxt'])
            # draw character shape and color
            dc.DrawText(C, 0, 0)
        # done
        dc.SelectObject(NullBitmap)

        # create bitmap buffer display and clear buffer
        self.bitmapBuffer = Bitmap(
            128 * w,  # bitmap width
            10 * h,  # bitmap height
            BITMAP_SCREEN_DEPTH)  # bitmap depth
        dc.SelectObject(self.bitmapBuffer)
        dc.SetBackground(self.brushes['bkgd'])
        dc.Clear()
        dc.SelectObject(NullBitmap)

        # reference BackgroundBitmap to bitmapBuffer
        self.Panel.BackgroundBitmap = self.bitmapBuffer

        # adjust frame position
        scrw, scrh = 3840, 1200  # screen size
        w, h = self.Panel.BackgroundBitmap.GetSize()
        self.Frame.SetPosition(Point(scrw / 4 - 128 * 8 / 2, 800))

        # draw text string
        dc.SelectObject(self.bitmapBuffer)

        t = list("hello")
        # select buffer
        # draw text
        X = 0
        w, h = self.rawChars['Size']
        for c in t:
            dc.DrawBitmap(self.rawChars[c], X, 0)
            X += w

        t = list("World!")
        # select buffer
        # draw text
        X = 0
        w, h = self.selChars['Size']
        for c in t:
            dc.DrawBitmap(self.selChars[c], X, h)
            X += w

        # release bitmap
        dc.SelectObject(NullBitmap)

        # done
        return
Example #26
0
class RowScroller(wx.Window):
    """ A VScrolledWindow that allows for pixel size scrolling
    """
    def __init__(self,
                 datamodel,
                 parent,
                 id=wx.ID_ANY,
                 label="",
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.NO_BORDER):
        super().__init__(parent)
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_CHAR, self.__OnChar)
        self.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
        self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
        self.line_size = 16  # Scroll this many pixels each time

        self.pixels_hidden_first_row = 0
        self.pixels_hidden_last_row = 0
        self.client_height = 0
        self.fixed_row = None
        self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
        self.current_pos = 0
        self.margin = 8
        #above this, use scroll directly without retrieving all intermediary rows
        self.scroll_row_threshold = 500
        self.datamodel = datamodel
        self.datamodel.INSERTED.subscribe(self.OnInserted)
        self.datamodel.DELETED.subscribe(self.OnRemoved)
        self.datamodel.MODIFIED.subscribe(self.OnModified)

        # New
        self.displayed_rows = deque()
        self.heights = RowHeigths()

    def SetFixedRow(self, rowpos):
        """ The current row is the row that stays fixed when rows are inserted, or removed"""
        self.fixed_row = rowpos
        self.PaintRect(self.GetClientRect())

    def GetFixedRow(self):
        return first(self.displayed_rows, lambda e: e.rowpos == self.fixed_row)

    def GetRowCached(self, row_id):
        result = self.datamodel.Get(row_id)
        self.heights.add(row_id, result.height)
        return result

    def ReindexDisplayedRows(self, reindex_func):
        if self.fixed_row is not None:
            self.fixed_row = reindex_func(self.fixed_row)
        for d in self.displayed_rows:
            d.rowpos = reindex_func(d.rowpos)
        self.heights.reindex(reindex_func)

    def OnInserted(self, insert_pos, reindex_func):
        self.ReindexDisplayedRows(reindex_func)
        fixed_row = self.GetFixedRow()
        if self.fixed_row:
            self.ScrollToLayout(self.fixed_row, fixed_row.y)
        else:
            self.ScrollToLayout(self.displayed_rows[0].rowpos,
                                self.displayed_rows[0].y)
        self.PaintRect(self.GetClientRect())
        wx.PostEvent(self, RowScrollerDisplayChanged())

    def OnRemoved(self, pos, reindex_func):
        if self.fixed_row == pos:
            self.fixed_row = None
        fixed_row = self.GetFixedRow()
        self.ReindexDisplayedRows(reindex_func)
        if self.fixed_row:
            self.ScrollToLayout(self.fixed_row, fixed_row.y)
        else:
            self.ScrollToLayout(self.displayed_rows[0].rowpos,
                                self.displayed_rows[0].y)
        self.PaintRect(self.GetClientRect())

    def OnModified(self, rowpos):
        disprow = first(self.displayed_rows, lambda e: e.rowpos == rowpos)
        if not disprow:
            return
        row = self.GetRowCached(rowpos)
        if row.height != disprow.height():
            fixed_row = self.GetFixedRow()
            if self.fixed_row:
                self.ScrollToLayout(self.fixed_row, fixed_row.y)
            else:
                self.ScrollToLayout(self.displayed_rows[0].rowpos,
                                    self.displayed_rows[0].y)
            self.PaintRect(self.GetClientRect())
        else:
            self.RepaintRow(rowpos)
            self.BlitToScreen(self.GetLayoutRect(rowpos))

    def GetLayoutRect(self, rowpos):
        disprow = first(self.displayed_rows, lambda e: e.rowpos == rowpos)
        result = wx.Rect(0, disprow.y, self.client_width, disprow.end_y)

    def PaintRow(self, dc, row, start_y, end_y):
        dc.SetClippingRegion(
            wx.Rect(
                (self.margin, start_y, self.client_width, end_y - start_y)))
        dc.Clear()
        row.Paint(dc, self.margin, start_y)
        dc.DestroyClippingRegion()

    def RepaintRow(self, rowpos):
        d = first(self.displayed_rows, lambda e: e.rowpos == rowpos)
        #rowpos, row, start_y, next_y = self.displayed_rows(rowpos)
        self.dc_back.SetClippingRegion(
            wx.Rect(self.margin, d.y, self.client_width, d.height()))
        self.dc_back.Clear()
        d.row.Paint(self.dc_back, self.margin, d.y)
        self.dc_back.DestroyClippingRegion()

    def BlitToScreen(self, rect):
        # TODO: Remove this..
        rect = self.GetClientRect()
        dc = wx.ClientDC(self)
        dc.Blit(rect.x, rect.y, rect.width, rect.height, self.dc_back, rect.x,
                rect.y)

    def PaintRect(self, rect, refresh=True):
        self.dc_back.SetClippingRegion(rect)
        self.dc_back.Clear()
        for displayed_row in self.displayed_rows:
            if displayed_row.y + displayed_row.row.height >= rect.top:
                self.PaintRow(self.dc_back, displayed_row.row, displayed_row.y,
                              displayed_row.y + displayed_row.row.height)
            if displayed_row.y >= rect.bottom:
                break
            if self.fixed_row is not None:
                self.dc_back.SetBrush(wx.TRANSPARENT_BRUSH)
                self.dc_back.SetPen(wx.BLACK_PEN)
                fixed_row = first(self.displayed_rows,
                                  lambda e: e.rowpos == self.fixed_row)
                if fixed_row:
                    self.dc_back.DrawRectangle(
                        1, fixed_row.y + 1, self.client_width - 2,
                        fixed_row.end_y - fixed_row.y - 2)
        self.BlitToScreen(rect)
        self.dc_back.DestroyClippingRegion()

    def ScrollBackBufferRow(self, start_y, end_y, distance):
        self.dc_back.Blit(0, start_y + distance, self.client_width,
                          end_y - start_y, self.dc_back, 0, start_y)

    def ScrollBackBuffer(self, distance):
        # do we need another image (e.g. test Blit for overlapping regions)
        self.dc_back.Blit(0, distance, self.client_width, self.inner_height,
                          self.dc_back, 0, 0)

    def HitTest(self, x, y):
        x -= self.margin
        for displayed_row in self.displayed_rows:
            if displayed_row.y <= y <= displayed_row.end_y:
                return (displayed_row.rowpos, ) + displayed_row.row.HitTest(
                    x, y - displayed_row.y)

    def OnSize(self, event):
        #print ("OnSize", event)
        self.client_width, self.client_height = self.GetClientSize()
        self.inner_height = self.client_height
        self.BackBuffer = wx.Bitmap(self.client_width, self.client_height)
        self.dc_back = MemoryDC()
        self.dc_back.SelectObject(self.BackBuffer)
        #self.ResetHeightEstimate()
        # Estimate Height
        max_idx = self.datamodel.GetApproximateCount()
        if max_idx < 50:
            rowsample = range(max_idx)
        else:
            rowsample = set([
                self.datamodel.GetApproximatePos(random.randrange(0, max_idx))
                for _ in range(50)
            ])
        for pos in rowsample:
            self.heights.add(pos, self.datamodel.Get(pos).height)

        if self.displayed_rows:
            rowpos, y = self.displayed_rows[0].rowpos, self.displayed_rows[0].y
        else:
            rowpos, y = self.datamodel.GetFirstPos(), 0
        self.ScrollToLayout(rowpos, y)
        self.PaintRect(self.GetClientRect(), refresh=True)
        event.Skip()

    def GetScrollPosition(self):
        return self.current_pos

    def GetInnerHeight(self):
        return self.inner_height

    def RefreshScrollBar(self):
        # idx = self.GetApproximateIndex(self.layout_rows[0][0])
        # This line was removed as it was unused. Would we need this?
        self.SetScrollbar(wx.VERTICAL,
                          self.current_pos,
                          self.inner_height,
                          self.heights.estimate() *
                          self.datamodel.GetApproximateCount(),
                          refresh=True)

    def Display(self, displayed_row, position):
        #print ("Displaying", displayed_row)
        self.displayed_rows.insert(position, displayed_row)

    def Hide(self, top=True):
        if top:
            result = self.displayed_rows.popleft()
        else:
            result = self.displayed_rows.pop()
        #print ("Hiding", result)

    def FillRemaingRows(self):
        if self.displayed_rows:
            # Expand bottom
            displayed_row = self.displayed_rows[-1]
            y = displayed_row.y
            rowpos = self.datamodel.GetNextPos(displayed_row.rowpos)
            while y + displayed_row.row.height < self.inner_height and rowpos is not None:
                row = self.GetRowCached(rowpos)
                y += displayed_row.row.height
                displayed_row = DisplayedRow(y, y + row.height, rowpos, row)
                self.Display(displayed_row, len(self.displayed_rows))
                rowpos = self.datamodel.GetNextPos(displayed_row.rowpos)
            # Expand top
            displayed_row = self.displayed_rows[0]
            y = displayed_row.y
            rowpos = self.datamodel.GetPrevPos(displayed_row.rowpos)
            while y > 0 and rowpos is not None:

                row = self.GetRowCached(rowpos)
                y -= row.height
                self.Display(DisplayedRow(y, y + row.height, rowpos, row), 0)
                rowpos = self.datamodel.GetPrevPos(rowpos)

    def ClearExtraRows(self):
        # Remove Top
        while self.displayed_rows and self.displayed_rows[
                0].y + self.displayed_rows[0].row.height <= 0:
            self.Hide(True)
        # Remove Bottom
        while self.displayed_rows and self.displayed_rows[
                -1].y >= self.inner_height:
            self.Hide(False)

    def ScrollToLayout(self, rowpos, start_px):
        """  Absolute scroll rows such that the row 'rowpos' is now at 'start_px' pixels
        from the top of the window (start_px can be negative).
        """
        y = start_px
        self.displayed_rows = deque()
        if rowpos is not None:
            row = self.GetRowCached(rowpos)
            self.displayed_rows.append(
                DisplayedRow(y, y + row.height, rowpos, row))
        self.FillRemaingRows()
        self.RefreshScrollBar()

    def _ScrollNoRefresh(self, distance):
        ''' Relative Scroll distance in pixels (negative is up) '''
        if distance == 0:
            return 0
        if distance > 0:
            distance_moved = self.MoveDownBottom(distance)
            self.MoveDownTop(distance_moved)
        else:
            distance_moved = self.MoveUpTop(-distance)
            self.MoveUpBottom(distance_moved)
        distance_moved = math.copysign(distance_moved, distance)
        self.current_pos = max(
            min(self.current_pos + distance_moved, self.estimated_height), 0)
        return distance_moved

    def _RefreshAfterScrolling(self, distance):
        ''' Refresh after scrolling distance pixels (negative is up) '''
        if abs(distance) < self.inner_height:
            if distance > 0:
                paint_rect = wx.Rect(0, self.inner_height - distance,
                                     self.client_width, self.client_height)
            else:
                paint_rect = wx.Rect(0, 0, self.client_width, -distance)
            self.ScrollBackBuffer(-distance)
            self.ScrollWindow(0, -distance)
        else:
            paint_rect = wx.Rect(0, 0, self.client_width, self.inner_height)
        self.PaintRect(paint_rect, refresh=True)
        self.RefreshScrollBar()

    def _ScrollUntil(self, distance_increment, fct):
        ''' Relative Scroll distance_increment in pixels until fct returns True.
            Then, refresh the screen.
            This can be used for "Scroll until cursor is in view"
        '''
        distance_moved = 0
        while not fct:
            distance_moved += self._ScrollNoRefresh(distance_increment)

    def ScrollIntoViewXY(self, row_id, x, y):
        return self.ScrollIntoRectView(row_id, wx.Rect(x, y, 0, 0))

    def ScrollIntoRectView(self, row_id, rect):
        # FIXME
        print("ScrollIntoRectView")
        first, last = self.layout_row_ids[0], self.layout_row_ids[-1]
        if row_id > last:
            #self.ScrollIntoViewXY2(row_id, rect.left, rect.bottom)
            self.ScrollToLayout(row_id, self.inner_height - 1 - rect.bottom)
            self.PaintRect(self.GetClientRect(), refresh=True)
            self.RefreshScrollBar()

        elif row_id < first:
            self.ScrollToLayout(row_id, -rect.top)
            self.PaintRect(self.GetClientRect(), refresh=True)
            self.RefreshScrollBar()
            #self.ScrollIntoViewXY2(row_id, rect.left, rect.top)
        elif row_id == last:
            missing = max(rect.bottom - self.PixelsVisibleLastRow(), 0)
            distance_moved = self.Scroll(missing)
        elif row_id == first:
            missing = max(self.PixelsHiddenFirstRow() - rect.top, 0)
            distance_moved = self.Scroll(-missing)

    def _ScrollRows(self, distance):
        for displayed_row in self.displayed_rows:
            displayed_row.y -= distance
            displayed_row.end_y -= distance

    def Scroll(self, distance, bounded_scolling=True):
        if not self.displayed_rows:
            return
        self._ScrollRows(distance)
        self.FillRemaingRows()
        scrolled_pixels = distance
        # Now we might have scrolled too far
        if bounded_scolling:
            if distance < 0:
                if self.displayed_rows[0].y > 0:
                    dist = self.displayed_rows[0].y
                    self._ScrollRows(dist)
                    scrolled_pixels += dist
            elif distance > 0:
                if self.displayed_rows[
                        -1].y < self.inner_height - self.displayed_rows[
                            -1].row.height:
                    dist = self.displayed_rows[-1].y - (
                        self.inner_height - self.displayed_rows[-1].row.height)
                    self._ScrollRows(dist)
                    scrolled_pixels += dist
            self.FillRemaingRows()
        self.ClearExtraRows()
        self.current_pos += scrolled_pixels
        paint_rect = wx.Rect(0, 0, self.client_width, self.inner_height)
        self.PaintRect(paint_rect, refresh=True)
        self.RefreshScrollBar()
        wx.PostEvent(self, RowScrollerScrolledEvent())

    def ScrollTo(self, pos):
        '''Absolute scroll pos in pixels'''
        # pos varies between 0 and self.estimated_height - self.inner_height
        if abs(pos - self.current_pos) < 1000:
            # Avoid flickering, when scrolling small distances by doing a relative scroll
            return self.Scroll(pos - self.current_pos)
        else:
            estimated_row_height = self.heights.estimate()
            rowpos = self.datamodel.GetApproximatePos(
                pos // int(estimated_row_height))
            hidden_first_row = pos % int(estimated_row_height)
            self.ScrollToLayout(rowpos, hidden_first_row)
        self.PaintRect(self.GetClientRect(), refresh=True)
        self.current_pos = pos
        self.RefreshScrollBar()
        wx.PostEvent(self, RowScrollerScrolledEvent())

    def OnScroll(self, event):
        event_type = event.GetEventType()
        if event_type == wx.EVT_SCROLLWIN_PAGEDOWN.typeId:
            pos = event.GetPosition()
            self.Scroll(self.inner_height)
        elif event_type == wx.EVT_SCROLLWIN_PAGEUP.typeId:
            self.Scroll(-self.inner_height)
        elif event_type == wx.EVT_SCROLLWIN_THUMBTRACK.typeId:
            pos = event.GetPosition()
            self.ScrollTo(pos)
        elif event_type == wx.EVT_SCROLLWIN_THUMBRELEASE.typeId:
            pos = event.GetPosition()
            self.ScrollTo(pos)

    def OnMouseWheel(self, event):
        rotation = event.GetWheelRotation()
        delta = event.GetWheelDelta()
        self.Scroll(-self.line_size * (rotation / delta))

    def __OnChar(self, event):
        key_code = event.GetKeyCode()
        if key_code == WXK_PAGEDOWN:
            self.Scroll(self.inner_height)
        elif key_code == WXK_PAGEUP:
            self.Scroll(-self.inner_height)
        elif key_code == WXK_UP:
            self.Scroll(-self.line_size)
        elif key_code == WXK_DOWN:
            self.Scroll(self.line_size)
        event.Skip()
Example #27
0
    def CalcLayout(self):
        """
        Calculates the layout and height of the pannel based off of it's
        width and the size of the elements
        """
        dc = MemoryDC()

        #x and y are the cursor for were the next item will be placed
        #padx and pady are just local refs to padding.x and padding.y
        x, y = padx, pady = self.padding

        sz = self.Size

        linkfont = self.linkfont
        minorfont = self.minorfont
        majorfont = self.majorfont

        licon = self.licon
        link = self.link

        #Positiong the service icon and the status/close icon to the left or
        #   right respectivly
        self.liconpos = Point(x, y)
        self.riconpos = Point(sz.width - 16 - padx, y)

        #incriment x position to right of icon
        x += licon.Width + padx

        #Which is taller, the label or the icon
        h = max(majorfont.Height, 16)

        #Place title rect with the erlier calculated values and width whats left
        #   of the overall width for the width left for the label
        self.titlerect = Rect(x, y, sz.width - 4 * padx - licon.Width - 16, h)

        #incriment y to below the filled space
        y += h + pady

        #Find the link width because it's needed to know how much room the
        #   reason rect needs
        linkwidth = GetTextWidth(link, linkfont)

        #Determine the horizantal space left for the reason, then wrap it
        reasonwidth = sz.width - x - (linkwidth + 2 * padx)
        reason = self.reason() if callable(self.reason) else self.reason
        wrappedreason = self.wrappedreason = Wrap(reason, reasonwidth,
                                                  minorfont, dc)

        #Get the height needed for the label from the wraped string
        reasonheight = dc.GetMultiLineTextExtent(wrappedreason, minorfont)[1]

        #combine into a rectangle
        self.reasonrect = Rect(x, y, reasonwidth, reasonheight)

        #Figure the rest of the link size information
        self.linksize = Size(linkwidth, linkfont.LineHeight)

        #figure out the height the panel has to be in order to fit the content
        h = max(y + reasonheight + pady, self.liconsize + 2 * padx)

        newSize = Size(self.MinSize.width, h)
        if self.MinSize != newSize:
            self.MinSize = newSize

        self.Refresh()
Example #28
0
 def createCharBitmaps(self):
     # create device context
     dc = MemoryDC()               
     # set font
     dc.SetFont(self.fonts['monospace'])
     # get font size (monospace)
     cw, ch = dc.GetTextExtent(' ')
     # record geometry
     self.charSize = cw, ch
     # NORMAL CHARACTERS
     self.normalChars = {}
     # create bitmaps
     for c in self.charSet:
         # create black and white bitmap
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         # select bitmap
         dc.SelectObject(bitmap)
         # set background
         dc.SetBackground(self.brushes['bkgd'])
         # clear bitmap
         dc.Clear()
         # set text color
         dc.SetTextForeground(Colour(230,230,230))
         # write character
         dc.DrawText(c,0,0)
         # create reference to bitmap
         self.normalChars[c] = bitmap
     # SELECTED CHARACTERS
     self.selectedChars = {}
     # create bitmaps
     for c in self.charSet:
         # create black and white bitmap
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         # select bitmap
         dc.SelectObject(bitmap)
         # set background
         dc.SetBackground(Brush(Colour(70, 80, 90)))
         # clear bitmap
         dc.Clear()
         # set text color
         dc.SetTextForeground(Colour(160,160,180))
         # write character
         dc.DrawText(c,0,0)
         # create reference to bitmap
         self.selectedChars[c] = bitmap
     # NUMBER CHARACTERS
     self.numberChars = {}
     # create bitmaps
     for c in ' 0123456789':
         # create black and white bitmap
         bitmap = Bitmap(cw, ch, BITMAP_SCREEN_DEPTH)
         # select bitmap
         dc.SelectObject(bitmap)
         # set background
         dc.SetBackground(self.brushes['bkgd'])
         # clear bitmap
         dc.Clear()
         # set text color
         dc.SetTextForeground(Colour(150,150,200))
         # write character
         dc.DrawText(c,0,0)
         # create reference to bitmap
         self.numberChars[c] = bitmap
     # release bitmap
     dc.SelectObject(NullBitmap)
     # done
     return
Example #29
0
 def refreshBuffer(self):
     X, Y = self.scroll
     cw, ch = self.charSize
     sl, sr, st, sb = 5, 15, 5, 5
     cl, rw = self.screenSize
     dc = MemoryDC()
     dc.SelectObject(self.bmpBuf)
     dc.SetBackground(self.brushes['bkgd'])
     dc.Clear()
     x3, x4 = 0 * cw, cl * cw
     x1, y1 = (sl - 0.5) * cw, (st - 0.5) * ch
     x2, y2 = (cl - sr + 0.5) * cw, (rw - sb + 0.5) * ch
     dc.SetPen(self.pens['margin'])
     dc.DrawLine(x1, y1, x1, y2)
     dc.DrawLine(x2, y1, x2, y2)
     dc.DrawLine(x3, y1, x4, y1)
     dc.DrawLine(x3, y2, x4, y2)
     c1, r1, c2, r2 = self.getBlockGeometry()
     dc.SetBrush(Brush(Colour(100, 100, 100)))
     dc.SetPen(self.pens['transparent'])
     x, y = 0, -1
     for line in self.chrBuf[Y:]:
         y += 1
         if y + st >= rw - sb: break
         self.drawText(dc, f'{y+Y:4d}', 0, y + st, self.numberChars)
         if y + Y < r1 or y + Y > r2:
             self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
             continue
         if r1 == r2:
             self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
             self.drawText(dc, line[X:c2], x + sl, y + st,
                           self.selectedChars)
             self.drawText(dc, line[X:c1], x + sl, y + st, self.normalChars)
             continue
         if y + Y == r1:
             self.drawText(dc, line[X:] + '¶', x + sl, y + st,
                           self.selectedChars)
             self.drawText(dc, line[X:c1], x + sl, y + st, self.normalChars)
             continue
         if y + Y == r2:
             self.drawText(dc, line[X:], x + sl, y + st, self.normalChars)
             self.drawText(dc, line[X:c2], x + sl, y + st,
                           self.selectedChars)
             continue
         self.drawText(dc, line[X:] + '¶', x + sl, y + st,
                       self.selectedChars)
     x, y = self.cursor
     x1, y1, y2 = (x + sl) * cw, (y + st) * ch, (y + st + 1) * ch - 1
     dc.SetPen(self.pens['cursor'])
     dc.DrawLine(x1, y1, x1, y2)
     dc.SelectObject(NullBitmap)
     return
Example #30
0
    def refreshBuffer(self):
        # get geometry
        X, Y = self.scroll
        cw, ch = self.charSize
        sl, sr, st, sb = 5, 15, 5, 5
        cl, rw = self.screenSize
        # create device context
        dc = MemoryDC()               
        # select
        dc.SelectObject(self.bmpBuf)
        # set background
        dc.SetBackground(self.brushes['bkgd'])
        # and clear buffer
        dc.Clear()
        # draw margins
        x3, x4 = 0*cw, cl*cw
        x1, y1 = (sl-0.5)*cw, (st-0.5)*ch
        x2, y2 = (cl-sr+0.5)*cw, (rw-sb+0.5)*ch
        dc.SetPen(self.pens['margin'])
        dc.DrawLine(x1, y1, x1, y2)
        dc.DrawLine(x2, y1, x2, y2)
        dc.DrawLine(x3, y1, x4, y1)
        dc.DrawLine(x3, y2, x4, y2)
        # get block geometry
        c1, r1, c2, r2 = self.getBlockGeometry()
        # set brush
        dc.SetBrush(Brush(Colour(100,100,100)))
        dc.SetPen(self.pens['transparent'])
        # draw text
        x, y = 0, -1
        for line in self.chrBuf[Y:]:
            y += 1
            if y+st >= rw-sb: break
            # draw line number
            self.drawText(dc, f'{y+Y:4d}', 0, y+st, self.numberChars)
            # the line is outside of the block
            if y+Y < r1 or y+Y > r2:
                self.drawText(dc, line[X:], x+sl, y+st, self.normalChars)
                continue
            # block is inside if the line
            if r1 == r2:
                self.drawText(dc, line[X:],   x+sl, y+st, self.normalChars)
                self.drawText(dc, line[X:c2], x+sl, y+st, self.selectedChars)
                self.drawText(dc, line[X:c1], x+sl, y+st, self.normalChars)
                continue
            # line at the start of the block
            if y+Y == r1:
                self.drawText(dc, line[X:]+'¶',   x+sl, y+st, self.selectedChars)
                self.drawText(dc, line[X:c1], x+sl, y+st, self.normalChars)
                continue
            # line at the end of the block
            if y+Y == r2:
                self.drawText(dc, line[X:],   x+sl, y+st, self.normalChars)
                self.drawText(dc, line[X:c2], x+sl, y+st, self.selectedChars)
                continue
            # line is inside the block
            self.drawText(dc, line[X:]+'¶', x+sl, y+st, self.selectedChars)

        # draw cursor
        x, y = self.cursor
        x1, y1, y2 = (x+sl)*cw, (y+st)*ch, (y+st+1)*ch-1
        dc.SetPen(self.pens['cursor'])
        dc.DrawLine(x1, y1, x1, y2)
        # done
        dc.SelectObject(NullBitmap)
        return
Example #31
0
 def _createCharBitmap(self, name, font, foreground, background):
     # create device context
     dc = MemoryDC()               
     # set font
     dc.SetFont(self._fonts[font])
     # get font size
     _cw, _ch = dc.GetTextExtent(' ')
     BitmapSet = {}
     for c in self._CharSet:
         # create bitmap
         bitmap = Bitmap(_cw, _ch, BITMAP_SCREEN_DEPTH)
         # select bitmap
         dc.SelectObject(bitmap)
         # set background
         dc.SetBackground(self._brushes[background])
         # clear bitmap
         dc.Clear()
         # set text color
         dc.SetTextForeground(self._colours[foreground])
         # record reference
         BitmapSet[c] = bitmap
         # check alternate drawing 1
         if name == 'nrm' and c == '¶':
             dc.DrawText(' ',0,0)
             continue
         # check alternate drawing 2
         if name == 'sel' and c == ' ':
             dc.DrawText('·',0,0)
             continue
         # draw character
         dc.DrawText(c,0,0) 
     # release bitmap
     dc.SelectObject(NullBitmap)
     # record set
     self._CharBitmaps[name] = BitmapSet
     # done
     return