[wxPython-users] Skinnable interface in (wx)Python?

Nizam Sayeed ibnameen at gmail.com
Tue Oct 3 08:24:34 PDT 2006


Skipped content of type multipart/alternative-------------- next part -----=
---------

__author__  =3D "Nizam Sayeed <ibnameen_at_gmail_dot_com>"
__date__    =3D "March 16, 2006"

"""
  Description:  This class extends the wx.Frame class and gives it the
                ability to be skinned like fancy GUI apps. This class
                should be treated as a base class which provides only
                the following features:
                =

                - Ability to have a shaped window based on a bitmap
                  (24-bit PNG preferred)
                =

                - Basic mouse events for moving the window by
                  dragging along any point on the surface

  Todo:         - Add the ability to define a region of the window
                  where mouse events are ignored (non-draggable areas)

                - Add the ability to resize the window and the ability
                  to turn resizing on and off

  Credits:      A.R. Dikhoff (captain at xentax.com)
                Some of the code was adapted from EarthClock which can be
                downloaded at: http://earthclock.xentax.com
"""

import math
import wx

class SkinnableFrame( wx.Frame ):

    #{{{ __init__
    def __init__( self, parent, bitmap, title ):
        wx.Frame.__init__( self, parent, -1, title,
                           style=3Dwx.FRAME_SHAPED|wx.SIMPLE_BORDER )
       =

        self.bmp =3D bitmap
        self.currentCursor =3D wx.NullCursor
        self.SetWindowShape()

        # for moving events
        self.moving =3D False
        self.center =3D wx.Point(0, 0)
        self.startDist =3D 0
        self.startOri =3D wx.Point(0, 0)
        self.startSize =3D wx.Size()

        w =3D self.bmp.GetWidth()
        h =3D self.bmp.GetHeight()
        self.SetSize( (w, h) )
        self.CenterOnScreen()

        # define events
        wx.EVT_PAINT( self, self.OnPaint )
        wx.EVT_LEFT_DOWN( self, self.OnLeftDown )
        wx.EVT_LEFT_UP( self, self.OnLeftUp )
        wx.EVT_MOTION( self, self.OnMouseMove )
    #}}}

    #
    # Event handlers
    #

    #{{{ OnPaint
    def OnPaint( self, event ):
        dc =3D wx.PaintDC( self )
        dc.DrawBitmap( self.bmp, 0, 0, True )
        event.Skip()
    #}}}

    #{{{ OnLeftDown    =

    def OnLeftDown( self, event ):
        self.CaptureMouse()
        pos =3D self.ClientToScreen( event.GetPosition() )
        origin =3D self.GetPosition()
        dx =3D pos.x - origin.x
        dy =3D pos.y - origin.y
        self.delta =3D wx.Point( dx, dy )
        =

        # near edge?
        if self.NearEdge( event.GetPosition() ):
            self.centre =3D self.ClientToScreen( self.GetCenter() )
            self.startDist =3D int( self.Dist( self.GetCenter(), event.GetP=
osition() ) )
            self.startOri =3D self.GetPosition()
            self.startSize =3D self.GetClientSize()
            self.moving =3D False
        else:
            self.moving =3D True
        event.Skip()
    #}}}

    #{{{ OnLeftUp
    def OnLeftUp( self, event ):
        if self.HasCapture():
            self.ReleaseMouse()
        self.size =3D self.GetClientSize().width
        event.Skip()
    #}}}

    #{{{ OnMouseMove
    def OnMouseMove( self, event ):
        if self.NearEdge(event.GetPosition()):
            size =3D self.GetClientSize().width
            =

            dx =3D event.GetPosition().x - self.GetCenter().x
            dy =3D event.GetPosition().y - self.GetCenter().y
            =

            angle =3D math.atan2( abs( dy ), abs( dx ) )
            lazyAngle =3D angle / ( math.pi * 2 ) + 0.5
            =

            cursor =3D wx.CURSOR_ARROW
            if lazyAngle >=3D 0.5 and lazyAngle < 0.5625: cursor =3D wx.CUR=
SOR_SIZEWE
            if lazyAngle >=3D 0.6875 and lazyAngle < 0.75: cursor =3D wx.CU=
RSOR_SIZENS
            if lazyAngle >=3D 0.5625 and lazyAngle < 0.6875:
                if dx * dy > 0: cursor =3D wx.CURSOR_SIZENWSE
                if dx * dy <=3D 0: cursor =3D wx.CURSOR_SIZENESW
            =

            self.SetCursor( wx.StockCursor( cursor ) )
        else:
            self.SetCursor( self.currentCursor )
        =

        # do dragging
        if event.Dragging() and event.LeftIsDown():
            if self.moving:
                pos =3D self.ClientToScreen( event.GetPosition() )
                fp =3D ( pos.x - self.delta.x, pos.y - self.delta.y )
                self.Move( fp )
    #}}}

    #
    # Helpers
    #

    #{{{ GetCenter
    def GetCenter( self ):
        d =3D self.GetClientSize()
        cx =3D d.width / 2
        cy =3D d.height / 2
        return wx.Point( cx, cy )
    #}}}
   =

    #{{{ Dist
    def Dist( self, posa, posb ):
        distx =3D abs( posb.x - posa.x )
        disty =3D abs( posb.y - posa.y )
        dist =3D math.sqrt( distx * distx + disty * disty )
        return dist
    #}}}
       =

    #{{{ NearEdge
    def NearEdge( self, pos ):
        if abs( self.Dist( self.GetCenter(), pos ) - self.GetClientSize().w=
idth / 2 ) < 10:
            return True
        else:
            return False
    #}}}
       =

    #{{{ Move
    def Move( self, pos ):
        wx.Frame.Move( self, pos )
        self.posx =3D pos[ 0 ]
        self.posy =3D pos[ 1 ]
    #}}}

    #{{{ SetWindowShape
    def SetWindowShape( self, *event ):
        r =3D wx.RegionFromBitmap( self.bmp )
        self.hasShape =3D self.SetShape( r )
    #}}}

# vim: set ts=3D4 sw=3D4 et:


More information about the wxpython-users mailing list