⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatcanvas.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:

    def SetText(self, String):
        """
        Re-sets the text displayed by the object

        In the case of the ScaledTextBox, it will re-do the layout as appropriate

        Note: only tested with the ScaledTextBox

        """

        self.String = String
        self.LayoutText()

    def LayoutText(self):
        """
        A dummy method to re-do the layout of the text.

        A derived object needs to override this if required.

        """
        pass

    ## store the function that shift the coords for drawing text. The
    ## "c" parameter is the correction for world coordinates, rather
    ## than pixel coords as the y axis is reversed
    ## pad is the extra space around the text
    ## if world = 1, the vertical shift is done in y-up coordinates
    ShiftFunDict = {'tl': lambda x, y, w, h, world=0, pad=0: (x + pad,     y + pad - 2*world*pad),
                    'tc': lambda x, y, w, h, world=0, pad=0: (x - w/2,     y + pad - 2*world*pad), 
                    'tr': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y + pad - 2*world*pad), 
                    'cl': lambda x, y, w, h, world=0, pad=0: (x + pad,     y - h/2 + world*h), 
                    'cc': lambda x, y, w, h, world=0, pad=0: (x - w/2,     y - h/2 + world*h), 
                    'cr': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y - h/2 + world*h),
                    'bl': lambda x, y, w, h, world=0, pad=0: (x + pad,     y - h + 2*world*h - pad + world*2*pad) ,
                    'bc': lambda x, y, w, h, world=0, pad=0: (x - w/2,     y - h + 2*world*h - pad + world*2*pad) , 
                    'br': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y - h + 2*world*h - pad + world*2*pad)}

class Text(DrawObject, TextObjectMixin):
    """
    This class creates a text object, placed at the coordinates,
    x,y. the "Position" argument is a two charactor string, indicating
    where in relation to the coordinates the string should be oriented.

    The first letter is: t, c, or b, for top, center and bottom The
    second letter is: l, c, or r, for left, center and right The
    position refers to the position relative to the text itself. It
    defaults to "tl" (top left).

    Size is the size of the font in pixels, or in points for printing
    (if it ever gets implimented). Those will be the same, If you assume
    72 PPI.

    Family:
        Font family, a generic way of referring to fonts without
        specifying actual facename. One of:
            wx.DEFAULT:  Chooses a default font. 
            wx.DECORATIVE: A decorative font. 
            wx.ROMAN: A formal, serif font. 
            wx.SCRIPT: A handwriting font. 
            wx.SWISS: A sans-serif font. 
            wx.MODERN: A fixed pitch font.
        NOTE: these are only as good as the wxWindows defaults, which aren't so good.
    Style:
        One of wx.NORMAL, wx.SLANT and wx.ITALIC.
    Weight:
        One of wx.NORMAL, wx.LIGHT and wx.BOLD.
    Underline:
        The value can be True or False. At present this may have an an
        effect on Windows only.

    Alternatively, you can set the kw arg: Font, to a wx.Font, and the
    above will be ignored.
    
    The size is fixed, and does not scale with the drawing.

    The hit-test is done on the entire text extent

    """
    
    def __init__(self,String, xy,
                 Size =  12,
                 Color = "Black",
                 BackgroundColor = None,
                 Family = wx.MODERN,
                 Style = wx.NORMAL,
                 Weight = wx.NORMAL,
                 Underline = False,
                 Position = 'tl',
                 InForeground = False,
                 Font = None):
        
        DrawObject.__init__(self,InForeground)

        self.String = String
        # Input size in in Pixels, compute points size from PPI info.
        # fixme: for printing, we'll have to do something a little different
        self.Size = int(round(72.0 * Size / ScreenPPI))

        self.Color = Color
        self.BackgroundColor = BackgroundColor

        if not Font:
            FaceName = ''
        else:
            FaceName           =  Font.GetFaceName()           
            Family             =  Font.GetFamily()
            Size               =  Font.GetPointSize()          
            Style              =  Font.GetStyle()
            Underlined         =  Font.GetUnderlined()         
            Weight             =  Font.GetWeight()
        self.SetFont(Size, Family, Style, Weight, Underline, FaceName)

        self.BoundingBox = array((xy, xy),Float)

        self.XY = asarray(xy)
        self.XY.shape = (2,)

        (self.TextWidth, self.TextHeight) = (None, None)
        self.ShiftFun = self.ShiftFunDict[Position]

    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
        XY = WorldToPixel(self.XY)
        dc.SetFont(self.Font)
        dc.SetTextForeground(self.Color)
        if self.BackgroundColor:
            dc.SetBackgroundMode(wx.SOLID)
            dc.SetTextBackground(self.BackgroundColor)
        else:
            dc.SetBackgroundMode(wx.TRANSPARENT)
        if self.TextWidth is None or self.TextHeight is None:
            (self.TextWidth, self.TextHeight) = dc.GetTextExtent(self.String)
        XY = self.ShiftFun(XY[0], XY[1], self.TextWidth, self.TextHeight)
        dc.DrawTextPoint(self.String, XY)
        if HTdc and self.HitAble:
            HTdc.SetPen(self.HitPen)
            HTdc.SetBrush(self.HitBrush)
            HTdc.DrawRectanglePointSize(XY, (self.TextWidth, self.TextHeight) )

class ScaledText(DrawObject, TextObjectMixin):
    """
    This class creates a text object that is scaled when zoomed.  It is
    placed at the coordinates, x,y. the "Position" argument is a two
    charactor string, indicating where in relation to the coordinates
    the string should be oriented.

    The first letter is: t, c, or b, for top, center and bottom The
    second letter is: l, c, or r, for left, center and right The
    position refers to the position relative to the text itself. It
    defaults to "tl" (top left).

    Size is the size of the font in world coordinates.

    Family:
        Font family, a generic way of referring to fonts without
        specifying actual facename. One of:
            wx.DEFAULT:  Chooses a default font. 
            wx.DECORATI: A decorative font. 
            wx.ROMAN: A formal, serif font. 
            wx.SCRIPT: A handwriting font. 
            wx.SWISS: A sans-serif font. 
            wx.MODERN: A fixed pitch font.
        NOTE: these are only as good as the wxWindows defaults, which aren't so good.
    Style:
        One of wx.NORMAL, wx.SLANT and wx.ITALIC.
    Weight:
        One of wx.NORMAL, wx.LIGHT and wx.BOLD.
    Underline:
        The value can be True or False. At present this may have an an
        effect on Windows only.

    Alternatively, you can set the kw arg: Font, to a wx.Font, and the
    above will be ignored. The size of the font you specify will be
    ignored, but the rest of its attributes will be preserved.
    
    The size will scale as the drawing is zoomed.

    Bugs/Limitations:

    As fonts are scaled, the do end up a little different, so you don't
    get exactly the same picture as you scale up and doen, but it's
    pretty darn close.
    
    On wxGTK1 on my Linux system, at least, using a font of over about
    3000 pts. brings the system to a halt. It's the Font Server using
    huge amounts of memory. My work around is to max the font size to
    3000 points, so it won't scale past there. GTK2 uses smarter font
    drawing, so that may not be an issue in future versions, so feel
    free to test. Another smarter way to do it would be to set a global
    zoom limit at that point.

    The hit-test is done on the entire text extent. This could be made
    optional, but I haven't gotten around to it.

    """
    
    def __init__(self, String, XY , Size,
                 Color = "Black",
                 BackgroundColor = None,
                 Family = wx.MODERN,
                 Style = wx.NORMAL,
                 Weight = wx.NORMAL,
                 Underline = False,
                 Position = 'tl',
                 Font = None,
                 InForeground = False):
        
        DrawObject.__init__(self,InForeground)

        self.String = String
        self.XY = array( XY, Float)
        self.XY.shape = (2,)
        self.Size = Size     
        self.Color = Color
        self.BackgroundColor = BackgroundColor
        self.Family = Family   
        self.Style = Style    
        self.Weight = Weight   
        self.Underline = Underline
        if not Font:
            self.FaceName = ''
        else:
            self.FaceName           =  Font.GetFaceName()           
            self.Family             =  Font.GetFamily()    
            self.Style              =  Font.GetStyle()     
            self.Underlined         =  Font.GetUnderlined()         
            self.Weight             =  Font.GetWeight()    

        # Experimental max font size value on wxGTK2: this works OK on
        # my system. If it's a lot  larger, there is a crash, with the
        # message:
        #
        # The application 'FloatCanvasDemo.py' lost its
        # connection to the display :0.0; most likely the X server was
        # shut down or you killed/destroyed the application.
        #
        # Windows and OS-X seem to be better behaved in this regard.
        # They may not draw it, but they don't crash either!
        self.MaxFontSize = 1000
        
        self.ShiftFun = self.ShiftFunDict[Position]

        self.CalcBoundingBox()

    def LayoutText(self):
        # This will be called when the text is re-set
        # nothing much to be done here
        self.CalcBoundingBox()

    def CalcBoundingBox(self):
        ## this isn't exact, as fonts don't scale exactly.
        dc = wx.MemoryDC()
        bitmap = wx.EmptyBitmap(1, 1)
        dc.SelectObject(bitmap) #wxMac needs a Bitmap selected for GetTextExtent to work.
        DrawingSize = 40 # pts This effectively determines the resolution that the BB is computed to.
        ScaleFactor = float(self.Size) / DrawingSize
        dc.SetFont(self.SetFont(DrawingSize, self.Family, self.Style, self.Weight, self.Underline, self.FaceName) )
        (w,h) = dc.GetTextExtent(self.String)
        w = w * ScaleFactor
        h = h * ScaleFactor
        x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world = 1)
        self.BoundingBox = array(((x, y-h ),(x + w, y)),Float)
        
    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
        (X,Y) = WorldToPixel( (self.XY) )

        # compute the font size:
        Size = abs( ScaleWorldToPixel( (self.Size, self.Size) )[1] ) # only need a y coordinate length
        ## Check to see if the font size is large enough to blow up the X font server
        ## If so, limit it. Would it be better just to not draw it?
        ## note that this limit is dependent on how much memory you have, etc.
        Size = min(Size, self.MaxFontSize)
        dc.SetFont(self.SetFont(Size, self.Family, self.Style, self.Weight, self.Underline, self.FaceName))
        dc.SetTextForeground(self.Color)
        if self.BackgroundColor:
            dc.SetBackgroundMode(wx.SOLID)
            dc.SetTextBackground(self.BackgroundColor)
        else:
            dc.SetBackgroundMode(wx.TRANSPARENT)
        (w,h) = dc.GetTextExtent(self.String)
        # compute the shift, and adjust the coordinates, if neccesary
        # This had to be put in here, because it changes with Zoom, as
        # fonts don't scale exactly.
        xy = self.ShiftFun(X, Y, w, h)

        dc.DrawTextPoint(self.String, xy)
        if HTdc and self.HitAble:
            HTdc.SetPen(self.HitPen)
            HTdc.SetBrush(self.HitBrush)
            HTdc.DrawRectanglePointSize(xy, (w, h) )

class ScaledTextBox(DrawObject, TextObjectMixin):
    """
    This class creates a TextBox object that is scaled when zoomed.  It is
    placed at the coordinates, x,y.

    If the Width parameter is defined, the text will be wrapped to the width given.

    A Box can be drawn around the text, be specifying:
    LineWidth and/or  FillColor 

    A space(margin) can be put all the way around the text, be specifying:
    the PadSize argument in world coordinates.

    The spacing between lines can be adjusted with the:
    LineSpacing argument.

    The "Position" argument is a two character string, indicating where
    in relation to the coordinates the Box should be oriented.
    -The first letter is: t, c, or b, for top, center and bottom.
    -The second letter is: l, c, or r, for left, center and right The
    position refers to the position relative to the text itself. It
    defaults to "tl" (top left).

    Size is the size of the font in world coordinates.

    Family:
        Font family, a generic way of referring to fonts without
        specifying actual facename. One of:
            wx.DEFAULT:  Chooses a default font. 
            wx.DECORATIVE: A decorative font. 
            wx.ROMAN: A formal, serif font. 
            wx.SCRIPT: A handwriting font. 
            wx.SWISS: A sans-serif font. 
            wx.MODERN: A fixed pitch font.
        NOTE: these are only as good as the wxWindows defaults, which aren't so good.
    Style:
        One of wx.NORMAL, wx.SLANT and wx.ITALIC.
    Weight:
        One of wx.NORMAL, wx.LIGHT and wx.BOLD.
    Underline:
        The value can be True or False. At present this may have an an
        effect on Windows only.

    Alternatively, you can set the kw arg: Font, to a wx.Font, and the
    above will be ignored. The size of the font you specify will be
    ignored, but the rest of its attributes will be preserved.
    
    The size will scale as the drawing is zoomed.

    Bugs/Limitations:

    As fonts are scaled, they do end up a little different, so you don't
    get exactly the same picture as you scale up and down, but it's
    pretty darn close.
    
    On wxGTK1 on my Linux system, at least, using a font of over about
    1000 pts. brings the system to a halt. It's the Font Server using
    huge amounts of memory. My work around is to max the font size to
    1000 points, so it won't scale past there. GTK2 uses smarter font
    drawing, so that may not be an issue in future versions, so feel
    free to test. Another smarter way to do it would be to set a global
    zoom limit at that point.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -