Exemplo n.º 1
0
 def Zoom(self, zoomtype):
     """控制缩放的总调函数(鼠标位置获取都由内部获取)
     @type zoomtype: ModeKey
     @param zoomtype: 放大还是缩小
     """
     dcrect = self.GetClientRect()
     georect = mainDocument.geoext
     if zoomtype == ModeKey.ZoomInMode:  # 放大
         x1, y1 = ScreenPToGeoP(self.tmpxb, self.tmpyb, dcrect, georect)
         x2, y2 = ScreenPToGeoP(self.tmpxe, self.tmpye, dcrect, georect)
         if x1 == x2 and y1 == y2:
             realgeoext = self.__initZoomIn(x1, y1, georect)
         else:
             mgrect = GeoRect(x1, y1, x2, y2)
             realgeoext = self.__initZoomInRect(mgrect,dcrect.GetWidth(), \
                 dcrect.GetHeight())
     else:  # 缩小
         if self.tmpxb == self.tmpxe and self.tmpyb == self.tmpye:
             x1, y1 = ScreenPToGeoP(self.tmpxb, self.tmpyb, dcrect, georect)
             realgeoext = self.__initZoomOut(x1, y1, georect)
         else:
             mrect = GeoRect(self.tmpxb, self.tmpyb, self.tmpxe, self.tmpye)
             realgeoext = self.__initZoomOutRect(georect, dcrect, mrect)
     mainDocument.geoext.ReSet(realgeoext.GetLeft(),realgeoext.GetTop(), \
             realgeoext.GetRight(),realgeoext.GetBottom())
     mainDocument.zoomall = 0
     #self.Refresh()
     self.ReDraw()
Exemplo n.º 2
0
 def __initZoomOutRect(self, grect, dcrect, mrect):
     """获得调整后要缩小的矩形范围(拉框的大小和屏幕大小不成比例)
     @type grect: L{geosings.core.GeoRect.GeoRect}
     @param grect: 拉框覆盖的地理范围矩形
     @type dcrect: Rect
     @param dcrect: 绘制区域的矩形
     @type mrect: Rect
     @param mrect: 拉框矩形
     @rtype: L{geosings.core.GeoRect.GeoRect}
     @return: 调整大小后需要绘制的地理区域矩形
     """
     mrw = mrect.GetWidth() * 1.0
     mrh = mrect.GetHeight() * 1.0
     dcw = dcrect.GetWidth()
     dch = dcrect.GetHeight()
     if mrw * 1.0 / mrh > dcw * 1.0 / dch:  # 按宽调整
         mrh = dch * 1.0 / dcw * mrw
     else:
         mrw = dcw * 1.0 / dch * mrh
     mrmx, mrmy = mrect.GetMiddlePoint()
     x = mrmx - mrw / 2
     y = mrmy - mrh / 2
     realw = dcw / mrw * dcw
     realh = dch / mrh * dch
     realx = -(x / dcw * realw)
     realy = -(y / dch * realh)
     realx2 = realx + realw
     realy2 = realy + realh
     realgx, realgy = ScreenPToGeoP(realx, realy, dcrect, grect)
     realgx2, realgy2 = ScreenPToGeoP(realx2, realy2, dcrect, grect)
     return GeoRect(realgx, realgy, realgx2, realgy2)
Exemplo n.º 3
0
 def __initZoomOut(self, x, y, georect):
     """ 缩小2倍
     @type x,y: number
     @param x,y: 中点位置
     @type georect: L{geosings.core.GeoRect.GeoRect}
     @param georect: 绘制区域所覆盖的空间区域
     @rtype: L{geosings.core.GeoRect.GeoRect}
     @return: 缩小两倍后绘制区域所覆盖的空间范围
     """
     hw = georect.GetWidth()
     hh = georect.GetHeight()
     return GeoRect(x - hw, y - hh, x + hw, y + hh)
Exemplo n.º 4
0
 def OnLeftUp(self, evt):
     RectHandler.OnLeftUp(self, evt)
     rect = self.ctrl.GetClientRect()
     gwidth = self.ctrl.geoext.GetWidth()
     gheight = self.ctrl.geoext.GetHeight()
     egx, egy = ScreenPToGeoP(evt.GetX(), evt.GetY(), \
             rect, self.ctrl.geoext)
     if self.bgx==egx or self.bgy==egy:
         return
     nowext = GeoRect(self.bgx, self.bgy, egx, egy)
     nowext = ExtGeoRect(nowext, rect.GetWidth(), rect.GetHeight())
     self.ctrl.geoext.Set(nowext)
     self.ctrl.ReDraw()
Exemplo n.º 5
0
 def Draw(self, dc, geoext=None, all=False):
     """进行绘制操作时的主要函数
     @type dc: wxDC
     @param dc: 绘制环境
     @type all: bool
     @param all: 要不要绘制所有范围(默认为否)
     """
     rect = self.GetClientRect()
     for oper in self.operh:
         oper.OnBDraw(dc)
     try:
         if self.map.GetLayerCount():
             if self.geoext is None:
                 self.geoext = GeoRect(0, 0, 1, 1)
                 self.geoext.Set(self.map.allGeoExt)
             ge = self.__ExtRect(self.geoext, \
                     rect.GetWidth(),rect.GetHeight())
             self.geoext.ReSet(ge[0], ge[1], ge[2], ge[3])
             dc.BeginDrawing()
             #dc.SetDeviceOrigin(0,rect.GetHeight()-20)
             debug("draw geoext: %s", self.geoext)
             if not self.LABEL_ALONE:
                 labelRender = LabelRender()
             for layer in self.map.layers:
                 if layer.visual:
                     render = self.__GetRender(layer)
                     if self.LABEL_ALONE:
                         labelRender = LabelRender()
                     render.labelCanvas = labelRender
                     render.Draw(dc, rect, self.geoext)
                     if self.LABEL_ALONE:
                         labelRender.Draw(dc, rect, self.geoext)
             if not self.LABEL_ALONE:
                 labelRender.Draw(dc, rect, self.geoext)
     except (Exception, e):
         error("draw except! %s", e)
     for oper in self.operh:
         oper.OnEDraw(dc)
     dc.EndDrawing()
Exemplo n.º 6
0
    def OnLeftDown(self, evt):
        map = self.ctrl.map
        if self.ctrl.geoext is None:
            return
        rect = self.ctrl.GetClientRect()
        gx,gy = ScreenPToGeoP(evt.GetX(), evt.GetY(), \
                rect, self.ctrl.geoext)
        gwidth = self.ctrl.geoext.GetWidth()
        gheight = self.ctrl.geoext.GetHeight()

        nowext = GeoRect(gx-gwidth/2.0, gy-gheight/2.0,
                gx+gwidth/2.0, gy+gheight/2.0)

        self.ctrl.geoext.Set(nowext)
        self.ctrl.ReDraw()
Exemplo n.º 7
0
def ExtGeoRect(rect, width, height):
    """用长宽比来调整第一个矩形形状(中心固定)
    """
    from geosings.core.GeoRect import GeoRect
    rw = rect.GetWidth()
    rh = rect.GetHeight()
    midx, midy = rect.GetMiddlePoint()
    if rw / rh > width * 1.0 / height:  #按宽调整
        newh = height * 1.0 / width * rw
        neww = rw
    else:  #按高调整
        neww = width * 1.0 / height * rh
        newh = rh
    return GeoRect(midx-neww/2.0,midy+newh/2.0, \
            midx+neww/2.0,midy-newh/2.0)
Exemplo n.º 8
0
 def __initZoomInRect(self, grect, dcw, dch):
     """获得调整后要放大的矩形范围(拉框的大小和屏幕大小不成比例)
     @type grect: L{geosings.core.GeoRect.GeoRect}
     @param grect: 拉框覆盖的地理范围矩形
     @type dcw,dch: int
     @param dcw,dch: 拉框的矩形的宽高
     @rtype: L{geosings.core.GeoRect.GeoRect}
     @return: 调整大小后需要绘制的地理区域矩形
     """
     grw = grect.GetWidth() * 1.0
     grh = grect.GetHeight() * 1.0
     grmx, grmy = grect.GetMiddlePoint()
     if grw * 1.0 / grh > dcw * 1.0 / dch:  # 按宽来调整
         grh = dch * 1.0 / dcw * grw
     else:  # 按高调整
         grw = dcw * 1.0 / dch * grh
     return GeoRect(grmx - grw / 2, grmy - grh / 2, grmx + grw / 2,
                    grmy + grh / 2)
Exemplo n.º 9
0
 def DoDrawing(self, dc, all=False):
     """进行重绘操作时的主要函数
     @type dc: wxDC
     @param dc: 绘制环境
     @type all: bool
     @param all: 要不要绘制所有范围(默认为否)
     """
     dc.BeginDrawing()
     rect = self.GetClientRect()
     #dc.SetDeviceOrigin(0,rect.GetHeight()-20)
     if all:  #如果要画超过屏幕范围的所有数据
         nowgeoext = mainDocument.geoext
         allgeoext = self.map.allGeoExt
         dcrect = rect
         allw = allgeoext.GetWidth() / nowgeoext.GetWidth(
         ) * dcrect.GetWidth()
         allh = allgeoext.GetHeight() / nowgeoext.GetHeight(
         ) * dcrect.GetHeight()
         rect = GeoRect(0, 0, allw, allh)
         igeoext = allgeoext
     else:
         if mainDocument.zoomall and len(self.map.layers) > 0:  # 如果放大到全图到屏幕
             debug("zoom to all")
             mainDocument.initGeoExt(rect.GetWidth(), rect.GetHeight())
             mainDocument.geoext = deepcopy(self.map.allGeoExt)
         igeoext = mainDocument.geoext
     self.labelCanvas = LabelCanvas()
     for layer in self.map.layers:
         if layer is not None and layer.visual:
             self.__DrawLayer(dc, layer, rect, igeoext)
     if self.map.whereFlite != "":
         sellyr = self.map.GetLayer(self.map.whereLayer)
         hlcanv = HLLayerCanvas(sellyr)
         hlcanv.SetWhereFilter(self.map.whereFlite, self.map.codec)
         hlcanv.Draw(dc, rect, igeoext)
     self.labelCanvas.Draw(dc, rect, igeoext)
     if not all:
         self.__DrawCross(dc,
                          rect.GetWidth() / 2,
                          rect.GetHeight() / 2, wx.RED)
     dc.EndDrawing()
Exemplo n.º 10
0
 def OnLeftUp(self, evt):
     RectHandler.OnLeftUp(self, evt)
     rect = self.ctrl.GetClientRect()
     gwidth = self.ctrl.geoext.GetWidth()
     gheight = self.ctrl.geoext.GetHeight()
     egx, egy = ScreenPToGeoP(evt.GetX(), evt.GetY(), \
             rect, self.ctrl.geoext)
     if self.bgx==egx or self.bgy==egy:
         return
     inext = GeoRect(self.bgx, self.bgy, egx, egy)
     inext = ExtGeoRect(inext, rect.GetWidth(), rect.GetHeight())
     scale = gwidth*1.0/inext.GetWidth()
     midgx, midgy = inext.GetMiddlePoint()
     midrx, midry = self.ctrl.geoext.GetMiddlePoint()
     nmidgx = midrx-(midgx-midrx)*scale
     nmidgy = midry+(midry-midgy)*scale
     xw = gwidth*scale/2.0
     xh = gheight*scale/2.0
     nowext = GeoRect(nmidgx-xw,nmidgy+xh,nmidgx+xw,nmidgy-xh)
     self.ctrl.geoext.Set(nowext)
     self.ctrl.ReDraw()
Exemplo n.º 11
0
class MapCanvas(wx.Panel):
    """主画板类
    """
    def __init__(self, parent):
        """初始化
        @type parent: wxCtrl
        @param parent: 父控件
        @type mainctrl: wxCtrl
        @param mainctrl: 主程序
        @type oparea: wxCtrl
        @param oparea: 输出控件
        """
        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
        self.parent = parent
        #self.mode = ModeKey.NoneMode
        self.map = GSSMap()

        cursor = wx.StockCursor(wx.CURSOR_CROSS)
        self.SetCursor(cursor)

        self.rd = 1  # 是否需要重绘?

        # Bind event handle to Function
        self.Bind(wx.EVT_PAINT, self.__OnPaint)
        self.Bind(wx.EVT_CHAR, self.__OnChar)
        self.Bind(wx.EVT_LEFT_DOWN, self.__OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.__OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.__OnMotion)
        self.Bind(wx.EVT_SIZE, self.__ReSize)
        self.Bind(wx.EVT_IDLE, self.__OnIdle)

        self.LABEL_ALONE = False

        self.operh = []
        self.moperh = None  #保存operh中管mode的handler

        self.geoext = None  #GeoRect(0,0,1,1)#用来计算绘制的地理范围

        self.__do_layout()
        self.InitBuffer()

    def InitBuffer(self):
        """因为采用双缓存,所以要对缓存进行初始化
        """
        size = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(size.width, size.height)
        dc = wx.BufferedDC(None, self.buffer)
        #dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        if GSSCONF["CANV_BACKGROUND_COLOR"]:
            dc.SetBackground(wx.Brush(GSSCONF["CANV_BACKGROUND_COLOR"]))
        dc.Clear()
        self.PrepareDC(dc)
        #self.DrawLines(dc)
        self.Draw(dc)
        self.rd = 0

    def GetPointCoor(self, x, y):
        if self.geoext is not None:
            #geoext = mainDocument.geoext
            rect = self.GetClientRect()
            dcw = rect.GetWidth()
            dch = rect.GetHeight()
            geox,geoy = ScreenPToGeoP(x,y, \
                    rect,self.geoext)
            if GSSCONF['SHOW_COORD'] == 'G' and len(self.map.layers) > 0:
                map = self.map
                layer = map.layers[0]
                if layer.sr is None or layer.sr == "":
                    return geox, geoy
                if type(layer.sr) == str:
                    sr = osr.SpatialReference()
                    sr.ImportFromWkt(layer.sr)
                else:
                    sr = layer.sr
                if sr.IsProjected():
                    gcs = sr.CloneGeogCS()
                    ct = osr.CoordinateTransformation(sr, gcs)
                    xys = ct.TransformPoint(geox, geoy)
                    geox, geoy = xys[0], xys[1]
            return geox, geoy
        else:
            return x, y

    def RegHandler(self, handler):
        debug("regHandler %s", handler)
        if isinstance(handler, ModeOperHandler):
            if self.moperh is not None:
                self.operh.remove(self.moperh)
            self.moperh = handler
        if handler is not None:
            self.operh.append(handler)

    def __do_layout(self):
        """对画板内的空间分布进行排列
        """
        #self.oparea.InitLayout()
        self.Layout()

    def __OnPaint(self, evt):
        """需要重绘时响应的事件
        @type evt: wxEvent
        @param evt: wxEVT_PAINT事件
        """
        dc = wx.BufferedPaintDC(self, self.buffer)

    def __GetRender(self, layer):
        if layer.render:
            return layer.render
        elif layer.type == DataSetType.Vector:
            return VectorRender(layer)
        elif layer.type == DataSetType.Raster:
            return RasterRender(layer)
        else:
            return None

    def __ExtRect(self, rect, width, height):
        """用长宽比来调整第一个矩形形状(中心固定)
        """
        rw = rect.GetWidth()
        rh = rect.GetHeight()
        midx, midy = rect.GetMiddlePoint()
        if rw / rh > width * 1.0 / height:  #按宽调整
            newh = height * 1.0 / width * rw
            neww = rw
        else:  #按高调整
            neww = width * 1.0 / height * rh
            newh = rh
        return [midx-neww/2.0,midy+newh/2.0, \
                midx+neww/2.0,midy-newh/2.0]

    def Draw(self, dc, geoext=None, all=False):
        """进行绘制操作时的主要函数
        @type dc: wxDC
        @param dc: 绘制环境
        @type all: bool
        @param all: 要不要绘制所有范围(默认为否)
        """
        rect = self.GetClientRect()
        for oper in self.operh:
            oper.OnBDraw(dc)
        try:
            if self.map.GetLayerCount():
                if self.geoext is None:
                    self.geoext = GeoRect(0, 0, 1, 1)
                    self.geoext.Set(self.map.allGeoExt)
                ge = self.__ExtRect(self.geoext, \
                        rect.GetWidth(),rect.GetHeight())
                self.geoext.ReSet(ge[0], ge[1], ge[2], ge[3])
                dc.BeginDrawing()
                #dc.SetDeviceOrigin(0,rect.GetHeight()-20)
                debug("draw geoext: %s", self.geoext)
                if not self.LABEL_ALONE:
                    labelRender = LabelRender()
                for layer in self.map.layers:
                    if layer.visual:
                        render = self.__GetRender(layer)
                        if self.LABEL_ALONE:
                            labelRender = LabelRender()
                        render.labelCanvas = labelRender
                        render.Draw(dc, rect, self.geoext)
                        if self.LABEL_ALONE:
                            labelRender.Draw(dc, rect, self.geoext)
                if not self.LABEL_ALONE:
                    labelRender.Draw(dc, rect, self.geoext)
        except (Exception, e):
            error("draw except! %s", e)
        for oper in self.operh:
            oper.OnEDraw(dc)
        dc.EndDrawing()

    def SendMessage(self, msg):
        """画布要向外发送信息
        @type msg: str
        @param msg: 向外发送的信息
        """
        from geosings.ui.core.Brain import msgParser
        msgParser.SendMsg(msg)
        result = msgParser.result
        if result == ActionResult.UpdateAll:
            #self.Refresh()
            self.ReDraw()
        else:
            return result

    def SendOrder(self, order, *arrs):
        """画布要向外发送的命令
        @type order: str
        @param order: 向外发送的命令
        """
        from geosings.ui.core.Brain import msgParser
        msgParser.SendOrder(order, arrs)
        result = msgParser.result
        if result == ActionResult.UpdateAll:
            #self.Refresh()
            self.ReDraw()
        else:
            return ActionResult.Failuse

    #def SetMode(self,mode):
    #    """将画布设置成某个状态
    #    @type mode: ModeKey
    #    @param mode: 要将画布设置的状态
    #    """
    #    self.mode = mode
    #    if mode == ModeKey.InfoMode:
    #        self.ShowFTable(True)
    #    else:
    #        self.ShowFTable(False)
    #    self.SetFocus()

    def ReDraw(self):
        """重新绘制当前屏幕的区域
        """
        self.rd = 1
        self.InitBuffer()
        self.Refresh(True)
        #self.ReDrawLayer()

    def __OnIdle(self, evt):
        """没有操作时进行的响应
        @type evt: wxEvent
        @param evt: EVT_IDLE事件
        """
        #print self.rd
        if self.rd:
            self.InitBuffer()
            self.Refresh(True)

    def __ReSize(self, evt):
        """窗口重新设置大小时的响应
        @type evt: wxEvent
        @param evt: EVT_SIZE事件
        """
        #self.ReDraw()
        self.rd = 1
        #self.ReDraw()
        self.Layout()  #重新排列上面的组件

    def __OnChar(self, evt):
        """键盘响应
        @type evt: wxEvent
        @param evt: wxEVT_CHAR事件
        """
        #self.mainctrl.EvtOrder(evt)
        for oper in self.operh:
            oper.OnChar(evt)

    def __OnLeftDown(self, evt):
        """鼠标左键按下的响应函数
        @type evt: wxEvent
        @param evt: 鼠标事件
        """
        for oper in self.operh:
            oper.OnLeftDown(evt)

    def __OnLeftUp(self, evt):
        """鼠标松开的时候的响应
        @type evt: wxEvent
        @param evt: 鼠标事件
        """
        for oper in self.operh:
            oper.OnLeftUp(evt)

    def __OnMotion(self, evt):
        """鼠标移动的相应事件
        @type evt: wxEvent
        @param evt: 鼠标事件
        """
        for oper in self.operh:
            oper.OnMotion(evt)

    def WinkFeatures(self, features):
        """闪动某(些)要素
        @type features: list
        @param features: 要闪动的要素集合
        """
        dc = wx.ClientDC(self)
        fc = FeaturesRender(features)
        fc.SetWink(10)
        fc.BindAimFoo(self.Aim)
        rect = self.GetClientRect()
        igeoext = self.geoext
        fc.Draw(dc, rect, igeoext)

    def Aim(self, sth):
        """倏地瞄准某个点
        @type sth: list
        @param sth: 要瞄准的点(或者矩形),矩形四个元素,点是两个元素
        """
        import time
        dc = wx.ClientDC(self)
        dcrect = self.GetClientRect()
        left, right = dcrect.GetLeft(), dcrect.GetRight()
        top, bottom = dcrect.GetTop(), dcrect.GetBottom()
        if len(sth) == 2:
            px, py = sth[0], sth[1]
        elif len(sth) == 4:
            px, py = sth[0] + sth[2] / 2, sth[1] + sth[3] / 2
        else:
            return
        point = [px, py]
        if not (left < px < right and top < py < bottom):
            return
        hw = max(px - left, right - px)
        hh = max(py - top, bottom - py)
        hl = max(hw, hh)  #计算一个要过渡的矩形范围

        hllen = 50  #要移动的线的一半长度

        xmove = hl / 20.0  #每次移动多少

        relen = 12  #四角框的长度

        dc.SetPen(wx.GREEN_PEN)

        if wx.Platform == "__WXGTK__":
            dc.SetLogicalFunction(wx.XOR)
            pen2 = wx.Pen(wx.WHITE, 2, wx.SOLID)
            dc.SetPen(pen2)
            self.__DrawAimLines(dc, point, hl, hllen)
            if len(sth) == 4:
                re = self.__ScaleRect(sth, 20 - 1)
                self.__DrawAimRect(dc, re, 0, relen)
            for i in range(20):
                for k in range(20):
                    self.__DrawAimLines(dc, point, hl, hllen)
                if len(sth) == 4:
                    re = self.__ScaleRect(sth, 20 - 1 - i)
                    self.__DrawAimRect(dc, re, 0, relen)
                hl -= xmove
                for k in range(20):
                    self.__DrawAimLines(dc, point, hl, hllen)
                if len(sth) == 4:
                    if i < 19:
                        re2 = self.__ScaleRect(sth, 20 - i - 2)
                    else:
                        re2 = self.__ScaleRect(sth, 20 - i - 1)
                    self.__DrawAimRect(dc, re2, 0, relen)
            dc.SetLogicalFunction(wx.COPY)
        else:
            dc.SetLogicalFunction(wx.XOR)
            self.__DrawAimLines(dc, point, hl, hllen)
            if len(sth) == 4:
                re = self.__ScaleRect(sth, 20 - 1)
                self.__DrawAimRect(dc, re, 0, relen)
            for i in range(20):
                self.__DrawAimLines(dc, point, hl, hllen)
                if len(sth) == 4:
                    re = self.__ScaleRect(sth, 20 - 1 - i)
                    self.__DrawAimRect(dc, re, 0, relen)
                hl -= xmove
                self.__DrawAimLines(dc, point, hl, hllen)
                if len(sth) == 4:
                    if i < 19:
                        re2 = self.__ScaleRect(sth, 20 - i - 2)
                    else:
                        re2 = self.__ScaleRect(sth, 20 - i - 1)
                    self.__DrawAimRect(dc, re2, 0, relen)
                time.sleep(0.02)
            dc.SetLogicalFunction(wx.COPY)

    def __DrawAimLines(self, dc, point, hl, hllen):
        dc.DrawLine(point[0] - hl - hllen - 1, point[1], point[0] - hl + hllen,
                    point[1])
        dc.DrawLine(point[0] + hl - hllen, point[1], point[0] + hl + hllen + 1,
                    point[1])
        dc.DrawLine(point[0], point[1] - hl - hllen - 1, point[0],
                    point[1] - hl + hllen)
        dc.DrawLine(point[0], point[1] + hl - hllen, point[0],
                    point[1] + hl + hllen + 1)

    def __DrawAimRect(self, dc, rect, hl, hllen):
        dc.DrawLine(rect[0], rect[1], rect[0] + hllen, rect[1])
        dc.DrawLine(rect[0], rect[1], rect[0], rect[1] + hllen)
        dc.DrawLine(rect[0] + rect[2], rect[1], rect[0] + rect[2] - hllen,
                    rect[1])
        dc.DrawLine(rect[0] + rect[2], rect[1], rect[0] + rect[2],
                    rect[1] + hllen)
        dc.DrawLine(rect[0], rect[1] + rect[3], rect[0] + hllen,
                    rect[1] + rect[3])
        dc.DrawLine(rect[0], rect[1] + rect[3], rect[0],
                    rect[1] + rect[3] - hllen)
        dc.DrawLine(rect[0] + rect[2], rect[1] + rect[3],
                    rect[0] + rect[2] - hllen, rect[1] + rect[3])
        dc.DrawLine(rect[0] + rect[2], rect[1] + rect[3], rect[0] + rect[2],
                    rect[1] + rect[3] - hllen)

    def __ScaleRect(self, rect, i):
        step = 5
        return [
            rect[0] - i * (step), rect[1] - i * (step), rect[2] + step * i * 2,
            rect[3] + step * i * 2
        ]