RtmSystemDraw.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # @file RtmSystemDraw.py
5 # @brief rtc-link component block diagram system draw management class
6 # @date $Date: 2005-05-27 15:51:31 $
7 # @author Tsuyoshi Tanabe, Noriaki Ando <n-ando@aist.go.jp>
8 #
9 # Copyright (C) 2004-2005
10 # Task-intelligence Research Group,
11 # Intelligent Systems Research Institute,
12 # National Institute of
13 # Advanced Industrial Science and Technology (AIST), Japan
14 # All rights reserved.
15 #
16 # $Id: RtmSystemDraw.py 775 2008-07-28 16:14:45Z n-ando $
17 #
18 # RtmSystemDraw.py Created on: 2004/09/13
19 # Author : Tsuyoshi Tanabe
20 
21 """
22  wxPython, OGL を用いたコンポーネント図形表示画面
23 """
24 
25 
26 import time
27 import wx
28 import wx.lib.colourdb
29 import wx.ogl as ogl
30 import RtmLineUtil as lu
31 import string
32 import sys,os
33 import copy
34 import RtmParser
35 from RtmDialog import *
36 
37 import RTM
38 
39 
40 ##wx.Trap()
41 
42 # ソース内で使用するデファイン# 色名称は、wx の colourdb パッケージ内のものを使用 SELECTED_COLOR = "LIGHT BLUE" UNLOADED_COLOR = "black" INACTIVE_COLOR = "blue" ACTIVE_COLOR = "green" ERROR_COLOR = "red" TEXT_COLOR = "red" #BACK_COLOR = "LightYellow" BACK_COLOR = "WHITE" MARK_COLOR = "red" OUTLINE_COLOR = "red" VIRTUAL_COLOR = "WHITE" TRUE = 1 FALSE = 0 DUP_CONNECT = -1 # Duplication connection BOX_WIDTH = 50 POLYGON_SIZE = 12 USE_BUFFERED_DC = 1 # バッググランド上でのコンテキストメニュー用文字列 strDEL_SELECT = "Delete Selected Item" strREFRESH = "Refresh" strOPEN = "Open System" strSAVE = "Save System" strSAVE_AS = "Save System As" strDEL_SYS = "Current System is Deleted when OPEN.\nDelete It?" # コンポーネント上でのコンテキストメニュー用文字列 strSTART = "Start" strSTOP = "Stop" strRESET = "Reset" strEXIT = "Exit" strKILL = "Kill" strDELITEM = "Delete Item" # アセンブリ・読み込み後のコンテキストメニュー strASM_CONNECT = "Connect" strASM_DELETE = "Delete" # 再接続処理の確認ダイアログ用文字列 strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?" # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか? # Save File As ダイアログのタイトル strSAVE_AS_TITLE = "Save file as ..." # Open FIle ダイアログのタイトル strOPEN_TITLE = "Open a file" #---------------------------------------------------------------------- class MyTextDropTarget(wx.TextDropTarget): """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス""" def __init__(self, parent, log): """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void """ wx.TextDropTarget.__init__(self) self.parent = parent self.log = log def OnDropText(self, x, y, text): """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void """ self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text)) canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(self.parent) canvas.PrepareDC(dc) self.parent.PrepareDC(dc) # NameService Treeからドロップされた名称を登録 if text not in self.parent.rtc_dict.keys(): # print "drag text:",text , " kind:",check ref = self.parent.frame.myDict.GetObjRefToFullpath(text) kind = self.parent.frame.myDict.GetKindToFullpath(text) if ref != None and kind == 'rtc': self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y) self.parent.rtc_list.append(text) self.parent.rtc_dict[text].refresh() self.parent.remakeLines() else: print "error: Drag Item does not obj-ref!" self.parent.Redraw(dc) def OnDragOver(self, x, y, d): """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する """ return wx.DragCopy #---------------------------------------------------------------------- def getBufferedDC(canvas): """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC """ cdc = wx.ClientDC(canvas) canvas.PrepareDC(cdc) bufSize = wx.Size(1000, 1000) dc = wx.BufferedDC(cdc, bufSize) canvas.PrepareDC(dc) dc.SetBackground(wx.Brush(canvas.GetBackgroundColour())) dc.Clear() return dc #---------------------------------------------------------------------- def setBodyColor(shape, colorFlag): """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void """ if colorFlag == 'select': shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) elif colorFlag == 'unloaded': shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR))) elif colorFlag == 'inactive': shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) elif colorFlag == 'active': shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR))) elif colorFlag == 'error': shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR))) elif colorFlag == 'virtual': shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR))) else: shape.SetBrush(wx.Brush(colorFlag)) shape.Flash() #---------------------------------------------------------------------- class makeCompositeShape(ogl.CompositeShape): """CompositeShapeのラッパークラス""" def __init__(self, parent): """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void """ ogl.CompositeShape.__init__(self) self.parent = parent #---------------------------------------------------------------------- class makeLineShape(ogl.LineShape): """2点間の線を描画するラッパークラス""" def __init__(self, parent, canvas ): """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void """ ogl.LineShape.__init__(self) self.parent = parent self.SetCanvas(canvas) self.SetPen(wx.Pen(wx.BLUE, 1)) setBodyColor(self, 'inactive') self.MakeLineControlPoints(2) diagram = canvas.GetDiagram() diagram.AddShape(self) def setPoints(self, startX,startY, endX, endY): """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void """ self.SetEnds(startX, startY, endX, endY) #---------------------------------------------------------------------- class makeRectangle(ogl.RectangleShape): """四角形を描画するラッパークラス""" def __init__(self, parent, width, height): """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void """ ogl.RectangleShape.__init__(self,width, height) self.parent = parent # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
43 # 色名称は、wx の colourdb パッケージ内のものを使用SELECTED_COLOR = "LIGHT BLUE" UNLOADED_COLOR = "black" INACTIVE_COLOR = "blue" ACTIVE_COLOR = "green" ERROR_COLOR = "red" TEXT_COLOR = "red" #BACK_COLOR = "LightYellow" BACK_COLOR = "WHITE" MARK_COLOR = "red" OUTLINE_COLOR = "red" VIRTUAL_COLOR = "WHITE" TRUE = 1 FALSE = 0 DUP_CONNECT = -1 # Duplication connection BOX_WIDTH = 50 POLYGON_SIZE = 12 USE_BUFFERED_DC = 1 # バッググランド上でのコンテキストメニュー用文字列 strDEL_SELECT = "Delete Selected Item" strREFRESH = "Refresh" strOPEN = "Open System" strSAVE = "Save System" strSAVE_AS = "Save System As" strDEL_SYS = "Current System is Deleted when OPEN.\nDelete It?" # コンポーネント上でのコンテキストメニュー用文字列 strSTART = "Start" strSTOP = "Stop" strRESET = "Reset" strEXIT = "Exit" strKILL = "Kill" strDELITEM = "Delete Item" # アセンブリ・読み込み後のコンテキストメニュー strASM_CONNECT = "Connect" strASM_DELETE = "Delete" # 再接続処理の確認ダイアログ用文字列 strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?" # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか? # Save File As ダイアログのタイトル strSAVE_AS_TITLE = "Save file as ..." # Open FIle ダイアログのタイトル strOPEN_TITLE = "Open a file" #---------------------------------------------------------------------- class MyTextDropTarget(wx.TextDropTarget): """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス""" def __init__(self, parent, log): """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void """ wx.TextDropTarget.__init__(self) self.parent = parent self.log = log def OnDropText(self, x, y, text): """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void """ self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text)) canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(self.parent) canvas.PrepareDC(dc) self.parent.PrepareDC(dc) # NameService Treeからドロップされた名称を登録 if text not in self.parent.rtc_dict.keys(): # print "drag text:",text , " kind:",check ref = self.parent.frame.myDict.GetObjRefToFullpath(text) kind = self.parent.frame.myDict.GetKindToFullpath(text) if ref != None and kind == 'rtc': self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y) self.parent.rtc_list.append(text) self.parent.rtc_dict[text].refresh() self.parent.remakeLines() else: print "error: Drag Item does not obj-ref!" self.parent.Redraw(dc) def OnDragOver(self, x, y, d): """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する """ return wx.DragCopy #---------------------------------------------------------------------- def getBufferedDC(canvas): """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC """ cdc = wx.ClientDC(canvas) canvas.PrepareDC(cdc) bufSize = wx.Size(1000, 1000) dc = wx.BufferedDC(cdc, bufSize) canvas.PrepareDC(dc) dc.SetBackground(wx.Brush(canvas.GetBackgroundColour())) dc.Clear() return dc #---------------------------------------------------------------------- def setBodyColor(shape, colorFlag): """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void """ if colorFlag == 'select': shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) elif colorFlag == 'unloaded': shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR))) elif colorFlag == 'inactive': shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) elif colorFlag == 'active': shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR))) elif colorFlag == 'error': shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR))) elif colorFlag == 'virtual': shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR))) else: shape.SetBrush(wx.Brush(colorFlag)) shape.Flash() #---------------------------------------------------------------------- class makeCompositeShape(ogl.CompositeShape): """CompositeShapeのラッパークラス""" def __init__(self, parent): """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void """ ogl.CompositeShape.__init__(self) self.parent = parent #---------------------------------------------------------------------- class makeLineShape(ogl.LineShape): """2点間の線を描画するラッパークラス""" def __init__(self, parent, canvas ): """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void """ ogl.LineShape.__init__(self) self.parent = parent self.SetCanvas(canvas) self.SetPen(wx.Pen(wx.BLUE, 1)) setBodyColor(self, 'inactive') self.MakeLineControlPoints(2) diagram = canvas.GetDiagram() diagram.AddShape(self) def setPoints(self, startX,startY, endX, endY): """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void """ self.SetEnds(startX, startY, endX, endY) #---------------------------------------------------------------------- class makeRectangle(ogl.RectangleShape): """四角形を描画するラッパークラス""" def __init__(self, parent, width, height): """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void """ ogl.RectangleShape.__init__(self,width, height) self.parent = parent # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
44 SELECTED_COLOR = "LIGHT BLUE"
45 UNLOADED_COLOR = "black"
46 INACTIVE_COLOR = "blue"
47 ACTIVE_COLOR = "green"
48 ERROR_COLOR = "red"
49 TEXT_COLOR = "red"
50 #BACK_COLOR = "LightYellow"
51 BACK_COLOR = "WHITE"
52 MARK_COLOR = "red"
53 OUTLINE_COLOR = "red"
54 VIRTUAL_COLOR = "WHITE"
55 
56 TRUE = 1
57 FALSE = 0
58 DUP_CONNECT = -1 # Duplication connection
59 
60 BOX_WIDTH = 50
61 POLYGON_SIZE = 12
62 
63 USE_BUFFERED_DC = 1
64 
65 # バッググランド上でのコンテキストメニュー用文字列strDEL_SELECT = "Delete Selected Item" strREFRESH = "Refresh" strOPEN = "Open System" strSAVE = "Save System" strSAVE_AS = "Save System As" strDEL_SYS = "Current System is Deleted when OPEN.\nDelete It?" # コンポーネント上でのコンテキストメニュー用文字列 strSTART = "Start" strSTOP = "Stop" strRESET = "Reset" strEXIT = "Exit" strKILL = "Kill" strDELITEM = "Delete Item" # アセンブリ・読み込み後のコンテキストメニュー strASM_CONNECT = "Connect" strASM_DELETE = "Delete" # 再接続処理の確認ダイアログ用文字列 strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?" # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか? # Save File As ダイアログのタイトル strSAVE_AS_TITLE = "Save file as ..." # Open FIle ダイアログのタイトル strOPEN_TITLE = "Open a file" #---------------------------------------------------------------------- class MyTextDropTarget(wx.TextDropTarget): """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス""" def __init__(self, parent, log): """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void """ wx.TextDropTarget.__init__(self) self.parent = parent self.log = log def OnDropText(self, x, y, text): """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void """ self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text)) canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(self.parent) canvas.PrepareDC(dc) self.parent.PrepareDC(dc) # NameService Treeからドロップされた名称を登録 if text not in self.parent.rtc_dict.keys(): # print "drag text:",text , " kind:",check ref = self.parent.frame.myDict.GetObjRefToFullpath(text) kind = self.parent.frame.myDict.GetKindToFullpath(text) if ref != None and kind == 'rtc': self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y) self.parent.rtc_list.append(text) self.parent.rtc_dict[text].refresh() self.parent.remakeLines() else: print "error: Drag Item does not obj-ref!" self.parent.Redraw(dc) def OnDragOver(self, x, y, d): """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する """ return wx.DragCopy #---------------------------------------------------------------------- def getBufferedDC(canvas): """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC """ cdc = wx.ClientDC(canvas) canvas.PrepareDC(cdc) bufSize = wx.Size(1000, 1000) dc = wx.BufferedDC(cdc, bufSize) canvas.PrepareDC(dc) dc.SetBackground(wx.Brush(canvas.GetBackgroundColour())) dc.Clear() return dc #---------------------------------------------------------------------- def setBodyColor(shape, colorFlag): """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void """ if colorFlag == 'select': shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) elif colorFlag == 'unloaded': shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR))) elif colorFlag == 'inactive': shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) elif colorFlag == 'active': shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR))) elif colorFlag == 'error': shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR))) elif colorFlag == 'virtual': shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR))) else: shape.SetBrush(wx.Brush(colorFlag)) shape.Flash() #---------------------------------------------------------------------- class makeCompositeShape(ogl.CompositeShape): """CompositeShapeのラッパークラス""" def __init__(self, parent): """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void """ ogl.CompositeShape.__init__(self) self.parent = parent #---------------------------------------------------------------------- class makeLineShape(ogl.LineShape): """2点間の線を描画するラッパークラス""" def __init__(self, parent, canvas ): """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void """ ogl.LineShape.__init__(self) self.parent = parent self.SetCanvas(canvas) self.SetPen(wx.Pen(wx.BLUE, 1)) setBodyColor(self, 'inactive') self.MakeLineControlPoints(2) diagram = canvas.GetDiagram() diagram.AddShape(self) def setPoints(self, startX,startY, endX, endY): """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void """ self.SetEnds(startX, startY, endX, endY) #---------------------------------------------------------------------- class makeRectangle(ogl.RectangleShape): """四角形を描画するラッパークラス""" def __init__(self, parent, width, height): """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void """ ogl.RectangleShape.__init__(self,width, height) self.parent = parent # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
66 strDEL_SELECT = "Delete Selected Item"
67 strREFRESH = "Refresh"
68 strOPEN = "Open System"
69 strSAVE = "Save System"
70 strSAVE_AS = "Save System As"
71 strDEL_SYS = "Current System is Deleted when OPEN.\nDelete It?"
72 
73 # コンポーネント上でのコンテキストメニュー用文字列strSTART = "Start" strSTOP = "Stop" strRESET = "Reset" strEXIT = "Exit" strKILL = "Kill" strDELITEM = "Delete Item" # アセンブリ・読み込み後のコンテキストメニュー strASM_CONNECT = "Connect" strASM_DELETE = "Delete" # 再接続処理の確認ダイアログ用文字列 strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?" # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか? # Save File As ダイアログのタイトル strSAVE_AS_TITLE = "Save file as ..." # Open FIle ダイアログのタイトル strOPEN_TITLE = "Open a file" #---------------------------------------------------------------------- class MyTextDropTarget(wx.TextDropTarget): """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス""" def __init__(self, parent, log): """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void """ wx.TextDropTarget.__init__(self) self.parent = parent self.log = log def OnDropText(self, x, y, text): """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void """ self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text)) canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(self.parent) canvas.PrepareDC(dc) self.parent.PrepareDC(dc) # NameService Treeからドロップされた名称を登録 if text not in self.parent.rtc_dict.keys(): # print "drag text:",text , " kind:",check ref = self.parent.frame.myDict.GetObjRefToFullpath(text) kind = self.parent.frame.myDict.GetKindToFullpath(text) if ref != None and kind == 'rtc': self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y) self.parent.rtc_list.append(text) self.parent.rtc_dict[text].refresh() self.parent.remakeLines() else: print "error: Drag Item does not obj-ref!" self.parent.Redraw(dc) def OnDragOver(self, x, y, d): """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する """ return wx.DragCopy #---------------------------------------------------------------------- def getBufferedDC(canvas): """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC """ cdc = wx.ClientDC(canvas) canvas.PrepareDC(cdc) bufSize = wx.Size(1000, 1000) dc = wx.BufferedDC(cdc, bufSize) canvas.PrepareDC(dc) dc.SetBackground(wx.Brush(canvas.GetBackgroundColour())) dc.Clear() return dc #---------------------------------------------------------------------- def setBodyColor(shape, colorFlag): """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void """ if colorFlag == 'select': shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) elif colorFlag == 'unloaded': shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR))) elif colorFlag == 'inactive': shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) elif colorFlag == 'active': shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR))) elif colorFlag == 'error': shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR))) elif colorFlag == 'virtual': shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR))) else: shape.SetBrush(wx.Brush(colorFlag)) shape.Flash() #---------------------------------------------------------------------- class makeCompositeShape(ogl.CompositeShape): """CompositeShapeのラッパークラス""" def __init__(self, parent): """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void """ ogl.CompositeShape.__init__(self) self.parent = parent #---------------------------------------------------------------------- class makeLineShape(ogl.LineShape): """2点間の線を描画するラッパークラス""" def __init__(self, parent, canvas ): """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void """ ogl.LineShape.__init__(self) self.parent = parent self.SetCanvas(canvas) self.SetPen(wx.Pen(wx.BLUE, 1)) setBodyColor(self, 'inactive') self.MakeLineControlPoints(2) diagram = canvas.GetDiagram() diagram.AddShape(self) def setPoints(self, startX,startY, endX, endY): """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void """ self.SetEnds(startX, startY, endX, endY) #---------------------------------------------------------------------- class makeRectangle(ogl.RectangleShape): """四角形を描画するラッパークラス""" def __init__(self, parent, width, height): """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void """ ogl.RectangleShape.__init__(self,width, height) self.parent = parent # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
74 strSTART = "Start"
75 strSTOP = "Stop"
76 strRESET = "Reset"
77 strEXIT = "Exit"
78 strKILL = "Kill"
79 strDELITEM = "Delete Item"
80 
81 # アセンブリ・読み込み後のコンテキストメニュー
82 strASM_CONNECT = "Connect"
83 strASM_DELETE = "Delete"
84 
85 # 再接続処理の確認ダイアログ用文字列strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?" # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか? # Save File As ダイアログのタイトル strSAVE_AS_TITLE = "Save file as ..." # Open FIle ダイアログのタイトル strOPEN_TITLE = "Open a file" #---------------------------------------------------------------------- class MyTextDropTarget(wx.TextDropTarget): """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス""" def __init__(self, parent, log): """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void """ wx.TextDropTarget.__init__(self) self.parent = parent self.log = log def OnDropText(self, x, y, text): """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void """ self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text)) canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(self.parent) canvas.PrepareDC(dc) self.parent.PrepareDC(dc) # NameService Treeからドロップされた名称を登録 if text not in self.parent.rtc_dict.keys(): # print "drag text:",text , " kind:",check ref = self.parent.frame.myDict.GetObjRefToFullpath(text) kind = self.parent.frame.myDict.GetKindToFullpath(text) if ref != None and kind == 'rtc': self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y) self.parent.rtc_list.append(text) self.parent.rtc_dict[text].refresh() self.parent.remakeLines() else: print "error: Drag Item does not obj-ref!" self.parent.Redraw(dc) def OnDragOver(self, x, y, d): """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する """ return wx.DragCopy #---------------------------------------------------------------------- def getBufferedDC(canvas): """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC """ cdc = wx.ClientDC(canvas) canvas.PrepareDC(cdc) bufSize = wx.Size(1000, 1000) dc = wx.BufferedDC(cdc, bufSize) canvas.PrepareDC(dc) dc.SetBackground(wx.Brush(canvas.GetBackgroundColour())) dc.Clear() return dc #---------------------------------------------------------------------- def setBodyColor(shape, colorFlag): """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void """ if colorFlag == 'select': shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) elif colorFlag == 'unloaded': shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR))) elif colorFlag == 'inactive': shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) elif colorFlag == 'active': shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR))) elif colorFlag == 'error': shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR))) elif colorFlag == 'virtual': shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR))) else: shape.SetBrush(wx.Brush(colorFlag)) shape.Flash() #---------------------------------------------------------------------- class makeCompositeShape(ogl.CompositeShape): """CompositeShapeのラッパークラス""" def __init__(self, parent): """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void """ ogl.CompositeShape.__init__(self) self.parent = parent #---------------------------------------------------------------------- class makeLineShape(ogl.LineShape): """2点間の線を描画するラッパークラス""" def __init__(self, parent, canvas ): """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void """ ogl.LineShape.__init__(self) self.parent = parent self.SetCanvas(canvas) self.SetPen(wx.Pen(wx.BLUE, 1)) setBodyColor(self, 'inactive') self.MakeLineControlPoints(2) diagram = canvas.GetDiagram() diagram.AddShape(self) def setPoints(self, startX,startY, endX, endY): """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void """ self.SetEnds(startX, startY, endX, endY) #---------------------------------------------------------------------- class makeRectangle(ogl.RectangleShape): """四角形を描画するラッパークラス""" def __init__(self, parent, width, height): """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void """ ogl.RectangleShape.__init__(self,width, height) self.parent = parent # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
86 strASKMESSAGE = "Old Connection Information was found.\nDelete it and reconnect?"
87 # 訳: 古い接続情報がコンポーネント上に見つかりました。古い接続は削除されます。再接続しますか?
88 
89 # Save File As ダイアログのタイトル
90 strSAVE_AS_TITLE = "Save file as ..."
91 # Open FIle ダイアログのタイトル
92 strOPEN_TITLE = "Open a file"
93 
94 #----------------------------------------------------------------------
95 class MyTextDropTarget(wx.TextDropTarget):
96  """ドラッグ&ドロップ:コンポーネントのツリー画面からテキストデータを受け取るクラス"""
97  def __init__(self, parent, log):
98  """クラスの初期化(TextDropTargetの作成) [引数] parent -- 親クラス log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void
99 
100  [引数]
101  parent -- 親クラス
102  log -- ログ出力用クラス(wx.LogMessageのラッパー) [戻り値] void
103 
104  [戻り値]
105  void
106  """
107  wx.TextDropTarget.__init__(self)
108  self.parent = parent
109  self.log = log
110 
111  def OnDropText(self, x, y, text):
112  """ドロップ機能のイベントハンドラ 別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void
113  別ウィンドウからのドロップ操作で文字列を受け取る [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void
114 
115  [引数]
116  x -- マウスカーソルのx座標
117  y -- マウスカーソルのy座標
118  text -- ドロップされた文字列(現時点はコンポーネント名) [戻り値] void
119 
120  [戻り値]
121  void
122  """
123  self.log.WriteText("(%d, %d)\n%s\n" % (x, y, text))
124  canvas = self.parent.diagram.GetCanvas()
125  dc = wx.ClientDC(self.parent)
126  canvas.PrepareDC(dc)
127  self.parent.PrepareDC(dc)
128 
129  # NameService Treeからドロップされた名称を登録
130  if text not in self.parent.rtc_dict.keys():
131 
132 # print "drag text:",text , " kind:",check
133  ref = self.parent.frame.myDict.GetObjRefToFullpath(text)
134  kind = self.parent.frame.myDict.GetKindToFullpath(text)
135  if ref != None and kind == 'rtc':
136  self.parent.rtc_dict[text] = GRtc(self.parent, text, x, y)
137  self.parent.rtc_list.append(text)
138  self.parent.rtc_dict[text].refresh()
139  self.parent.remakeLines()
140  else:
141  print "error: Drag Item does not obj-ref!"
142 
143  self.parent.Redraw(dc)
144 
145  def OnDragOver(self, x, y, d):
146  """ドラッグ通知?イベントハンドラ マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する
147  マウスカーソルがターゲット上に来たら呼び出される [引数] x -- マウスカーソルのx座標 y -- マウスカーソルのy座標 d -- SHIFT or CONTROL 押下時のフラグ [戻り値] wxDragResult -- ドラッグの状態を(システムに?)通知する
148 
149  [引数]
150  x -- マウスカーソルのx座標
151  y -- マウスカーソルのy座標
152  d -- SHIFT or CONTROL 押下時のフラグ
153 
154  [戻り値]
155  wxDragResult -- ドラッグの状態を(システムに?)通知する
156  """
157  return wx.DragCopy
158 
159 #----------------------------------------------------------------------
160 def getBufferedDC(canvas):
161  """メモリDC(BufferedDC)を設定、取得する関数 [引数] canvas -- キャンバス [戻り値] dc -- BufferedDC
162 
163  [引数]
164  canvas -- キャンバス
165 
166  [戻り値]
167  dc -- BufferedDC
168  """
169  cdc = wx.ClientDC(canvas)
170  canvas.PrepareDC(cdc)
171  bufSize = wx.Size(1000, 1000)
172  dc = wx.BufferedDC(cdc, bufSize)
173  canvas.PrepareDC(dc)
174  dc.SetBackground(wx.Brush(canvas.GetBackgroundColour()))
175  dc.Clear()
176  return dc
177 #----------------------------------------------------------------------
178 def setBodyColor(shape, colorFlag):
179  """コンポーネントの状態で図形の色を変更する関数 [引数] shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void
180 
181  [引数]
182  shape -- 図形(Shape)オブジェクト colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void
183  colorFlag -- コンポーネントの状態を示す文字列 select, unloaded, inactive, active, error, virtual [戻り値] void
184  select, unloaded, inactive, active, error, virtual
185 
186  [戻り値]
187  void
188  """
189  if colorFlag == 'select':
190  shape.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR)))
191  elif colorFlag == 'unloaded':
192  shape.SetBrush(wx.Brush(wx.NamedColor(UNLOADED_COLOR)))
193  elif colorFlag == 'inactive':
194  shape.SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR)))
195  elif colorFlag == 'active':
196  shape.SetBrush(wx.Brush(wx.NamedColor(ACTIVE_COLOR)))
197  elif colorFlag == 'error':
198  shape.SetBrush(wx.Brush(wx.NamedColor(ERROR_COLOR)))
199  elif colorFlag == 'virtual':
200  shape.SetBrush(wx.Brush(wx.NamedColor(VIRTUAL_COLOR)))
201  else:
202  shape.SetBrush(wx.Brush(colorFlag))
203 
204  shape.Flash()
205 
206 #----------------------------------------------------------------------
207 class makeCompositeShape(ogl.CompositeShape):
208  """CompositeShapeのラッパークラス"""
209  def __init__(self, parent):
210  """クラスの初期化(CompositeShapeの作成) [引数] parent -- 親クラスを指定 [戻り値] void
211 
212  [引数]
213  parent -- 親クラスを指定 [戻り値] void
214 
215  [戻り値]
216  void
217  """
218  ogl.CompositeShape.__init__(self)
219  self.parent = parent
220 
221 #----------------------------------------------------------------------
222 class makeLineShape(ogl.LineShape):
223  """2点間の線を描画するラッパークラス"""
224  def __init__(self, parent, canvas ):
225  """クラスの初期化(LineShapeの作成) [引数] parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void
226 
227  [引数]
228  parent -- 親クラスを指定 canvas -- ShapeCanvasオブジェクトを指定。 [戻り値] void
229  canvas -- ShapeCanvasオブジェクトを指定。
230 
231  [戻り値]
232  void
233  """
234  ogl.LineShape.__init__(self)
235  self.parent = parent
236  self.SetCanvas(canvas)
237  self.SetPen(wx.Pen(wx.BLUE, 1))
238  setBodyColor(self, 'inactive')
239  self.MakeLineControlPoints(2)
240  diagram = canvas.GetDiagram()
241  diagram.AddShape(self)
242 
243  def setPoints(self, startX,startY, endX, endY):
244  """開始、終了座標を指定し線を作成する [引数] startX -- 線を描画開始するx座標 startY -- 線を描画開始するy座標 endX -- 線を描画終了するx座標 endY -- 線を描画終了するy座標 [戻り値] void
245 
246  [引数]
247  startX -- 線を描画開始するx座標
248  startY -- 線を描画開始するy座標
249  endX -- 線を描画終了するx座標
250  endY -- 線を描画終了するy座標
251 
252  [戻り値]
253  void
254  """
255  self.SetEnds(startX, startY, endX, endY)
256 
257 #----------------------------------------------------------------------
258 class makeRectangle(ogl.RectangleShape):
259  """四角形を描画するラッパークラス"""
260  def __init__(self, parent, width, height):
261  """クラスの初期化(Rectangle作成) [引数] parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void
262 
263  [引数]
264  parent -- 親クラスを指定 width -- 四角形の幅 height -- 四角形の高さ [戻り値] void
265  width -- 四角形の幅 height -- 四角形の高さ [戻り値] void
266  height -- 四角形の高さ
267 
268  [戻り値]
269  void
270  """
271  ogl.RectangleShape.__init__(self,width, height)
272  self.parent = parent
273  # lastx,lasty は、イベント(移動、拡大等)後の座標を格納、移動量や拡大比率で使用 self.lastx = 0 self.lasty = 0 #---------------------------------------------------------------------- class makeInportPolygon(ogl.PolygonShape): """インポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateInportPolygon(self, points): """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeOutportPolygon(ogl.PolygonShape): """アウトポート図形(polygon)描画用クラス""" def __init__(self, parent, points): """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ ogl.PolygonShape.__init__(self) self.parent = parent self.Create(points) self.CalculatePolygonCentre() def updateOutportPolygon(self, points): """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void """ self.Create(points) self.UpdateOriginalPoints() self.CalculatePolygonCentre() #---------------------------------------------------------------------- class makeRectOval(ogl.EllipseShape): """楕円図形を生成するクラス""" def __init__(self, parent, pos_x, pos_y, width, height): """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void """ ogl.EllipseShape.__init__(self, width, height) self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.lastx = pos_x self.lasty = pos_y self.SetX(pos_x) self.SetY(pos_y) self.SetPen(wx.Pen(wx.BLACK, 1)) self.SetBrush(wx.Brush('red')) #---------------------------------------------------------------------- class makeTextShape(ogl.TextShape): """テキストを生成するクラス""" def __init__(self, parent, width, height): """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void """ ogl.TextShape.__init__(self,width, height) self.parent = parent #---------------------------------------------------------------------- class makeToolTip(ogl.Shape): """ツールチップ(バルーンヘルプ)図形を生成するクラス""" def __init__(self,parent,pt,dc): """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ self.parent = parent self.body = None self.x_size = 0 self.y_size = 0 self.color = BACK_COLOR # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
274  self.lastx = 0
275  self.lasty = 0
276 
277 #----------------------------------------------------------------------
278 class makeInportPolygon(ogl.PolygonShape):
279  """インポート図形(polygon)描画用クラス"""
280  def __init__(self, parent, points):
281  """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
282 
283  [引数]
284  parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
285  points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
286 
287  [戻り値]
288  void
289  """
290  ogl.PolygonShape.__init__(self)
291  self.parent = parent
292 
293  self.Create(points)
294  self.CalculatePolygonCentre()
295 
296  def updateInportPolygon(self, points):
297  """インポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
298 
299  [引数]
300  points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
301 
302  [戻り値]
303  void
304  """
305  self.Create(points)
306  self.UpdateOriginalPoints()
307  self.CalculatePolygonCentre()
308 
309 #----------------------------------------------------------------------
310 class makeOutportPolygon(ogl.PolygonShape):
311  """アウトポート図形(polygon)描画用クラス"""
312  def __init__(self, parent, points):
313  """クラスの初期化(PolygonShapeの作成) [引数] parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
314 
315  [引数]
316  parent -- 親クラスを指定 points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
317  points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
318 
319  [戻り値]
320  void
321  """
322  ogl.PolygonShape.__init__(self)
323  self.parent = parent
324 
325  self.Create(points)
326  self.CalculatePolygonCentre()
327 
328  def updateOutportPolygon(self, points):
329  """アウトポート図形(polygon)の再描画(座標再指定) [引数] points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
330 
331  [引数]
332  points -- タプルで連続した(x,y)座標(wxPoints型)を指定 [戻り値] void
333 
334  [戻り値]
335  void
336  """
337  self.Create(points)
338  self.UpdateOriginalPoints()
339  self.CalculatePolygonCentre()
340 
341 #----------------------------------------------------------------------
342 class makeRectOval(ogl.EllipseShape):
343  """楕円図形を生成するクラス"""
344  def __init__(self, parent, pos_x, pos_y, width, height):
345  """クラスの初期化(EllipseShapeの作成) [引数] parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void
346 
347  [引数]
348  parent -- 親クラスを指定 pos_x -- 描画するx座標 pos_y -- 描画するy座標 width -- 楕円の幅 height -- 楕円の高さ [戻り値] void
349  pos_x -- 描画するx座標
350  pos_y -- 描画するy座標
351  width -- 楕円の幅 height -- 楕円の高さ [戻り値] void
352  height -- 楕円の高さ
353 
354  [戻り値]
355  void
356  """
357  ogl.EllipseShape.__init__(self, width, height)
358  self.parent = parent
359  self.pos_x = pos_x
360  self.pos_y = pos_y
361  self.lastx = pos_x
362  self.lasty = pos_y
363  self.SetX(pos_x)
364  self.SetY(pos_y)
365  self.SetPen(wx.Pen(wx.BLACK, 1))
366  self.SetBrush(wx.Brush('red'))
367 
368 #----------------------------------------------------------------------
369 class makeTextShape(ogl.TextShape):
370  """テキストを生成するクラス"""
371  def __init__(self, parent, width, height):
372  """クラスの初期化(TextShapeの作成) [引数] parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void
373 
374  [引数]
375  parent -- 親クラスを指定する width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void
376  width -- テキスト描画エリアの幅 height -- テキスト描画エリアの高さ [戻り値] void
377  height -- テキスト描画エリアの高さ
378 
379  [戻り値]
380  void
381  """
382  ogl.TextShape.__init__(self,width, height)
383  self.parent = parent
384 
385 #----------------------------------------------------------------------
386 class makeToolTip(ogl.Shape):
387  """ツールチップ(バルーンヘルプ)図形を生成するクラス"""
388  def __init__(self,parent,pt,dc):
389  """クラスの初期化(ツールチップの作成) [引数] parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
390 
391  [引数]
392  parent -- 親クラスを指定する pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
393  pt -- ツールチップを表示する座標(x,y)のタプルで指定 dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
394  dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
395 
396  [戻り値]
397  void
398  """
399  self.parent = parent
400  self.body = None
401  self.x_size = 0
402  self.y_size = 0
403  self.color = BACK_COLOR
404 
405  # 表示文字列の設定 if parent.tag == 'in': string1 = parent.inport['name'] string2 = parent.inport['port_type'] else: string1 = parent.outport['name'] string2 = parent.outport['port_type'] atr = '%s\n%s'%(string1, string2) tmp = max(len(string1), len(string2)) # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
406  if parent.tag == 'in':
407  string1 = parent.inport['name']
408  string2 = parent.inport['port_type']
409  else:
410  string1 = parent.outport['name']
411  string2 = parent.outport['port_type']
412  atr = '%s\n%s'%(string1, string2)
413 
414  tmp = max(len(string1), len(string2))
415  # カレントのフォントサイズ取得:Widthは平均値なので注意 charW = dc.GetCharWidth() charH = dc.GetCharHeight() self.x_size = charW * tmp self.y_size = charH * 2.5 # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
416  charW = dc.GetCharWidth()
417  charH = dc.GetCharHeight()
418  self.x_size = charW * tmp
419  self.y_size = charH * 2.5
420  # Rectangleに文字列を表示させツールチップの代用とする self.body = makeRectangle(self, self.x_size, self.y_size) self.body.AddText(atr) # self.body.SetFormatMode(ogl.FORMAT_NONE,0) self.body.FormatText(dc,atr,0) self.body.SetDraggable(False, False) # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
421  self.body = makeRectangle(self, self.x_size, self.y_size)
422  self.body.AddText(atr)
423 # self.body.SetFormatMode(ogl.FORMAT_NONE,0)
424  self.body.FormatText(dc,atr,0)
425  self.body.SetDraggable(False, False)
426  # 表示位置は、四角形の左下の頂点をマウスカーソルの位置に設定 self.body.SetX(pt[0]+self.x_size/2) self.body.SetY(pt[1]-self.y_size/2) self.body.SetPen(wx.Pen(wx.RED, 1)) self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR))) def removeWidget(self,dc): """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) #---------------------------------------------------------------------- class GRectOval(ogl.Shape): """線の移動用の円を生成するクラス""" def __init__(self,parent,tag,pos_x, pos_y): """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void """ self.parent = parent self.pos_x = pos_x self.pos_y = pos_y self.tag = tag self.createWidget() def createWidget(self): """円を生成 [引数] なし [戻り値] void """ self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8) def removeWidget(self, dc): """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) def dmove(self, dc, d_x, d_y): """円及び線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void """ canvas = self.body.GetCanvas() line = self.parent oval_tag = self.getTag() oval_id = oval_tag[0] # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
427  self.body.SetX(pt[0]+self.x_size/2)
428  self.body.SetY(pt[1]-self.y_size/2)
429  self.body.SetPen(wx.Pen(wx.RED, 1))
430  self.body.SetBrush(wx.Brush(wx.NamedColor(BACK_COLOR)))
431 
432  def removeWidget(self,dc):
433  """ツールチップ図形をキャンバス、DC上から削除 [引数] dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void
434 
435  [引数]
436  dc -- 描画されているデバイス・コンテキストを指定 [戻り値] void
437 
438  [戻り値]
439  void
440  """
441  canvas = self.body.GetCanvas()
442  self.body.Erase(dc)
443  self.body.RemoveFromCanvas(canvas)
444 
445 #----------------------------------------------------------------------
446 class GRectOval(ogl.Shape):
447  """線の移動用の円を生成するクラス"""
448  def __init__(self,parent,tag,pos_x, pos_y):
449  """クラスの初期化(円を作成) [引数] parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void
450 
451  [引数]
452  parent -- 親クラスを指定する tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void
453  tag -- 識別子(連番,線との関係を表すフラグ)を指定 ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void
454  ※連番は、線を格納する配列の添え字と連係している pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void
455  pos_x -- 表示するx座標を指定 pos_y -- 表示するy座標を指定 [戻り値] void
456  pos_y -- 表示するy座標を指定 [戻り値] void
457 
458  [戻り値]
459  void
460  """
461  self.parent = parent
462  self.pos_x = pos_x
463  self.pos_y = pos_y
464  self.tag = tag
465  self.createWidget()
466 
467  def createWidget(self):
468  """円を生成
469 
470  [引数]
471  なし
472 
473  [戻り値]
474  void
475  """
476  self.body = makeRectOval(self, self.pos_x, self.pos_y, 8, 8)
477 
478  def removeWidget(self, dc):
479  """円をキャンバス、DC上から削除 [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
480 
481  [引数]
482  dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
483 
484  [戻り値]
485  void
486  """
487  canvas = self.body.GetCanvas()
488  self.body.Erase(dc)
489  self.body.RemoveFromCanvas(canvas)
490 
491  def dmove(self, dc, d_x, d_y):
492  """円及び線の移動
493 
494  [引数]
495  dc -- 描画するデバイス・コンテキストを指定 d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void
496  d_x -- x座標の相対移動量 (endPoint.x - startPoint.x の値) d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void
497  d_y -- y座標の相対移動量 (endPoint.y - startPoint.y の値) [戻り値] void
498 
499  [戻り値]
500  void
501  """
502  canvas = self.body.GetCanvas()
503 
504  line = self.parent
505  oval_tag = self.getTag()
506  oval_id = oval_tag[0]
507 
508  # 移動前の図形をDC上から削除 self.body.Erase(dc) # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
509  self.body.Erase(dc)
510 
511  # 移動後の座標算出 if oval_tag[1] == 'oval_width_pos': self.pos_x = self.body.GetX() + d_x self.pos_y = self.body.GetY() else: self.pos_x = self.body.GetX() self.pos_y = self.body.GetY() + d_y # 新しい座標で線の再作成 line.lines[oval_id].Move(dc, self.pos_x, self.pos_y) x1,y1,x2,y2 = line.lines[oval_id].GetEnds() line.changeCoordT(oval_id, (x1, y1), (x2, y2) ) self.body.Move(dc, self.pos_x, self.pos_y) # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
512  if oval_tag[1] == 'oval_width_pos':
513  self.pos_x = self.body.GetX() + d_x
514  self.pos_y = self.body.GetY()
515  else:
516  self.pos_x = self.body.GetX()
517  self.pos_y = self.body.GetY() + d_y
518 
519  # 新しい座標で線の再作成
520  line.lines[oval_id].Move(dc, self.pos_x, self.pos_y)
521  x1,y1,x2,y2 = line.lines[oval_id].GetEnds()
522  line.changeCoordT(oval_id, (x1, y1), (x2, y2) )
523 
524  self.body.Move(dc, self.pos_x, self.pos_y)
525 
526  # 円の移動(座標の再計算) for x in range(1,len(line.oval_dict)+1): tag = line.oval_dict[x].getTag() if oval_id != tag[0]: line_pos_0 = line.coordT[x] line_pos_1 = line.coordT[x+1] if tag[1] == 'oval_width_pos': hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] else: width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] line.oval_dict[x].body.Move(dc, pos_x, pos_y) def getTag(self): """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している """ return self.tag #---------------------------------------------------------------------- class GRtcLine(ogl.Shape): """線を生成するクラス""" def __init__(self, canvas, parent): """クラスの初期化 [引数] canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void """ self.canvas = canvas self.parent = parent self.startx = 0 self.starty = 0 self.endx = 0 self.endy = 0 self.coordT = None self.g_inp = None self.g_outp = None self.idx = 'L' + `canvas.line_idx` self.curOvalObj = None # Value is setup GWorld.leftDown() self.oval_dict = {} self.tag = 'line' self.lines = [] self.subscription_type = RTM.OPS_NEW self.profile = None def refresh(self): """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) self.unselected(dc) def remove(self, dc, canvas): """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void """ for x in range(len(self.lines)): self.lines[x].Unlink() self.lines[x].Erase(dc) self.lines[x].DeleteControlPoints() self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def removeWidget(self, dc): """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void """ if self.g_inp: if len(self.g_inp.line_idx) == 1: setBodyColor(self.g_inp.body, 'inactive') if self.g_outp: if len(self.g_outp.line_idx) == 1: setBodyColor(self.g_outp.body, 'inactive') canvas = self.lines[0].GetCanvas() if self.g_outp != None: self.g_outp.disconnect(self.idx) self.g_outp = None if self.g_inp != None: self.g_inp.disconnect(self.idx) self.g_inp = None self.remove(dc, canvas) def createWidget(self): """線の生成 [引数] なし [戻り値] void """ num = len(self.coordT) if num < 2: return if num == 2: # 2点間の線 self.lines.append(makeLineShape(self, self.canvas)) self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy) else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
527  for x in range(1,len(line.oval_dict)+1):
528  tag = line.oval_dict[x].getTag()
529  if oval_id != tag[0]:
530  line_pos_0 = line.coordT[x]
531  line_pos_1 = line.coordT[x+1]
532 
533  if tag[1] == 'oval_width_pos':
534  hight = line_pos_0[1] - line_pos_1[1]
535  pos_y = line_pos_1[1] + (hight/2)
536  pos_x = line_pos_0[0]
537  else:
538  width = line_pos_0[0] - line_pos_1[0]
539  pos_x = line_pos_1[0] + (width/2)
540  pos_y = line_pos_1[1]
541 
542  line.oval_dict[x].body.Move(dc, pos_x, pos_y)
543 
544  def getTag(self):
545  """タグの取得 [引数] なし [戻り値] tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している
546 
547  [引数]
548  なし
549 
550  [戻り値]
551  tag -- 識別子(連番,線との関係を表すフラグ)を返却 ※連番は、線を格納する配列の添え字と連係している
552  ※連番は、線を格納する配列の添え字と連係している
553  """
554  return self.tag
555 
556 #----------------------------------------------------------------------
557 class GRtcLine(ogl.Shape):
558  """線を生成するクラス"""
559  def __init__(self, canvas, parent):
560  """クラスの初期化
561 
562  [引数]
563  canvas -- 描画するキャンバスを指定 parent -- 親クラスを指定する [戻り値] void
564  parent -- 親クラスを指定する [戻り値] void
565 
566  [戻り値]
567  void
568  """
569  self.canvas = canvas
570  self.parent = parent
571  self.startx = 0
572  self.starty = 0
573  self.endx = 0
574  self.endy = 0
575  self.coordT = None
576  self.g_inp = None
577  self.g_outp = None
578  self.idx = 'L' + `canvas.line_idx`
579  self.curOvalObj = None # Value is setup GWorld.leftDown()
580  self.oval_dict = {}
581  self.tag = 'line'
582  self.lines = []
583  self.subscription_type = RTM.OPS_NEW
584  self.profile = None
585 
586  def refresh(self):
587  """リフレッシュ処理 線及び移動用の円を非選択状態にする [引数] なし [戻り値] void
588  線及び移動用の円を非選択状態にする [引数] なし [戻り値] void
589 
590  [引数]
591  なし
592 
593  [戻り値]
594  void
595  """
596  canvas = self.body.GetCanvas()
597  dc = wx.ClientDC(canvas)
598  canvas.PrepareDC(dc)
599  self.unselected(dc)
600 
601  def remove(self, dc, canvas):
602  """線および移動用の円をキャンバス、DC上から削除する [引数] dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void
603 
604  [引数]
605  dc -- 描画されているデバイス・コンテキストを指定 canvas -- 描画されているキャンバスを指定 [戻り値] void
606  canvas -- 描画されているキャンバスを指定 [戻り値] void
607 
608  [戻り値]
609  void
610  """
611  for x in range(len(self.lines)):
612  self.lines[x].Unlink()
613  self.lines[x].Erase(dc)
614  self.lines[x].DeleteControlPoints()
615  self.lines[x].RemoveFromCanvas(canvas)
616 
617  for x in range(len(self.oval_dict)):
618  self.oval_dict[x+1].removeWidget(dc)
619 
620  def removeWidget(self, dc):
621  """線の削除 関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す [引数] dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
622  関連するInport/Outportの情報(色、unsubscribe)の更新処理を呼び出す
623 
624  [引数]
625  dc -- 描画するデバイス・コンテキストを指定 [戻り値] void
626 
627  [戻り値]
628  void
629  """
630  if self.g_inp:
631  if len(self.g_inp.line_idx) == 1:
632  setBodyColor(self.g_inp.body, 'inactive')
633  if self.g_outp:
634  if len(self.g_outp.line_idx) == 1:
635  setBodyColor(self.g_outp.body, 'inactive')
636  canvas = self.lines[0].GetCanvas()
637  if self.g_outp != None:
638  self.g_outp.disconnect(self.idx)
639  self.g_outp = None
640  if self.g_inp != None:
641  self.g_inp.disconnect(self.idx)
642  self.g_inp = None
643  self.remove(dc, canvas)
644 
645 
646  def createWidget(self):
647  """線の生成
648 
649  [引数]
650  なし
651 
652  [戻り値]
653  void
654  """
655  num = len(self.coordT)
656  if num < 2:
657  return
658 
659  if num == 2: # 2点間の線
660  self.lines.append(makeLineShape(self, self.canvas))
661  self.lines[0].setPoints(self.startx, self.starty, self.endx, self.endy)
662  else: # 折線(頂点が2つ以上) for cnt in range(num-1): self.lines.append(makeLineShape(self, self.canvas)) self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
663  for cnt in range(num-1):
664 
665  self.lines.append(makeLineShape(self, self.canvas))
666  self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1])
667 
668 
669  # イベント割付 for x in range(len(self.lines)): setBodyColor(self.lines[x], 'inactive') evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) def setPoints(self, startX,startY, endX, endY): """線の座標設定 [引数] startX -- 描画開始位置のx座標 startY -- 描画開始位置のy座標 endtX -- 描画終了位置のx座標 endtY -- 描画終了位置のy座標 [戻り値] void """ lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY) self.coordT = lineUtil.drawLine() self.startx = startX self.starty = startY self.endx = endX self.endy = endY self.createWidget() def setStartPoint(self, dc, movex,movey): """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
670  for x in range(len(self.lines)):
671  setBodyColor(self.lines[x], 'inactive')
672  evthandler2 = MyEvtHandlerLine()
673  evthandler2.SetShape(self.lines[x])
674  evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler())
675  self.lines[x].SetEventHandler(evthandler2)
676 
677  def setPoints(self, startX,startY, endX, endY):
678  """線の座標設定
679 
680  [引数]
681  startX -- 描画開始位置のx座標
682  startY -- 描画開始位置のy座標
683  endtX -- 描画終了位置のx座標
684  endtY -- 描画終了位置のy座標
685 
686  [戻り値]
687  void
688  """
689 
690  lineUtil = lu.LineUtil(self, self.g_inp, self.g_outp, startX, startY, endX, endY)
691  self.coordT = lineUtil.drawLine()
692 
693  self.startx = startX
694  self.starty = startY
695  self.endx = endX
696  self.endy = endY
697 
698  self.createWidget()
699 
700 
701  def setStartPoint(self, dc, movex,movey):
702  """線の開始点を再設定(開始点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void
703 
704  [引数]
705  dc -- 描画するデバイス・コンテキストを指定 movex -- 開始点x座標の相対移動量 movey -- 開始点y座標の相対移動量 [戻り値] void
706  movex -- 開始点x座標の相対移動量
707  movey -- 開始点y座標の相対移動量
708 
709  [戻り値]
710  void
711  """
712  canvas = self.lines[0].GetCanvas()
713  # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.startx = self.startx + movex self.starty = self.starty + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def setEndPoint(self, dc, shape, movex,movey): """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void """ canvas = self.lines[0].GetCanvas() # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
714  for x in range(len(self.lines)):
715  self.lines[x].Erase(dc)
716  self.lines[x].RemoveFromCanvas(canvas)
717  for x in range(len(self.oval_dict)):
718  self.oval_dict[x+1].removeWidget(dc)
719 
720  # 座標を再設定し線を生成
721  self.lines = []
722  self.startx = self.startx + movex
723  self.starty = self.starty + movey
724  self.setPoints(self.startx, self.starty, self.endx, self.endy)
725  for x in range(len(self.lines)):
726  self.lines[x].Show(True)
727 
728  def setEndPoint(self, dc, shape, movex,movey):
729  """線の終了点を再設定(終了点の移動) [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void
730 
731  [引数]
732  dc -- 描画するデバイス・コンテキストを指定 movex -- 終了点x座標の相対移動量 movey -- 終了点y座標の相対移動量 [戻り値] void
733  movex -- 終了点x座標の相対移動量
734  movey -- 終了点y座標の相対移動量
735 
736  [戻り値]
737  void
738  """
739  canvas = self.lines[0].GetCanvas()
740  # 図形をキャンバス、DC上から削除 for x in range(len(self.lines)): self.lines[x].Erase(dc) self.lines[x].RemoveFromCanvas(canvas) for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) # 座標を再設定し線を生成 self.lines = [] self.endx = self.endx + movex self.endy = self.endy + movey self.setPoints(self.startx, self.starty, self.endx, self.endy) for x in range(len(self.lines)): self.lines[x].Show(True) def selected(self): """線の選択処理(色の変更) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1)) self.lines[x].Flash() def unselected(self,dc): """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void """ for x in range(len(self.lines)): self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1)) self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR))) self.lines[x].Flash() for x in range(len(self.oval_dict)): self.oval_dict[x+1].removeWidget(dc) def dmove(self, dc, movex, movey): """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void """ pass def setLine2port(self, canvas, dc ): """線の生成 線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。 canvas.lineTo, canvas.lineFrom にポートを設定しておく。 [引数] canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void """ # オブジェクトリファレンスの確認 ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath) if not ref: return if canvas.lineFrom.parent.tag == 'in': self.g_inp = canvas.lineFrom.parent self.g_outp = canvas.lineTo.parent else: self.g_inp = canvas.lineTo.parent self.g_outp = canvas.lineFrom.parent # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
741  for x in range(len(self.lines)):
742  self.lines[x].Erase(dc)
743  self.lines[x].RemoveFromCanvas(canvas)
744  for x in range(len(self.oval_dict)):
745  self.oval_dict[x+1].removeWidget(dc)
746 
747  # 座標を再設定し線を生成
748  self.lines = []
749  self.endx = self.endx + movex
750  self.endy = self.endy + movey
751  self.setPoints(self.startx, self.starty, self.endx, self.endy)
752  for x in range(len(self.lines)):
753  self.lines[x].Show(True)
754 
755  def selected(self):
756  """線の選択処理(色の変更) [引数] なし [戻り値] void
757 
758  [引数]
759  なし
760 
761  [戻り値]
762  void
763  """
764  for x in range(len(self.lines)):
765  self.lines[x].SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR)))
766  self.lines[x].SetPen(wx.Pen(SELECTED_COLOR, 1))
767  self.lines[x].Flash()
768 
769  def unselected(self,dc):
770  """線の選択解除処理(色の変更、移動用の円を削除) [引数] なし [戻り値] void
771 
772  [引数]
773  なし
774 
775  [戻り値]
776  void
777  """
778  for x in range(len(self.lines)):
779  self.lines[x].SetPen(wx.Pen(INACTIVE_COLOR, 1))
780  self.lines[x].SetBrush(wx.Brush(wx.NamedColor(INACTIVE_COLOR)))
781  self.lines[x].Flash()
782  for x in range(len(self.oval_dict)):
783  self.oval_dict[x+1].removeWidget(dc)
784 
785  def dmove(self, dc, movex, movey):
786  """移動処理のダミールーチン [引数] dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void
787 
788  [引数]
789  dc -- DCを指定 movex -- 移動時の相対距離 movey -- 移動時の相対距離 [戻り値] void
790  movex -- 移動時の相対距離
791  movey -- 移動時の相対距離
792 
793  [戻り値]
794  void
795  """
796  pass
797 
798  def setLine2port(self, canvas, dc ):
799  """線の生成
800  線を引く2つのポートをあらかじめ指定し本メソッドを呼び出す。
801  canvas.lineTo, canvas.lineFrom にポートを設定しておく。
802 
803  [引数]
804  canvas -- 線を描画するキャンバスを指定 dc -- 線を描画するDCを指定 [戻り値] void
805  dc -- 線を描画するDCを指定 [戻り値] void
806 
807  [戻り値]
808  void
809  """
810  # オブジェクトリファレンスの確認
811  ref = canvas.lineTo.parent.ns_dict.GetObjRefToFullpath(canvas.lineTo.parent.fullpath)
812  if not ref:
813  return
814  if canvas.lineFrom.parent.tag == 'in':
815  self.g_inp = canvas.lineFrom.parent
816  self.g_outp = canvas.lineTo.parent
817  else:
818  self.g_inp = canvas.lineTo.parent
819  self.g_outp = canvas.lineFrom.parent
820  # 線の生成とイベントの割付 self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY()) for x in range(len(self.lines)): evthandler2 = MyEvtHandlerLine() evthandler2.SetShape(self.lines[x]) evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler()) self.lines[x].SetEventHandler(evthandler2) # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
821  self.setPoints(self.g_inp.body.GetX(), self.g_inp.body.GetY(), self.g_outp.body.GetX(), self.g_outp.body.GetY())
822  for x in range(len(self.lines)):
823  evthandler2 = MyEvtHandlerLine()
824  evthandler2.SetShape(self.lines[x])
825  evthandler2.SetPreviousHandler(self.lines[x].GetEventHandler())
826  self.lines[x].SetEventHandler(evthandler2)
827 
828  # キャンバスへラインの登録及びラインカウンターのアップ canvas.line[self.idx] = self self.g_inp.connect(self.idx) canvas.line_idx = canvas.line_idx + 1 for x in range(len(self.lines)): self.lines[x].Show(True) # Inport/Outport の色の変更 self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY()) self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY()) setBodyColor(self.g_inp.body, 'active') setBodyColor(self.g_outp.body, 'active') def changeCoordT(self, id, new_p1, new_p2): """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void """ self.coordT[id] = new_p1 self.coordT[id+1] = new_p2 num = len(self.coordT) for cnt in range(num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) def childMove(self, dc, pos_new): """線の移動 [引数] dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void """ # canvas = self.body.GetCanvas() max_num = len(pos_new) if max_num <= 2: return self.coordT = pos_new for cnt in range(max_num-1): self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1]) #---------------------------------------------------------------------- class GRtcIn(ogl.Shape): """インポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y): """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.inport = inp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.tag = 'in' self.points = [] self.createWidget() def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """インポート図形を生成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
829  canvas.line[self.idx] = self
830  self.g_inp.connect(self.idx)
831  canvas.line_idx = canvas.line_idx + 1
832  for x in range(len(self.lines)):
833  self.lines[x].Show(True)
834  # Inport/Outport の色の変更
835  self.g_inp.body.Move(dc, self.g_inp.body.GetX(), self.g_inp.body.GetY())
836  self.g_outp.body.Move(dc, self.g_outp.body.GetX(), self.g_outp.body.GetY())
837  setBodyColor(self.g_inp.body, 'active')
838  setBodyColor(self.g_outp.body, 'active')
839 
840  def changeCoordT(self, id, new_p1, new_p2):
841  """線移動時に移動した線の座標を再設定 [引数] id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void
842 
843  [引数]
844  id -- 座標を再設定する開始インデックス(添え字) new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void
845  new_p1 -- 新しい座標(x,y)の開始点をタプルで指定 new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void
846  new_p2 -- 新しい座標(x,y)の終了点をタプルで指定 [戻り値] void
847 
848  [戻り値]
849  void
850  """
851  self.coordT[id] = new_p1
852  self.coordT[id+1] = new_p2
853 
854  num = len(self.coordT)
855  for cnt in range(num-1):
856  self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1])
857 
858  def childMove(self, dc, pos_new):
859  """線の移動
860 
861  [引数]
862  dc -- 描画するデバイス・コンテキストを指定 pos_new -- 移動後の座標リスト [戻り値] void
863  pos_new -- 移動後の座標リスト [戻り値] void
864 
865  [戻り値]
866  void
867  """
868 # canvas = self.body.GetCanvas()
869 
870  max_num = len(pos_new)
871  if max_num <= 2:
872  return
873 
874  self.coordT = pos_new
875  for cnt in range(max_num-1):
876  self.lines[cnt].setPoints(self.coordT[cnt][0], self.coordT[cnt][1], self.coordT[cnt+1][0], self.coordT[cnt+1][1])
877 
878 #----------------------------------------------------------------------
879 class GRtcIn(ogl.Shape):
880  """インポート図形を作成するクラス"""
881  def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y):
882  """クラスの初期化(インポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void
883 
884  [引数]
885  parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void
886  ns_data -- コンポーネントのディクショナリー
887  inp -- インポートのディクショナリー(in_list[n])
888  pos_x -- インポート図形のx座標
889  pos_y -- インポート図形のy座標
890 
891  [戻り値]
892  void
893  """
894  ogl.Shape.__init__(self)
895  self.parent = parent
896  self.ns_dict = ns_dict
897  self.fullpath = fullpath
898  self.inport = inp
899  self.x = pos_x
900  self.y = pos_y
901  self.x_size = POLYGON_SIZE
902  self.y_size = POLYGON_SIZE
903  self.line = []
904  self.line_idx = [] # Lxx line index
905  self.position = 'Left' # current position on compornent widget Left/Right/Top/Bottom
906  self.textwin = 'non'
907  self.tag = 'in'
908  self.points = []
909  self.createWidget()
910 
911  def getConfig(self, name) :
912  """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:
913 
914  [引数]
915  name -- 取得したい値のフラグを指定する フラグ:
916  フラグ:'x', 'y', 'position'
917 
918  [戻り値]
919  void
920  """
921  if name == 'x' :
922  return self.x
923  elif name == 'y' :
924  return self.y
925  elif name == 'position' :
926  return self.position
927  else :
928  return None
929 
930  def removeWidget(self, dc, rot=0):
931  """インポート図形をキャンバス、DC上から削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
932 
933  [引数]
934  dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
935  rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
936  0:線を削除 / 1:線を削除しない
937 
938  [戻り値]
939  void
940  """
941  canvas = self.body.GetCanvas()
942  self.body.Erase(dc)
943  self.body.RemoveFromCanvas(canvas)
944 
945  # line
946  if rot == 0:
947  line_list = copy.deepcopy(self.line_idx)
948  for idx in line_list:
949  canvas.line[idx].removeWidget(dc)
950  if idx in canvas.line.keys():
951  del canvas.line[idx]
952  self.line_idx = []
953 
954  def createWidget(self):
955  """インポート図形を生成する [引数] なし [戻り値] void
956 
957  [引数]
958  なし
959 
960  [戻り値]
961  void
962  """
963  self.color = INACTIVE_COLOR
964  # 座標の設定 self.dcoords() # 図形の生成 self.body = makeInportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
965  self.dcoords()
966  # 図形の生成
967  self.body = makeInportPolygon(self, self.points)
968  # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1) def dmove(self, dc, movex, movey): """インポート図形の移動 インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.body.Erase(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Move(dc, self.x, self.y) # line for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def delLineIdx(self,idx): """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """インポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """インポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """インポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
969  self.parent.parent.MyAddShape(
970  self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "" , 1)
971 
972  def dmove(self, dc, movex, movey):
973  """インポート図形の移動
974  インポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
975 
976  [引数]
977  dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
978  movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
979  movey -- y座標の相対移動量を指定 [戻り値] void
980 
981  [戻り値]
982  void
983  """
984  canvas = self.body.GetCanvas()
985  canvas.PrepareDC(dc)
986 
987  self.body.Erase(dc)
988  self.x = self.body.GetX() + movex
989  self.y = self.body.GetY() + movey
990  self.body.Move(dc, self.x, self.y)
991 
992  # line
993  for line_index in self.line_idx:
994  canvas.line[line_index].setStartPoint(dc, movex, movey)
995 
996  def delLineIdx(self,idx):
997  """インポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void
998 
999  [引数]
1000  idx -- 線のインデックス
1001 
1002  [戻り値]
1003  void
1004  """
1005  if idx in self.line_idx:
1006  tmp = self.line_idx.index(idx)
1007  del self.line_idx[tmp]
1008 
1009  def selected(self):
1010  """インポートを選択状態にする [引数] なし [戻り値] void
1011 
1012  [引数]
1013  なし
1014 
1015  [戻り値]
1016  void
1017  """
1018  self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR)))
1019  self.body.Flash()
1020 
1021  def unselected(self,dc):
1022  """インポートを非選択状態にする [引数] なし [戻り値] void
1023 
1024  [引数]
1025  なし
1026 
1027  [戻り値]
1028  void
1029  """
1030  self.body.SetBrush(wx.Brush(wx.NamedColor(self.color)))
1031  self.body.Flash()
1032 
1033  def updatePolygonSize(self, x, y, ratioW, ratioH):
1034  """インポート図形のサイズ変更
1035 
1036  [引数]
1037  x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void
1038  y -- サイズ変更後のy座標を指定 ratioW -- サイズ変更を行うWidthのサイズ比率 ratioH -- サイズ変更を行うHeightのサイズ比率 [戻り値] void
1039  ratioW -- サイズ変更を行うWidthのサイズ比率
1040  ratioH -- サイズ変更を行うHeightのサイズ比率
1041 
1042  [戻り値]
1043  void
1044  """
1045  movex = x - self.body.GetX()
1046  movey = y - self.body.GetY()
1047  self.x = x
1048  self.y = y
1049  # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1050  if self.parent.xy_swap == 1:
1051  self.y_size, self.x_size = self.body.GetBoundingBoxMin()
1052  self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size
1053  else:
1054  self.x_size, self.y_size = self.body.GetBoundingBoxMin()
1055 
1056  # ポリゴンサイズの再計算
1057  self.parent.px_size = self.x_size
1058  self.parent.py_size = self.y_size
1059  canvas = self.body.GetCanvas()
1060  dc = wx.ClientDC(canvas)
1061  canvas.PrepareDC(dc)
1062  brush = self.body.GetBrush()
1063  # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1064  self.body.Erase(dc)
1065  self.body.RemoveFromCanvas(canvas)
1066  # 座標の再設定 self.dcoords() self.body.updateInportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1067  self.dcoords()
1068  self.body.updateInportPolygon(self.points)
1069  # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1070  self.parent.parent.MyAddShape(
1071  self.body, self.x , self.y,
1072  wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1)
1073 
1074  # 線を再設定(インポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setStartPoint(dc, movex, movey) def connect(self, line_idx): """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功 """ ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) if not ref: return 0 else: self.line_idx.append(line_idx) return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else: return 0 def dcoords(self): """インポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2), (self.x, self.y), (self.x + self.x_size , self.y), (self.x + self.x_size , self.y + self.y_size ), (self.x , self.y + self.y_size ), (self.x + self.x_size/2-1, self.y + self.y_size/2) ] elif self.position == 'Right' : self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size/2+1, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size/2, self.y+self.y_size/2-1) ] elif self.position == 'Bottom' : self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1), (self.x, self.y+self.y_size), (self.x, self.y), (self.x+self.x_size, self.y), (self.x+self.x_size, self.y+self.y_size), (self.x+self.x_size/2, self.y+self.y_size/2+1) ] #---------------------------------------------------------------------- class GRtcOut(ogl.Shape): """アウトポート図形を作成するクラス""" def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) : """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.ns_dict = ns_dict self.fullpath = fullpath self.outport = outp self.x = pos_x self.y = pos_y self.x_size = POLYGON_SIZE self.y_size = POLYGON_SIZE self.line = [] self.line_idx = [] # Lxx line index self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom self.textwin = 'non' self.isInactive = 0 self.tag = 'out' self.uuid = {} self.subscription_type = RTM.OPS_NEW self.createWidget() def refresh(self): """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void """ canvas = self.body.GetCanvas() if canvas.viewMode == True: return dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for idx in self.line_idx: # for line try: # g_inp update # state get ?? for inp in self.parent.in_list : if inp['name'] == canvas.line[idx].g_inp.inport['name']: canvas.line[idx].g_inp.inport = inp break ref = canvas.line[idx].g_inp.inport['ref'] ref = ref._narrow(RTM.InPort) except : except_mess('inport object-ref failure:%s\n'%inp['name']) setBodyColor(canvas.line[idx].g_inp.body, 'inactive') try : ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) rslt = ref.unsubscribe(self.uuid[idx]) print "refresh:unsubscribe:",rslt if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : except_mess('unsubscribe failure:') def getConfig(self, name) : """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:'x', 'y', 'position' [戻り値] void """ if name == 'x' : return self.x elif name == 'y' : return self.y elif name == 'position' : return self.position else : return None def removeWidget(self, dc, rot=0): """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # line if rot == 0: line_list = copy.deepcopy(self.line_idx) for idx in line_list: canvas.line[idx].removeWidget(dc) if idx in canvas.line.keys(): del canvas.line[idx] self.line_idx = [] def createWidget(self): """アウトポート図形を作成する [引数] なし [戻り値] void """ self.color = INACTIVE_COLOR # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1075  for line_index in self.line_idx:
1076  canvas.line[line_index].setStartPoint(dc, movex, movey)
1077 
1078  def connect(self, line_idx):
1079  """コネクト処理(線のインデックスを格納) [引数] line_idx -- インポートに接続する線のインデックス [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功
1080 
1081  [引数]
1082  line_idx -- インポートに接続する線のインデックス
1083 
1084  [戻り値]
1085  成否フラグ -- 0:エラー(オブジェクトリファレンス無し) / 1:成功
1086  """
1087  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
1088  if not ref:
1089  return 0
1090  else:
1091  self.line_idx.append(line_idx)
1092  return 1
1093 
1094  def disconnect(self, line_idx):
1095  """ディスコネクト処理(線のインデックスを削除) [引数] line_idx -- インポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功
1096 
1097  [引数]
1098  line_idx -- インポートに接続している線のインデックス
1099 
1100  [戻り値]
1101  成否フラグ -- 0:エラー / 1:成功
1102  """
1103  if line_idx in self.line_idx:
1104  self.delLineIdx(line_idx)
1105  return 1
1106  else:
1107  return 0
1108 
1109  def dcoords(self):
1110  """インポート図形の座標設定
1111  現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void
1112  各頂点は(x,y)のタプル形式
1113 
1114  [引数]
1115  なし
1116 
1117  [戻り値]
1118  void
1119  """
1120  if self.position == 'Left':
1121  self.points = [ (self.x + self.x_size/2-1, self.y + self.y_size/2),
1122  (self.x, self.y),
1123  (self.x + self.x_size , self.y),
1124  (self.x + self.x_size , self.y + self.y_size ),
1125  (self.x , self.y + self.y_size ),
1126  (self.x + self.x_size/2-1, self.y + self.y_size/2)
1127  ]
1128  elif self.position == 'Right' :
1129  self.points = [ (self.x+self.x_size/2+1, self.y+self.y_size/2),
1130  (self.x+self.x_size, self.y+self.y_size),
1131  (self.x, self.y+self.y_size),
1132  (self.x, self.y),
1133  (self.x+self.x_size, self.y),
1134  (self.x+self.x_size/2+1, self.y+self.y_size/2)
1135  ]
1136  elif self.position == 'Top' :
1137  self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2-1),
1138  (self.x+self.x_size, self.y),
1139  (self.x+self.x_size, self.y+self.y_size),
1140  (self.x, self.y+self.y_size),
1141  (self.x, self.y),
1142  (self.x+self.x_size/2, self.y+self.y_size/2-1)
1143  ]
1144  elif self.position == 'Bottom' :
1145  self.points = [ (self.x+self.x_size/2, self.y+self.y_size/2+1),
1146  (self.x, self.y+self.y_size),
1147  (self.x, self.y),
1148  (self.x+self.x_size, self.y),
1149  (self.x+self.x_size, self.y+self.y_size),
1150  (self.x+self.x_size/2, self.y+self.y_size/2+1)
1151  ]
1152 
1153 #----------------------------------------------------------------------
1154 class GRtcOut(ogl.Shape):
1155  """アウトポート図形を作成するクラス"""
1156  def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y) :
1157  """クラスの初期化(アウトポート図形の作成) [引数] parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void
1158 
1159  [引数]
1160  parent -- 親クラスを指定する ns_data -- コンポーネントのディクショナリー inp -- インポートのディクショナリー(in_list[n]) pos_x -- インポート図形のx座標 pos_y -- インポート図形のy座標 [戻り値] void
1161  ns_data -- コンポーネントのディクショナリー
1162  inp -- インポートのディクショナリー(in_list[n])
1163  pos_x -- インポート図形のx座標
1164  pos_y -- インポート図形のy座標
1165 
1166  [戻り値]
1167  void
1168  """
1169  ogl.Shape.__init__(self)
1170  self.parent = parent
1171  self.ns_dict = ns_dict
1172  self.fullpath = fullpath
1173  self.outport = outp
1174  self.x = pos_x
1175  self.y = pos_y
1176  self.x_size = POLYGON_SIZE
1177  self.y_size = POLYGON_SIZE
1178  self.line = []
1179  self.line_idx = [] # Lxx line index
1180  self.position = 'Right' # current position on compornent widget Left/Right/Top/Bottom
1181  self.textwin = 'non'
1182  self.isInactive = 0
1183  self.tag = 'out'
1184  self.uuid = {}
1185  self.subscription_type = RTM.OPS_NEW
1186  self.createWidget()
1187 
1188  def refresh(self):
1189  """リフレッシュ処理 現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void
1190  現在の接続状況(Inportのオブジェクトリファレンスが存在するか?)を チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void
1191  チェックし、接続状態を継続もしくはunsubscribeを実行する [引数] なし [戻り値] void
1192 
1193  [引数]
1194  なし
1195 
1196  [戻り値]
1197  void
1198  """
1199  canvas = self.body.GetCanvas()
1200  if canvas.viewMode == True:
1201  return
1202 
1203  dc = wx.ClientDC(canvas)
1204  canvas.PrepareDC(dc)
1205  for idx in self.line_idx:
1206  # for line
1207  try:
1208  # g_inp update
1209  # state get ??
1210  for inp in self.parent.in_list :
1211  if inp['name'] == canvas.line[idx].g_inp.inport['name']:
1212  canvas.line[idx].g_inp.inport = inp
1213  break
1214 
1215  ref = canvas.line[idx].g_inp.inport['ref']
1216  ref = ref._narrow(RTM.InPort)
1217  except :
1218  except_mess('inport object-ref failure:%s\n'%inp['name'])
1219  setBodyColor(canvas.line[idx].g_inp.body, 'inactive')
1220  try :
1221  ref = self.outport['ref']
1222  ref = ref._narrow(RTM.OutPort)
1223  rslt = ref.unsubscribe(self.uuid[idx])
1224  print "refresh:unsubscribe:",rslt
1225  if rslt != 0:
1226  print 'unsubscribe failure: rslt=',rslt
1227  except :
1228  except_mess('unsubscribe failure:')
1229 
1230  def getConfig(self, name) :
1231  """x,y座標もしくはpositionを取得する [引数] name -- 取得したい値のフラグを指定する フラグ:
1232 
1233  [引数]
1234  name -- 取得したい値のフラグを指定する フラグ:
1235  フラグ:'x', 'y', 'position'
1236 
1237  [戻り値]
1238  void
1239  """
1240  if name == 'x' :
1241  return self.x
1242  elif name == 'y' :
1243  return self.y
1244  elif name == 'position' :
1245  return self.position
1246  else :
1247  return None
1248 
1249  def removeWidget(self, dc, rot=0):
1250  """アウトポート図形を削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
1251 
1252  [引数]
1253  dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
1254  rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
1255  0:線を削除 / 1:線を削除しない
1256 
1257  [戻り値]
1258  void
1259  """
1260  canvas = self.body.GetCanvas()
1261  self.body.Erase(dc)
1262  self.body.RemoveFromCanvas(canvas)
1263 
1264  # line
1265  if rot == 0:
1266  line_list = copy.deepcopy(self.line_idx)
1267  for idx in line_list:
1268  canvas.line[idx].removeWidget(dc)
1269  if idx in canvas.line.keys():
1270  del canvas.line[idx]
1271  self.line_idx = []
1272 
1273  def createWidget(self):
1274  """アウトポート図形を作成する [引数] なし [戻り値] void
1275 
1276  [引数]
1277  なし
1278 
1279  [戻り値]
1280  void
1281  """
1282  self.color = INACTIVE_COLOR
1283  # 座標の設定 self.dcoords() # 図形の生成 self.body = makeOutportPolygon(self, self.points) # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1284  self.dcoords()
1285  # 図形の生成
1286  self.body = makeOutportPolygon(self, self.points)
1287  # イベントや図形の割付 self.parent.parent.MyAddShape( self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1) def dmove(self, dc, movex, movey): """アウトポート図形の移動 アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() canvas.PrepareDC(dc) self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # line num = 0 for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) num = num+1 def delLineIdx(self, idx): """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void """ if idx in self.line_idx: tmp = self.line_idx.index(idx) del self.line_idx[tmp] def selected(self): """アウトポートを選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() def unselected(self,dc): """アウトポートを非選択状態にする [引数] なし [戻り値] void """ self.body.SetBrush(wx.Brush(wx.NamedColor(self.color))) self.body.Flash() def updatePolygonSize(self, x, y, ratioW, ratioH): """アウトポート図形のサイズ変更 [引数] x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void """ movex = x - self.body.GetX() movey = y - self.body.GetY() self.x = x self.y = y # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1288  self.parent.parent.MyAddShape(
1289  self.body, self.x+POLYGON_SIZE/2-1, self.y+POLYGON_SIZE/2-1, wx.Pen(OUTLINE_COLOR, 1), wx.Brush(self.color, wx.SOLID), "",1)
1290 
1291  def dmove(self, dc, movex, movey):
1292  """アウトポート図形の移動
1293  アウトポートに割り付けられている線も同時に移動させる [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
1294 
1295  [引数]
1296  dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
1297  movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
1298  movey -- y座標の相対移動量を指定 [戻り値] void
1299 
1300  [戻り値]
1301  void
1302  """
1303  canvas = self.body.GetCanvas()
1304  canvas.PrepareDC(dc)
1305 
1306  self.x = self.body.GetX() + movex
1307  self.y = self.body.GetY() + movey
1308  self.body.Erase(dc)
1309  self.body.Move(dc, self.x, self.y)
1310 
1311  # line
1312  num = 0
1313  for line_index in self.line_idx:
1314  canvas.line[line_index].setEndPoint(dc, self.body,movex, movey)
1315  num = num+1
1316 
1317  def delLineIdx(self, idx):
1318  """アウトポートに割り付けた線のインデックスを削除する [引数] idx -- 線のインデックス [戻り値] void
1319 
1320  [引数]
1321  idx -- 線のインデックス
1322 
1323  [戻り値]
1324  void
1325  """
1326  if idx in self.line_idx:
1327  tmp = self.line_idx.index(idx)
1328  del self.line_idx[tmp]
1329 
1330  def selected(self):
1331  """アウトポートを選択状態にする [引数] なし [戻り値] void
1332 
1333  [引数]
1334  なし
1335 
1336  [戻り値]
1337  void
1338  """
1339  self.body.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR)))
1340  self.body.Flash()
1341 
1342  def unselected(self,dc):
1343  """アウトポートを非選択状態にする [引数] なし [戻り値] void
1344 
1345  [引数]
1346  なし
1347 
1348  [戻り値]
1349  void
1350  """
1351  self.body.SetBrush(wx.Brush(wx.NamedColor(self.color)))
1352  self.body.Flash()
1353 
1354  def updatePolygonSize(self, x, y, ratioW, ratioH):
1355  """アウトポート図形のサイズ変更
1356 
1357  [引数]
1358  x -- サイズ変更後のx座標を指定 y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void
1359  y -- サイズ変更後のy座標を指定 ratioW -- 変更を行うWidthのサイズ比率 ratioH -- 変更を行うHeightのサイズ比率 [戻り値] void
1360  ratioW -- 変更を行うWidthのサイズ比率
1361  ratioH -- 変更を行うHeightのサイズ比率
1362 
1363  [戻り値]
1364  void
1365  """
1366  movex = x - self.body.GetX()
1367  movey = y - self.body.GetY()
1368  self.x = x
1369  self.y = y
1370  # 図形回転後にwidth,heightを入れ替える if self.parent.xy_swap == 1: self.y_size, self.x_size = self.body.GetBoundingBoxMin() self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size else: self.x_size, self.y_size = self.body.GetBoundingBoxMin() # ポリゴンサイズの再計算 self.parent.px_size = self.x_size self.parent.py_size = self.y_size canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) brush = self.body.GetBrush() # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1371  if self.parent.xy_swap == 1:
1372  self.y_size, self.x_size = self.body.GetBoundingBoxMin()
1373  self.parent.py_size, self.parent.px_size = self.parent.px_size, self.parent.py_size
1374  else:
1375  self.x_size, self.y_size = self.body.GetBoundingBoxMin()
1376  # ポリゴンサイズの再計算
1377  self.parent.px_size = self.x_size
1378  self.parent.py_size = self.y_size
1379  canvas = self.body.GetCanvas()
1380  dc = wx.ClientDC(canvas)
1381  canvas.PrepareDC(dc)
1382  brush = self.body.GetBrush()
1383  # 図形をキャンバス、DC上から削除する self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1384  self.body.Erase(dc)
1385  self.body.RemoveFromCanvas(canvas)
1386  # 座標の再設定 self.dcoords() self.body.updateOutportPolygon(self.points) # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1387  self.dcoords()
1388  self.body.updateOutportPolygon(self.points)
1389  # 新しい図形にイベントを割付 self.parent.parent.MyAddShape( self.body, self.x , self.y, wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1) # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1390  self.parent.parent.MyAddShape(
1391  self.body, self.x , self.y,
1392  wx.Pen(OUTLINE_COLOR, 1), brush, "" , 1)
1393 
1394  # 線を再設定(アウトポートの位置に合わせ移動) for line_index in self.line_idx: canvas.line[line_index].setEndPoint(dc, self.body,movex, movey) def connect2(self, line_idx, subscription_type): """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() # get outport-object-ref ref = self.outport['ref'] if ref == None : return 0 try: ref = ref._narrow(RTM.OutPort) except: except_mess('outport obj-ref failure:') return 0 # get inport-object-ref inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 connect_num = self.checkConnect(inp_ref, subscription_list) if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile) self.uuid[line_idx] = canvas.line[line_idx].profile.id if rslt != 0: print "subscribe failure!" except: except_mess('subscribe failure:') print "connect2 subscribe :",self.uuid[line_idx] else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id return 1 def connect(self, line_idx, subscription_type): """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功 """ canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry try: ref = self.outport['ref'] if ref == None : return 0 ref = ref._narrow(RTM.OutPort) break except: except_mess('outport obj-ref failure:') self.parent.refresh() if n == 2: print "error retry" return 0 inp_ref = canvas.line[line_idx].g_inp.inport['ref'] try: inp_ref = inp_ref._narrow(RTM.InPort) except: except_mess('inport obj-ref failure:') return 0 # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 except: except_mess('get subscriptions failure:') return 0 canvas.line[line_idx].subscription_type = subscription_type canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[]) connect_num = self.checkConnect(inp_ref, subscription_list) #assembly dummy # connect_num = -1 #assembly dummy rslt = 0 if canvas.viewMode == False: if connect_num == -1: try: canvas.line[line_idx].profile.out_port = ref canvas.line[line_idx].profile.in_port = inp_ref (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile) if rslt != 0: print "subscribe failuer! :rslt=",rslt self.uuid[line_idx] = canvas.line[line_idx].profile.id print "connect subscribe :",self.uuid[line_idx] except: err_mess = 'subscribe failure! :' except_mess(err_mess) else: rslt = 0 # get uuid self.uuid[line_idx] = subscription_list[connect_num].id if rslt : print "subsrcibe-rslt:",rslt return 0 else : self.line_idx.append(line_idx) self.isInactive = self.isInactive + 1 return 1 def disconnect(self, line_idx): """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功 """ if self.isInactive == 1 : setBodyColor(self.body, 'inactive') canvas = self.body.GetCanvas() n = 0 for n in range(2): # for retry ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) inp_obj = canvas.line[line_idx].g_inp.inport['ref'] # get subscription-list subscription_list = [] subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return 0 connect_num = self.checkConnect(inp_obj, subscription_list) #assembly dummy # connect_num = 0 #assembly dummy break except: err_mess = 'outport disconnect failure:' except_mess(err_mess) connect_num = -1 self.parent.refresh() if n == 2: # bad connect return 0 if ref != None and canvas.viewMode == False and connect_num != -1: try : print "unsubscribe :",self.uuid[line_idx] rslt = ref.unsubscribe(self.uuid[line_idx]) if rslt != 0: print 'unsubscribe failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) self.isInactive = self.isInactive - 1 if line_idx in self.line_idx: self.delLineIdx(line_idx) return 1 else : return 0 def remakeLines(self): """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) rtc_list = self.parent.parent.rtc_list rtc_dict = self.parent.parent.rtc_dict ret_name = [] ret_obj = [] ret_ref = [] for subscr in subscr_list_tmp: inp_ref = subscr.in_port for fullname in rtc_list: in_list = rtc_dict[fullname].in_list in_dict = rtc_dict[fullname].in_dict for inp in in_list: if inp['name'] in in_dict.keys(): ref = in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(ref): print "_is_equivalent is OK!!!" ret_name.append( inp['name'] ) ret_obj.append( in_dict[inp['name']] ) ret_ref.append(inp_ref) for num in range(len(ret_name)): canvas.lineFrom = self.body canvas.lineTo = ret_obj[num].body line = GRtcLine(canvas,self) line.setLine2port(canvas, dc) self.line_idx.append(line.idx) self.isInactive = self.isInactive + 1 connect_num = self.checkConnect(ret_ref[num], subscription_list) # get uuid self.uuid[line.idx] = subscription_list[connect_num].id canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def checkOtherConnect(self): """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない """ ret = False canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return ret # get subscription-list subscription_list = [] try: subscription_list = ref._get_subscriptions() if subscription_list == None: print "get subscriptions failure: return value is None." return ret except: except_mess('get subscriptions failure:') return ret for line_idx in self.line_idx: line = canvas.line[line_idx] (ret2,subscription_list) = self.checkConnect2(line,subscription_list) if len(subscription_list) > 0: ret = True return ret def checkConnect(self, inp_obj, subscr_list): """接続チェック 指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1 """ ret = False ret_num = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): print "checkConnect: _is_equivalent is OK!!!" ret = True break ret_num = ret_num + 1 if ret == False: ret_num = -1 return ret_num def checkConnect2(self, line, subscr_list): """接続チェック チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト """ inp_obj = line.g_inp.inport['ref'] cnt = 0 ret = 0 for subscr in subscr_list: ref_inp = subscr.in_port if ref_inp._is_equivalent(inp_obj): # print "checkConnect2: _is_equivalent is OK!!!" ret = 1 break cnt = cnt + 1 if ret == 1: del subscr_list[cnt] return (ret, subscr_list) def disconnectToObjref(self,subscr_list): """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void """ #assembly: for debug: # print "disconnectToObjref : it's dummy for debug!" # return # for debug #for debug: canvas = self.body.GetCanvas() ref = self.outport['ref'] ref = ref._narrow(RTM.OutPort) for subscr in subscr_list: inp = subscr.in_port # print "test:",dir(inp) #get uuid connect_num = self.checkConnect(inp, subscr_list) uuid = subscr_list[connect_num].id if ref != None and canvas.viewMode == False: try : print "unsubscribe2 :",uuid rslt = ref.unsubscribe(uuid) if rslt != 0: print 'unsubscribe2 failure: rslt=',rslt except : err_mess = 'unsubscribe failure:' except_mess(err_mess) def reConnectLine(self): """再接続処理 [引数] なし [戻り値] void """ #assembly dummy # return #assembly dummy canvas = self.body.GetCanvas() ref = self.outport['ref'] try: ref = ref._narrow(RTM.OutPort) except: err_mess = 'outport obj-ref failure:' except_mess(err_mess) return # get subscription-list subscription_list = [] subscr_list_tmp = [] try: subscription_list = ref._get_subscriptions() subscr_list_tmp = copy.deepcopy(subscription_list) if subscription_list == None: print "get subscriptions failure: return value is None." return except: except_mess('get subscriptions failure:') return for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) else: # get uuid inp_ref = canvas.line[line_idx].g_inp.inport['ref'] connect_num = self.checkConnect(inp_ref, subscription_list) self.uuid[line_idx] = subscription_list[connect_num].id # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ? for line_idx in self.line_idx: line = canvas.line[line_idx] (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp) if ret == 0: self.connect2(line_idx,line.subscription_type) if len(subscr_list_tmp) > 0: # print "reconnect " self.disconnectToObjref(subscr_list_tmp) def dcoords(self): """アウトポート図形の座標設定 現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void """ if self.position == 'Left': self.points = [ (self.x, self.y+self.y_size/2), ( self.x+self.x_size/2, self.y), ( self.x+self.x_size, self.y), ( self.x+self.x_size, self.y+self.y_size), ( self.x+self.x_size/2, self.y+self.y_size), ( self.x, self.y+self.y_size/2) ] elif self.position == 'Right' : self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y ), ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2) ] elif self.position == 'Top' : self.points = [ ( self.x+self.x_size/2, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size, self.y+self.y_size ), ( self.x, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y ) ] elif self.position == 'Bottom' : self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ), ( self.x, self.y+self.y_size/2 ), ( self.x, self.y ), ( self.x+self.x_size, self.y ), ( self.x+self.x_size, self.y+self.y_size/2 ), ( self.x+self.x_size/2, self.y+self.y_size ) ] #---------------------------------------------------------------------- class GRtc(ogl.Shape): """コンポーネント図形の本体を作成するクラス""" def __init__(self, parent, fullpath, pos_x, pos_y): """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void """ ogl.Shape.__init__(self) self.parent = parent self.fullpath = fullpath self.ns_dict = self.parent.frame.myDict # print "check cur_dict:",cur_dict[0] self.name = self.ns_dict.GetCompName(fullpath) self.in_list = self.ns_dict.GetInPortToRef(fullpath) self.out_list = self.ns_dict.GetOutPortToRef(fullpath) self.x = pos_x self.y = pos_y self.color = INACTIVE_COLOR self.state = 'inactive' self.x_size = BOX_WIDTH self.y_size = BOX_WIDTH self.ratioW = 1.0 self.ratioH = 1.0 self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.xy_swap = 0 self.mark = None self.tag = 'body' self.text = None self.lastBBoxWidth = 0 self.lastBBoxHeight = 0 self.text_x = 0 self.text_y = 0 self.px_size = POLYGON_SIZE self.py_size = POLYGON_SIZE tmp = max(len(self.in_list), len(self.out_list)) self.minWidth = self.x_size self.minHeight = 2 * POLYGON_SIZE * tmp # self.blink = blinkTimer() self.createWidget(0) def remakeLines(self): # assembly dummy process # return # assembly dummy process for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].remakeLines() def checkOtherConnect(self): """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし """ ret = False for outp in self.out_list : if outp['name'] in self.out_dict.keys(): ret = self.out_dict[outp['name']].checkOtherConnect() if ret == True: break return ret def reConnectLine(self): """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].reConnectLine() def portToFlash(self): """ポート(Shape)のFlash(再描画?)を呼び出す コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void """ for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].body.Flash() for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].body.Flash() def checkCompState(self): """コンポーネントのステータスをチェックする [引数] なし [戻り値] void """ state = 'inactive' canvas = self.body.GetCanvas() tmp = self.ns_dict.GetCompState(self.fullpath) if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: state = 'active' elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING: state = 'inactive' elif tmp >= RTM.RTComponent.RTC_ABORTING : state = 'error' else: # unknown , born?, initializing state = 'unloaded' if canvas.viewMode == True and state != 'unloaded': state = 'virtual' self.state = state def ref_start(self): """コンポーネントにstart命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_start() except : err_mess = 'rtc_start error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'active') self.ns_dict.setCompBodyColor(self.fullpath, 'active') self.state = 'active' self.portToFlash() def ref_stop(self): """コンポーネントにstop命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_stop() except : err_mess = 'rtc_stop error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'inactive') self.state = 'inactive' self.portToFlash() def ref_reset(self): """コンポーネントにreset命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_reset() except : err_mess = 'rtc_reset error:%s\n'%self.fullpath except_mess(err_mess) # self.checkCompState() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() def ref_kill(self): """コンポーネントにkill命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_kill() except : err_mess = 'rtc_kill error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'inactive') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'inactive' self.portToFlash() def ref_exit(self): """コンポーネントにexit命令を発行 [引数] なし [戻り値] void """ try: ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) ref.rtc_exit() except : err_mess = 'rtc_exit error:%s\n'%self.fullpath except_mess(err_mess) self.checkCompState() # setBodyColor(self.baseBox, self.state) # setBodyColor(self.baseBox, 'unloaded') self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded') self.state = 'unloaded' self.portToFlash() def changeBodyColor(self,state): """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する 'active','inactive','error',unloaded','virtual' [戻り値] void """ if state == 'unloaded': self.state = 'unloaded' self.color = UNLOADED_COLOR elif state == 'active' : self.state = 'active' self.color = ACTIVE_COLOR elif state == 'inactive': self.state = 'inactive' self.color = INACTIVE_COLOR elif state == 'error' : self.state = 'error' self.color = ERROR_COLOR # canvas = self.body.GetCanvas() canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if canvas.viewMode == True and self.state != 'unloaded': self.state = 'virtual' self.color = VIRTUAL_COLOR setBodyColor(self.baseBox, self.state) self.portToFlash() canvas.Redraw(dc) def refresh_outp(self): """アウトポートのrefresh [引数] なし [戻り値] void """ for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].refresh() def refresh(self): """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void """ old_state = self.state canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) try : ref = self.ns_dict.GetObjRefToFullpath(self.fullpath) ref = ref._narrow(RTM.RTCBase) tmp_port = ref._get_rtc_state() tmp_port = tmp_port._narrow(RTM.OutPort) tmp = tmp_port.get() tmp = tmp.value() tmp = tmp.data print "refresh state:",tmp except : except_mess("except error:") ref = None if not ref: self.state = 'unloaded' self.color = UNLOADED_COLOR else: self.name = self.ns_dict.GetCompName(self.fullpath) self.in_list = self.ns_dict.GetInPortToRef(self.fullpath) self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath) for outp in self.out_list : if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].outport = outp for inp in self.in_list : if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].inport = inp if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE: self.state = 'active' self.color = ACTIVE_COLOR elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY: self.state = 'inactive' self.color = INACTIVE_COLOR elif tmp >= RTM.RTComponent.RTC_ABORTING : self.state = 'error' self.color = ERROR_COLOR else : self.state = 'unloaded' self.color = UNLOADED_COLOR # if old_state == 'unloaded' and self.state != 'unloaded': if len(self.out_dict.keys()) != len(self.out_list): self.removeWidget(dc,0) old_rot = self.rotTogle old_rev = self.revTogle old_lastrot = self.lastRot self.rotTogle = 0 self.revTogle = 1 self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom) self.x_size = BOX_WIDTH self.x = self.x - self.x_size/2 self.y = self.y - self.y_size/2 self.ratioW = 1.0 self.ratioH = 1.0 self.createWidget(0) if old_lastrot == 'LR': if old_rev == 0: self.reversesBody() else: if old_rot == 1: self.rotatesBody() else: self.rotatesBody() self.rotatesBody() # setBodyColor(self.baseBox, self.state) self.ns_dict.setCompBodyColor(self.fullpath, self.state) self.portToFlash() canvas.Redraw(dc) def removeWidget(self, dc, rot=0): """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void """ # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1395  for line_index in self.line_idx:
1396  canvas.line[line_index].setEndPoint(dc, self.body,movex, movey)
1397 
1398  def connect2(self, line_idx, subscription_type):
1399  """コネクト処理(subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1400 
1401  [引数]
1402  line_idx -- インポートに接続する線のインデックス
1403  subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1404 
1405  [戻り値]
1406  成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1407  """
1408  canvas = self.body.GetCanvas()
1409 
1410  # get outport-object-ref
1411  ref = self.outport['ref']
1412  if ref == None :
1413  return 0
1414  try:
1415  ref = ref._narrow(RTM.OutPort)
1416  except:
1417  except_mess('outport obj-ref failure:')
1418  return 0
1419 
1420  # get inport-object-ref
1421  inp_ref = canvas.line[line_idx].g_inp.inport['ref']
1422  try:
1423  inp_ref = inp_ref._narrow(RTM.InPort)
1424  except:
1425  except_mess('inport obj-ref failure:')
1426  return 0
1427 
1428  # get subscription-list
1429  subscription_list = []
1430  try:
1431  subscription_list = ref._get_subscriptions()
1432  if subscription_list == None:
1433  print "get subscriptions failure: return value is None."
1434  return 0
1435  except:
1436  except_mess('get subscriptions failure:')
1437  return 0
1438 
1439  connect_num = self.checkConnect(inp_ref, subscription_list)
1440 
1441  if canvas.viewMode == False:
1442  if connect_num == -1:
1443  try:
1444  canvas.line[line_idx].subscription_type = subscription_type
1445  canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[])
1446  canvas.line[line_idx].profile.out_port = ref
1447  canvas.line[line_idx].profile.in_port = inp_ref
1448  rslt, canvas.line[line_idx].profile = ref.subscribe(canvas.line[line_idx].profile)
1449  self.uuid[line_idx] = canvas.line[line_idx].profile.id
1450 
1451  if rslt != 0:
1452  print "subscribe failure!"
1453  except:
1454  except_mess('subscribe failure:')
1455  print "connect2 subscribe :",self.uuid[line_idx]
1456  else:
1457  rslt = 0
1458  # get uuid
1459  self.uuid[line_idx] = subscription_list[connect_num].id
1460  return 1
1461 
1462  def connect(self, line_idx, subscription_type):
1463  """コネクト処理(線のインデックスを格納、subscribeを発行) [引数] line_idx -- インポートに接続する線のインデックス subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1464 
1465  [引数]
1466  line_idx -- インポートに接続する線のインデックス
1467  subscription_type -- サブスクリプション・タイプを指定(現在未使用) [戻り値] 成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1468 
1469  [戻り値]
1470  成否フラグ -- 0:エラー(オブジェクトリファレンス無し,subscribe失敗) / 1:成功
1471  """
1472  canvas = self.body.GetCanvas()
1473  n = 0
1474  for n in range(2): # for retry
1475  try:
1476  ref = self.outport['ref']
1477  if ref == None :
1478  return 0
1479  ref = ref._narrow(RTM.OutPort)
1480  break
1481  except:
1482  except_mess('outport obj-ref failure:')
1483  self.parent.refresh()
1484  if n == 2:
1485  print "error retry"
1486  return 0
1487 
1488 
1489  inp_ref = canvas.line[line_idx].g_inp.inport['ref']
1490  try:
1491  inp_ref = inp_ref._narrow(RTM.InPort)
1492  except:
1493  except_mess('inport obj-ref failure:')
1494  return 0
1495 
1496  # get subscription-list
1497  subscription_list = []
1498  try:
1499  subscription_list = ref._get_subscriptions()
1500  if subscription_list == None:
1501  print "get subscriptions failure: return value is None."
1502  return 0
1503  except:
1504  except_mess('get subscriptions failure:')
1505  return 0
1506 
1507  canvas.line[line_idx].subscription_type = subscription_type
1508  canvas.line[line_idx].profile = RTM.SubscriptionProfile(subscription_type,"",None,None,False,[])
1509 
1510 
1511  connect_num = self.checkConnect(inp_ref, subscription_list)
1512 #assembly dummy
1513 # connect_num = -1
1514 #assembly dummy
1515 
1516  rslt = 0
1517  if canvas.viewMode == False:
1518  if connect_num == -1:
1519  try:
1520  canvas.line[line_idx].profile.out_port = ref
1521  canvas.line[line_idx].profile.in_port = inp_ref
1522  (rslt, canvas.line[line_idx].profile) = ref.subscribe(canvas.line[line_idx].profile)
1523  if rslt != 0:
1524  print "subscribe failuer! :rslt=",rslt
1525  self.uuid[line_idx] = canvas.line[line_idx].profile.id
1526  print "connect subscribe :",self.uuid[line_idx]
1527  except:
1528  err_mess = 'subscribe failure! :'
1529  except_mess(err_mess)
1530  else:
1531  rslt = 0
1532  # get uuid
1533  self.uuid[line_idx] = subscription_list[connect_num].id
1534 
1535  if rslt :
1536  print "subsrcibe-rslt:",rslt
1537  return 0
1538  else :
1539  self.line_idx.append(line_idx)
1540  self.isInactive = self.isInactive + 1
1541  return 1
1542 
1543  def disconnect(self, line_idx):
1544  """ディスコネクト処理(線のインデックスを削除、unsubscribeを発行) [引数] line_idx -- アウトポートに接続している線のインデックス [戻り値] 成否フラグ -- 0:エラー / 1:成功
1545 
1546  [引数]
1547  line_idx -- アウトポートに接続している線のインデックス
1548 
1549  [戻り値]
1550  成否フラグ -- 0:エラー / 1:成功
1551  """
1552  if self.isInactive == 1 :
1553  setBodyColor(self.body, 'inactive')
1554 
1555  canvas = self.body.GetCanvas()
1556 
1557  n = 0
1558  for n in range(2): # for retry
1559  ref = self.outport['ref']
1560  try:
1561  ref = ref._narrow(RTM.OutPort)
1562 
1563  inp_obj = canvas.line[line_idx].g_inp.inport['ref']
1564 
1565  # get subscription-list
1566  subscription_list = []
1567  subscription_list = ref._get_subscriptions()
1568  if subscription_list == None:
1569  print "get subscriptions failure: return value is None."
1570  return 0
1571 
1572  connect_num = self.checkConnect(inp_obj, subscription_list)
1573 #assembly dummy
1574 # connect_num = 0
1575 #assembly dummy
1576  break
1577  except:
1578  err_mess = 'outport disconnect failure:'
1579  except_mess(err_mess)
1580  connect_num = -1
1581  self.parent.refresh()
1582 
1583  if n == 2: # bad connect
1584  return 0
1585 
1586  if ref != None and canvas.viewMode == False and connect_num != -1:
1587  try :
1588  print "unsubscribe :",self.uuid[line_idx]
1589  rslt = ref.unsubscribe(self.uuid[line_idx])
1590  if rslt != 0:
1591  print 'unsubscribe failure: rslt=',rslt
1592  except :
1593  err_mess = 'unsubscribe failure:'
1594  except_mess(err_mess)
1595 
1596  self.isInactive = self.isInactive - 1
1597 
1598  if line_idx in self.line_idx:
1599  self.delLineIdx(line_idx)
1600  return 1
1601  else :
1602  return 0
1603 
1604  def remakeLines(self):
1605  """再接続処理 オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く [引数] なし [戻り値] void
1606  オブジェクト上だけに存在する接続情報(subscribe)を検索し線を引く
1607 
1608  [引数]
1609  なし
1610 
1611  [戻り値]
1612  void
1613  """
1614 # assembly dummy process
1615 # return
1616 # assembly dummy process
1617 
1618  canvas = self.body.GetCanvas()
1619  dc = wx.ClientDC(canvas)
1620  canvas.PrepareDC(dc)
1621 
1622  ref = self.outport['ref']
1623  try:
1624  ref = ref._narrow(RTM.OutPort)
1625  except:
1626  err_mess = 'outport obj-ref failure:'
1627  except_mess(err_mess)
1628  return
1629 
1630  # get subscription-list
1631  subscription_list = []
1632  subscr_list_tmp = []
1633  try:
1634  subscription_list = ref._get_subscriptions()
1635  subscr_list_tmp = copy.deepcopy(subscription_list)
1636  if subscription_list == None:
1637  print "get subscriptions failure: return value is None."
1638  return
1639  except:
1640  except_mess('get subscriptions failure:')
1641  return
1642 
1643  for line_idx in self.line_idx:
1644  line = canvas.line[line_idx]
1645  (ret2,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp)
1646 
1647  rtc_list = self.parent.parent.rtc_list
1648  rtc_dict = self.parent.parent.rtc_dict
1649  ret_name = []
1650  ret_obj = []
1651  ret_ref = []
1652 
1653  for subscr in subscr_list_tmp:
1654  inp_ref = subscr.in_port
1655  for fullname in rtc_list:
1656  in_list = rtc_dict[fullname].in_list
1657  in_dict = rtc_dict[fullname].in_dict
1658 
1659  for inp in in_list:
1660  if inp['name'] in in_dict.keys():
1661  ref = in_dict[inp['name']].inport['ref']
1662  if inp_ref._is_equivalent(ref):
1663  print "_is_equivalent is OK!!!"
1664  ret_name.append( inp['name'] )
1665  ret_obj.append( in_dict[inp['name']] )
1666  ret_ref.append(inp_ref)
1667 
1668  for num in range(len(ret_name)):
1669  canvas.lineFrom = self.body
1670  canvas.lineTo = ret_obj[num].body
1671  line = GRtcLine(canvas,self)
1672  line.setLine2port(canvas, dc)
1673 
1674  self.line_idx.append(line.idx)
1675  self.isInactive = self.isInactive + 1
1676  connect_num = self.checkConnect(ret_ref[num], subscription_list)
1677  # get uuid
1678  self.uuid[line.idx] = subscription_list[connect_num].id
1679 
1680  canvas.lineFrom = None
1681  canvas.lineTo = None
1682  canvas.Redraw(dc)
1683 
1684 
1686  """古い接続情報があるかチェックする 画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない
1687  画面上の線以外の接続がオブジェクト上にあるかチェックする [引数] なし [戻り値] ret --- True:ある / False:ない
1688 
1689  [引数]
1690  なし
1691 
1692  [戻り値]
1693  ret --- True:ある / False:ない
1694  """
1695  ret = False
1696  canvas = self.body.GetCanvas()
1697  ref = self.outport['ref']
1698  try:
1699  ref = ref._narrow(RTM.OutPort)
1700  except:
1701  err_mess = 'outport obj-ref failure:'
1702  except_mess(err_mess)
1703  return ret
1704 
1705  # get subscription-list
1706  subscription_list = []
1707  try:
1708  subscription_list = ref._get_subscriptions()
1709  if subscription_list == None:
1710  print "get subscriptions failure: return value is None."
1711  return ret
1712  except:
1713  except_mess('get subscriptions failure:')
1714  return ret
1715 
1716  for line_idx in self.line_idx:
1717  line = canvas.line[line_idx]
1718  (ret2,subscription_list) = self.checkConnect2(line,subscription_list)
1719  if len(subscription_list) > 0:
1720  ret = True
1721  return ret
1722 
1723  def checkConnect(self, inp_obj, subscr_list):
1724  """接続チェック
1725  指定した接続先(inport)のリファレンスがあるかチェックする [引数] inp_obj --- インポートのオブジェクト・リファレンス ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1
1726 
1727  [引数]
1728  inp_obj --- インポートのオブジェクト・リファレンス
1729  ref_list --- インポートのリファレンス・リスト [戻り値] ret_num --- subScription_list の添え字/ない場合は-1
1730 
1731  [戻り値]
1732  ret_num --- subScription_list の添え字/ない場合は-1
1733  """
1734  ret = False
1735  ret_num = 0
1736  for subscr in subscr_list:
1737  ref_inp = subscr.in_port
1738  if ref_inp._is_equivalent(inp_obj):
1739  print "checkConnect: _is_equivalent is OK!!!"
1740  ret = True
1741  break
1742  ret_num = ret_num + 1
1743  if ret == False:
1744  ret_num = -1
1745  return ret_num
1746 
1747  def checkConnect2(self, line, subscr_list):
1748  """接続チェック
1749  チェック対象の接続があった場合は、リスト上から削除して返却する 古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト
1750  古い情報があるか調べる為に呼ばれる [引数] line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト
1751 
1752  [引数]
1753  line --- 線のオブジェクト ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト
1754  ref_list --- 接続先(inport)のオブジェクトリファレンス・リスト [戻り値] (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト
1755 
1756  [戻り値]
1757  (ret, ref_list) --- ret 0:ない / 1:ある , ref_list: 残りのリファレンスリスト
1758  """
1759 
1760  inp_obj = line.g_inp.inport['ref']
1761 
1762  cnt = 0
1763  ret = 0
1764  for subscr in subscr_list:
1765  ref_inp = subscr.in_port
1766  if ref_inp._is_equivalent(inp_obj):
1767 # print "checkConnect2: _is_equivalent is OK!!!"
1768  ret = 1
1769  break
1770  cnt = cnt + 1
1771  if ret == 1:
1772  del subscr_list[cnt]
1773 
1774  return (ret, subscr_list)
1775 
1776  def disconnectToObjref(self,subscr_list):
1777  """コンポーネント上の接続情報(subscribe)を削除する [引数] inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void
1778 
1779  [引数]
1780  inp_list --- 接続先(subscriptionProfile)のリスト [戻り値] void
1781 
1782  [戻り値]
1783  void
1784  """
1785 #assembly: for debug:
1786 # print "disconnectToObjref : it's dummy for debug!"
1787 # return # for debug
1788 #for debug:
1789 
1790  canvas = self.body.GetCanvas()
1791  ref = self.outport['ref']
1792  ref = ref._narrow(RTM.OutPort)
1793 
1794  for subscr in subscr_list:
1795  inp = subscr.in_port
1796 # print "test:",dir(inp)
1797  #get uuid
1798  connect_num = self.checkConnect(inp, subscr_list)
1799  uuid = subscr_list[connect_num].id
1800 
1801  if ref != None and canvas.viewMode == False:
1802  try :
1803  print "unsubscribe2 :",uuid
1804  rslt = ref.unsubscribe(uuid)
1805  if rslt != 0:
1806  print 'unsubscribe2 failure: rslt=',rslt
1807  except :
1808  err_mess = 'unsubscribe failure:'
1809  except_mess(err_mess)
1810 
1811 
1812  def reConnectLine(self):
1813  """再接続処理 [引数] なし [戻り値] void
1814 
1815  [引数]
1816  なし
1817 
1818  [戻り値]
1819  void
1820  """
1821 #assembly dummy
1822 # return
1823 #assembly dummy
1824 
1825  canvas = self.body.GetCanvas()
1826  ref = self.outport['ref']
1827  try:
1828  ref = ref._narrow(RTM.OutPort)
1829  except:
1830  err_mess = 'outport obj-ref failure:'
1831  except_mess(err_mess)
1832  return
1833 
1834  # get subscription-list
1835  subscription_list = []
1836  subscr_list_tmp = []
1837  try:
1838  subscription_list = ref._get_subscriptions()
1839  subscr_list_tmp = copy.deepcopy(subscription_list)
1840  if subscription_list == None:
1841  print "get subscriptions failure: return value is None."
1842  return
1843  except:
1844  except_mess('get subscriptions failure:')
1845  return
1846 
1847  for line_idx in self.line_idx:
1848  line = canvas.line[line_idx]
1849  (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp)
1850  if ret == 0:
1851  self.connect2(line_idx,line.subscription_type)
1852  else:
1853  # get uuid
1854  inp_ref = canvas.line[line_idx].g_inp.inport['ref']
1855  connect_num = self.checkConnect(inp_ref, subscription_list)
1856  self.uuid[line_idx] = subscription_list[connect_num].id
1857 
1858  # 再接続処理から漏れたsubscribeの検出:大抵はnaming-service上のゴミ?
1859  for line_idx in self.line_idx:
1860  line = canvas.line[line_idx]
1861  (ret,subscr_list_tmp) = self.checkConnect2(line,subscr_list_tmp)
1862  if ret == 0:
1863  self.connect2(line_idx,line.subscription_type)
1864  if len(subscr_list_tmp) > 0:
1865 # print "reconnect "
1866  self.disconnectToObjref(subscr_list_tmp)
1867 
1868  def dcoords(self):
1869  """アウトポート図形の座標設定
1870  現在のpositionを見て図形の向きを決定する 各頂点は(x,y)のタプル形式 [引数] なし [戻り値] void
1871  各頂点は(x,y)のタプル形式
1872 
1873  [引数]
1874  なし
1875 
1876  [戻り値]
1877  void
1878  """
1879  if self.position == 'Left':
1880  self.points = [ (self.x, self.y+self.y_size/2),
1881  ( self.x+self.x_size/2, self.y),
1882  ( self.x+self.x_size, self.y),
1883  ( self.x+self.x_size, self.y+self.y_size),
1884  ( self.x+self.x_size/2, self.y+self.y_size),
1885  ( self.x, self.y+self.y_size/2) ]
1886  elif self.position == 'Right' :
1887  self.points = [ ( self.x+self.x_size, self.y+self.y_size/2 ),
1888  ( self.x+self.x_size/2, self.y+self.y_size ),
1889  ( self.x, self.y+self.y_size ),
1890  ( self.x, self.y ),
1891  ( self.x+self.x_size/2, self.y ),
1892  ( self.x+self.x_size, self.y+self.y_size/2) ]
1893  elif self.position == 'Top' :
1894  self.points = [ ( self.x+self.x_size/2, self.y ),
1895  ( self.x+self.x_size, self.y+self.y_size/2 ),
1896  ( self.x+self.x_size, self.y+self.y_size ),
1897  ( self.x, self.y+self.y_size ),
1898  ( self.x, self.y+self.y_size/2 ),
1899  ( self.x+self.x_size/2, self.y ) ]
1900  elif self.position == 'Bottom' :
1901  self.points = [ ( self.x+self.x_size/2, self.y+self.y_size ),
1902  ( self.x, self.y+self.y_size/2 ),
1903  ( self.x, self.y ),
1904  ( self.x+self.x_size, self.y ),
1905  ( self.x+self.x_size, self.y+self.y_size/2 ),
1906  ( self.x+self.x_size/2, self.y+self.y_size ) ]
1907 
1908 #----------------------------------------------------------------------
1909 class GRtc(ogl.Shape):
1910  """コンポーネント図形の本体を作成するクラス"""
1911  def __init__(self, parent, fullpath, pos_x, pos_y):
1912  """クラスの初期化(コンポーネント図形の作成) [引数] parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void
1913 
1914  [引数]
1915  parent -- 親クラスを指定する fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void
1916  fullpath -- コンポーネントのロングネーム pos_x -- コンポーネント図形のx座標 pos_y -- コンポーネント図形のy座標 [戻り値] void
1917  pos_x -- コンポーネント図形のx座標
1918  pos_y -- コンポーネント図形のy座標
1919 
1920  [戻り値]
1921  void
1922  """
1923  ogl.Shape.__init__(self)
1924  self.parent = parent
1925  self.fullpath = fullpath
1926  self.ns_dict = self.parent.frame.myDict
1927 # print "check cur_dict:",cur_dict[0]
1928  self.name = self.ns_dict.GetCompName(fullpath)
1929  self.in_list = self.ns_dict.GetInPortToRef(fullpath)
1930  self.out_list = self.ns_dict.GetOutPortToRef(fullpath)
1931 
1932  self.x = pos_x
1933  self.y = pos_y
1934  self.color = INACTIVE_COLOR
1935  self.state = 'inactive'
1936  self.x_size = BOX_WIDTH
1937  self.y_size = BOX_WIDTH
1938  self.ratioW = 1.0
1939  self.ratioH = 1.0
1940  self.rotTogle = 0
1941  self.revTogle = 1
1942  self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom)
1943  self.xy_swap = 0
1944  self.mark = None
1945  self.tag = 'body'
1946  self.text = None
1947  self.lastBBoxWidth = 0
1948  self.lastBBoxHeight = 0
1949  self.text_x = 0
1950  self.text_y = 0
1951  self.px_size = POLYGON_SIZE
1952  self.py_size = POLYGON_SIZE
1953  tmp = max(len(self.in_list), len(self.out_list))
1954  self.minWidth = self.x_size
1955  self.minHeight = 2 * POLYGON_SIZE * tmp
1956 # self.blink = blinkTimer()
1957  self.createWidget(0)
1958 
1959  def remakeLines(self):
1960 # assembly dummy process
1961 # return
1962 # assembly dummy process
1963  for outp in self.out_list :
1964  if outp['name'] in self.out_dict.keys():
1965  self.out_dict[outp['name']].remakeLines()
1966 
1968  """古い接続情報(画面上に表示されていないsubscribe情報)をチェックする [引数] なし [戻り値] ret --- True:古い情報あり / False:古い情報なし
1969 
1970  [引数]
1971  なし
1972 
1973  [戻り値]
1974  ret --- True:古い情報あり / False:古い情報なし
1975  """
1976  ret = False
1977  for outp in self.out_list :
1978  if outp['name'] in self.out_dict.keys():
1979  ret = self.out_dict[outp['name']].checkOtherConnect()
1980  if ret == True:
1981  break
1982  return ret
1983 
1984  def reConnectLine(self):
1985  """再接続処理 コンポーネントのアウトポートの再接続処理を呼び出す [引数] なし [戻り値] void
1986  コンポーネントのアウトポートの再接続処理を呼び出す
1987 
1988  [引数]
1989  なし
1990 
1991  [戻り値]
1992  void
1993  """
1994  for outp in self.out_list :
1995  if outp['name'] in self.out_dict.keys():
1996  self.out_dict[outp['name']].reConnectLine()
1997 
1998  def portToFlash(self):
1999  """ポート(Shape)のFlash(再描画?)を呼び出す
2000  コンポーネントの絵の下にポートの絵がもぐり込むケースの時に呼び出している。(回避策) 他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void
2001  他に良い処理があれば、随時そちらに変更する [引数] なし [戻り値] void
2002 
2003  [引数]
2004  なし
2005 
2006  [戻り値]
2007  void
2008  """
2009  for inp in self.in_list :
2010  if inp['name'] in self.in_dict.keys():
2011  self.in_dict[inp['name']].body.Flash()
2012  for outp in self.out_list :
2013  if outp['name'] in self.out_dict.keys():
2014  self.out_dict[outp['name']].body.Flash()
2015 
2016  def checkCompState(self):
2017  """コンポーネントのステータスをチェックする [引数] なし [戻り値] void
2018 
2019  [引数]
2020  なし
2021 
2022  [戻り値]
2023  void
2024  """
2025  state = 'inactive'
2026 
2027  canvas = self.body.GetCanvas()
2028  tmp = self.ns_dict.GetCompState(self.fullpath)
2029  if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE:
2030  state = 'active'
2031  elif tmp == RTM.RTComponent.RTC_READY or tmp == RTM.RTComponent.RTC_STOPPING:
2032  state = 'inactive'
2033  elif tmp >= RTM.RTComponent.RTC_ABORTING :
2034  state = 'error'
2035  else: # unknown , born?, initializing
2036  state = 'unloaded'
2037  if canvas.viewMode == True and state != 'unloaded':
2038  state = 'virtual'
2039 
2040  self.state = state
2041 
2042  def ref_start(self):
2043  """コンポーネントにstart命令を発行 [引数] なし [戻り値] void
2044 
2045  [引数]
2046  なし
2047 
2048  [戻り値]
2049  void
2050  """
2051  try:
2052  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2053  ref = ref._narrow(RTM.RTCBase)
2054  ref.rtc_start()
2055  except :
2056  err_mess = 'rtc_start error:%s\n'%self.fullpath
2057  except_mess(err_mess)
2058  self.checkCompState()
2059 # setBodyColor(self.baseBox, self.state)
2060 # setBodyColor(self.baseBox, 'active')
2061  self.ns_dict.setCompBodyColor(self.fullpath, 'active')
2062  self.state = 'active'
2063  self.portToFlash()
2064 
2065  def ref_stop(self):
2066  """コンポーネントにstop命令を発行 [引数] なし [戻り値] void
2067 
2068  [引数]
2069  なし
2070 
2071  [戻り値]
2072  void
2073  """
2074  try:
2075  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2076  ref = ref._narrow(RTM.RTCBase)
2077  ref.rtc_stop()
2078  except :
2079  err_mess = 'rtc_stop error:%s\n'%self.fullpath
2080  except_mess(err_mess)
2081  self.checkCompState()
2082 # setBodyColor(self.baseBox, self.state)
2083 # setBodyColor(self.baseBox, 'inactive')
2084  self.ns_dict.setCompBodyColor(self.fullpath, 'inactive')
2085  self.state = 'inactive'
2086  self.portToFlash()
2087 
2088  def ref_reset(self):
2089  """コンポーネントにreset命令を発行 [引数] なし [戻り値] void
2090 
2091  [引数]
2092  なし
2093 
2094  [戻り値]
2095  void
2096  """
2097  try:
2098  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2099  ref = ref._narrow(RTM.RTCBase)
2100  ref.rtc_reset()
2101  except :
2102  err_mess = 'rtc_reset error:%s\n'%self.fullpath
2103  except_mess(err_mess)
2104 # self.checkCompState()
2105 # setBodyColor(self.baseBox, self.state)
2106  self.ns_dict.setCompBodyColor(self.fullpath, self.state)
2107  self.portToFlash()
2108 
2109  def ref_kill(self):
2110  """コンポーネントにkill命令を発行 [引数] なし [戻り値] void
2111 
2112  [引数]
2113  なし
2114 
2115  [戻り値]
2116  void
2117  """
2118  try:
2119  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2120  ref = ref._narrow(RTM.RTCBase)
2121  ref.rtc_kill()
2122  except :
2123  err_mess = 'rtc_kill error:%s\n'%self.fullpath
2124  except_mess(err_mess)
2125  self.checkCompState()
2126 # setBodyColor(self.baseBox, self.state)
2127 # setBodyColor(self.baseBox, 'inactive')
2128  self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded')
2129  self.state = 'inactive'
2130  self.portToFlash()
2131 
2132  def ref_exit(self):
2133  """コンポーネントにexit命令を発行 [引数] なし [戻り値] void
2134 
2135  [引数]
2136  なし
2137 
2138  [戻り値]
2139  void
2140  """
2141  try:
2142  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2143  ref = ref._narrow(RTM.RTCBase)
2144  ref.rtc_exit()
2145  except :
2146  err_mess = 'rtc_exit error:%s\n'%self.fullpath
2147  except_mess(err_mess)
2148  self.checkCompState()
2149 # setBodyColor(self.baseBox, self.state)
2150 # setBodyColor(self.baseBox, 'unloaded')
2151  self.ns_dict.setCompBodyColor(self.fullpath, 'unloaded')
2152  self.state = 'unloaded'
2153  self.portToFlash()
2154 
2155  def changeBodyColor(self,state):
2156  """ステータスによりコンポーネントの色を設定する [引数] state --- コンポーネントの状態を指定する
2157 
2158  [引数]
2159  state --- コンポーネントの状態を指定する
2160  'active','inactive','error',unloaded','virtual'
2161 
2162  [戻り値]
2163  void
2164  """
2165  if state == 'unloaded':
2166  self.state = 'unloaded'
2167  self.color = UNLOADED_COLOR
2168  elif state == 'active' :
2169  self.state = 'active'
2170  self.color = ACTIVE_COLOR
2171  elif state == 'inactive':
2172  self.state = 'inactive'
2173  self.color = INACTIVE_COLOR
2174  elif state == 'error' :
2175  self.state = 'error'
2176  self.color = ERROR_COLOR
2177 # canvas = self.body.GetCanvas()
2178  canvas = self.parent.diagram.GetCanvas()
2179  dc = wx.ClientDC(canvas)
2180  canvas.PrepareDC(dc)
2181  if canvas.viewMode == True and self.state != 'unloaded':
2182  self.state = 'virtual'
2183  self.color = VIRTUAL_COLOR
2184  setBodyColor(self.baseBox, self.state)
2185  self.portToFlash()
2186  canvas.Redraw(dc)
2187 
2188  def refresh_outp(self):
2189  """アウトポートのrefresh
2190 
2191  [引数]
2192  なし
2193 
2194  [戻り値]
2195  void
2196  """
2197  for outp in self.out_list :
2198  if outp['name'] in self.out_dict.keys():
2199  self.out_dict[outp['name']].refresh()
2200 
2201  def refresh(self):
2202  """リフレッシュ処理 コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void
2203  コンポーネントのstateフラグで現在の状態(active,error,inactive等)を設定 [引数] なし [戻り値] void
2204 
2205  [引数]
2206  なし
2207 
2208  [戻り値]
2209  void
2210  """
2211  old_state = self.state
2212  canvas = self.body.GetCanvas()
2213  dc = wx.ClientDC(canvas)
2214  canvas.PrepareDC(dc)
2215  try :
2216  ref = self.ns_dict.GetObjRefToFullpath(self.fullpath)
2217  ref = ref._narrow(RTM.RTCBase)
2218  tmp_port = ref._get_rtc_state()
2219  tmp_port = tmp_port._narrow(RTM.OutPort)
2220  tmp = tmp_port.get()
2221  tmp = tmp.value()
2222  tmp = tmp.data
2223  print "refresh state:",tmp
2224  except :
2225  except_mess("except error:")
2226  ref = None
2227 
2228  if not ref:
2229  self.state = 'unloaded'
2230  self.color = UNLOADED_COLOR
2231  else:
2232  self.name = self.ns_dict.GetCompName(self.fullpath)
2233  self.in_list = self.ns_dict.GetInPortToRef(self.fullpath)
2234  self.out_list = self.ns_dict.GetOutPortToRef(self.fullpath)
2235 
2236  for outp in self.out_list :
2237  if outp['name'] in self.out_dict.keys():
2238  self.out_dict[outp['name']].outport = outp
2239  for inp in self.in_list :
2240  if inp['name'] in self.in_dict.keys():
2241  self.in_dict[inp['name']].inport = inp
2242 
2243 
2244  if tmp == RTM.RTComponent.RTC_STARTING or tmp == RTM.RTComponent.RTC_ACTIVE:
2245  self.state = 'active'
2246  self.color = ACTIVE_COLOR
2247  elif tmp == RTM.RTComponent.RTC_STOPPING or tmp == RTM.RTComponent.RTC_READY:
2248  self.state = 'inactive'
2249  self.color = INACTIVE_COLOR
2250  elif tmp >= RTM.RTComponent.RTC_ABORTING :
2251  self.state = 'error'
2252  self.color = ERROR_COLOR
2253  else :
2254  self.state = 'unloaded'
2255  self.color = UNLOADED_COLOR
2256 
2257 # if old_state == 'unloaded' and self.state != 'unloaded':
2258  if len(self.out_dict.keys()) != len(self.out_list):
2259  self.removeWidget(dc,0)
2260 
2261  old_rot = self.rotTogle
2262  old_rev = self.revTogle
2263  old_lastrot = self.lastRot
2264  self.rotTogle = 0
2265  self.revTogle = 1
2266  self.lastRot = 'LR' # LR(Left/Right) or TB(Top/Bottom)
2267  self.x_size = BOX_WIDTH
2268  self.x = self.x - self.x_size/2
2269  self.y = self.y - self.y_size/2
2270  self.ratioW = 1.0
2271  self.ratioH = 1.0
2272  self.createWidget(0)
2273  if old_lastrot == 'LR':
2274  if old_rev == 0:
2275  self.reversesBody()
2276  else:
2277  if old_rot == 1:
2278  self.rotatesBody()
2279  else:
2280  self.rotatesBody()
2281  self.rotatesBody()
2282 
2283 # setBodyColor(self.baseBox, self.state)
2284  self.ns_dict.setCompBodyColor(self.fullpath, self.state)
2285  self.portToFlash()
2286  canvas.Redraw(dc)
2287 
2288  def removeWidget(self, dc, rot=0):
2289  """コンポーネント図形を削除する インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
2290  インポート図形、アウトポート図形、関連する線も削除する [引数] dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
2291 
2292  [引数]
2293  dc -- 描画するデバイス・コンテキストを指定 rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
2294  rot -- 線の削除可否を指定する。(回転処理等で使用) 0:線を削除 / 1:線を削除しない [戻り値] void
2295  0:線を削除 / 1:線を削除しない
2296 
2297  [戻り値]
2298  void
2299  """
2300  # 本体図形をキャンバス、DC上から削除する canvas = self.body.GetCanvas() self.body.Erase(dc) self.body.RemoveFromCanvas(canvas) # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2301  canvas = self.body.GetCanvas()
2302  self.body.Erase(dc)
2303  self.body.RemoveFromCanvas(canvas)
2304 
2305  # ビットマップの削除 if self.bmp: self.bmp.Erase(dc) self.bmp.RemoveFromCanvas(canvas) # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2306  if self.bmp:
2307  self.bmp.Erase(dc)
2308  self.bmp.RemoveFromCanvas(canvas)
2309 
2310  # コンポーネント名称の削除 self.text.Erase(dc) self.text.RemoveFromCanvas(canvas) # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2311  self.text.Erase(dc)
2312  self.text.RemoveFromCanvas(canvas)
2313 
2314  # インポート/アウトポートの削除 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].removeWidget(dc,rot) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].removeWidget(dc,rot) def createWidget(self, rot): """コンポーネント図形の作成 [引数] rot -- 図形の回転処理を行うフラグ 0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void """ if rot == 0: tmp = max(len(self.in_list), len(self.out_list)) if tmp == 0: tmp = 1 self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp pos_x = self.x + (BOX_WIDTH * self.ratioW)/2 pos_y = self.y + self.y_size/2 else: pos_x = self.x pos_y = self.y # コンポーネント名称(TextShape)の作成 canvas = self.parent.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) cnt = len(self.name) charW = dc.GetCharWidth() charH = dc.GetCharHeight() tmpW = charW * (cnt*1.2) tmpH = charH * 1.4 self.text_x = pos_x + (self.x_size/2) self.text_y = self.y + self.y_size + POLYGON_SIZE self.text = makeTextShape(self,tmpW, tmpH) self.text.AddText(self.name) self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN) ### # ビットマップの作成 self.bmp = ogl.BitmapShape() # if self.rtc.icon_path != None or self.rtc.icon_path != "": # if self.rtc.icon_path != "": # bitmap = wx.Bitmap(self.rtc.icon_path) # else: # bitmap = wx.NullBitmap # self.bmp.SetSize(10,10,False) bitmap = wx.NullBitmap self.bmp.SetSize(10,10,False) # self.bmp.SetBitmap(bitmap) self.bmp.parent = self self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN ) # 本体の四角形を作成 self.baseBox = makeRectangle(self, self.x_size, self.y_size) self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2315  for inp in self.in_list:
2316  if inp['name'] in self.in_dict.keys():
2317  self.in_dict[inp['name']].removeWidget(dc,rot)
2318  for outp in self.out_list:
2319  if outp['name'] in self.out_dict.keys():
2320  self.out_dict[outp['name']].removeWidget(dc,rot)
2321 
2322 
2323  def createWidget(self, rot):
2324  """コンポーネント図形の作成
2325 
2326  [引数]
2327  rot -- 図形の回転処理を行うフラグ
2328  0:回転なし(座標を計算で求める) 1:回転あり(既存の座標を使用) [戻り値] void
2329 
2330  [戻り値]
2331  void
2332  """
2333  if rot == 0:
2334  tmp = max(len(self.in_list), len(self.out_list))
2335  if tmp == 0:
2336  tmp = 1
2337  self.y_size = 2 * POLYGON_SIZE * self.ratioH * tmp
2338  pos_x = self.x + (BOX_WIDTH * self.ratioW)/2
2339  pos_y = self.y + self.y_size/2
2340  else:
2341  pos_x = self.x
2342  pos_y = self.y
2343 
2344  # コンポーネント名称(TextShape)の作成
2345  canvas = self.parent.diagram.GetCanvas()
2346  dc = wx.ClientDC(canvas)
2347  canvas.PrepareDC(dc)
2348  cnt = len(self.name)
2349  charW = dc.GetCharWidth()
2350  charH = dc.GetCharHeight()
2351  tmpW = charW * (cnt*1.2)
2352  tmpH = charH * 1.4
2353  self.text_x = pos_x + (self.x_size/2)
2354  self.text_y = self.y + self.y_size + POLYGON_SIZE
2355 
2356  self.text = makeTextShape(self,tmpW, tmpH)
2357  self.text.AddText(self.name)
2358  self.parent.MyAddText(self.text, self.text_x, self.text_y,wx.BLACK_PEN)
2359 ###
2360  # ビットマップの作成
2361  self.bmp = ogl.BitmapShape()
2362 # if self.rtc.icon_path != None or self.rtc.icon_path != "":
2363 # if self.rtc.icon_path != "":
2364 # bitmap = wx.Bitmap(self.rtc.icon_path)
2365 # else:
2366 # bitmap = wx.NullBitmap
2367 # self.bmp.SetSize(10,10,False)
2368  bitmap = wx.NullBitmap
2369  self.bmp.SetSize(10,10,False)
2370 #
2371  self.bmp.SetBitmap(bitmap)
2372  self.bmp.parent = self
2373  self.parent.MyAddBmp( self.bmp, pos_x, pos_y, wx.BLACK_PEN )
2374 
2375  # 本体の四角形を作成
2376  self.baseBox = makeRectangle(self, self.x_size, self.y_size)
2377  self.parent.MyAddShape(self.baseBox, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0)
2378  # 前述のパーツ郡をCompositeShapeとして、親子構造にする self.body = makeCompositeShape(self) self.body.AddChild(self.baseBox) self.body.AddChild(self.bmp) self.body.AddChild(self.text) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp]) self.body.AddConstraint(self.constraint) self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text]) self.body.AddConstraint(self.constraint2) # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text]) # self.body.AddConstraint(self.constraint) self.body.Recompute() self.body.CalculateSize() ### self.parent.MyAddShape( self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0) # 比率計算用の最後の座標および拡大縮小用の最後のサイズ self.baseBox.lastx = self.body.GetX() self.baseBox.lasty = self.body.GetY() self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin() if rot == 0: # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2380  self.body.AddChild(self.baseBox)
2381  self.body.AddChild(self.bmp)
2382  self.body.AddChild(self.text)
2383 #
2384  self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_ALIGNED_TOP, self.baseBox, [self.bmp])
2385  self.body.AddConstraint(self.constraint)
2386  self.constraint2 = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.bmp, [self.text])
2387  self.body.AddConstraint(self.constraint2)
2388 # self.constraint = ogl.OGLConstraint(ogl.gyCONSTRAINT_CENTRED_HORIZONTALLY, self.baseBox, [self.text])
2389 # self.body.AddConstraint(self.constraint)
2390  self.body.Recompute()
2391  self.body.CalculateSize()
2392 ###
2393  self.parent.MyAddShape(
2394  self.body, pos_x, pos_y, wx.BLACK_PEN, wx.Brush(self.color, wx.SOLID), "" ,0)
2395  # 比率計算用の最後の座標および拡大縮小用の最後のサイズ
2396  self.baseBox.lastx = self.body.GetX()
2397  self.baseBox.lasty = self.body.GetY()
2398  self.lastBBoxWidth, self.lastBBoxHeight = self.baseBox.GetBoundingBoxMin()
2399 
2400  if rot == 0:
2401  # インポートの作成(回転処理時は行わない) self.in_dict = {} port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 for inp in self.in_list : self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath, inp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 # # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2402  self.in_dict = {}
2403  port_x = self.x - (POLYGON_SIZE*self.ratioW)*2/3
2404  port_y = self.y + (POLYGON_SIZE*self.ratioH)/2
2405  for inp in self.in_list :
2406  self.in_dict[inp['name']] = GRtcIn(self, self.ns_dict, self.fullpath,
2407  inp,
2408  port_x, port_y)
2409  port_y = port_y + (POLYGON_SIZE*self.ratioH)*2
2410 #
2411  # アウトポートの作成(回転処理時は行わない) port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3 port_y = self.y + (POLYGON_SIZE*self.ratioH)/2 self.out_dict = {} for outp in self.out_list : self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath, outp, port_x, port_y) port_y = port_y + (POLYGON_SIZE*self.ratioH)*2 self.portToFlash() def dmove(self, dc, movex, movey): """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void """ canvas = self.body.GetCanvas() self.x = self.body.GetX() + movex self.y = self.body.GetY() + movey self.body.Erase(dc) self.body.Move(dc, self.x, self.y) # インポート、アウトポート図形の移動 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].dmove(dc, movex, movey) for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].dmove(dc, movex, movey) def selected(self): """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void """ self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR))) self.body.Flash() # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def unselected(self,dc): """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void """ self.checkCompState() setBodyColor(self.baseBox, self.state) # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示 self.portToFlash() def updatePolygonSize(self, x, y, ratioW, ratioH): """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void """ self.x = x self.y = y self.ratioW = ratioW self.ratioH = ratioH self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更 if self.lastRot == 'TB': minW, minH = self.minHeight, self.minWidth else: minH, minW = self.minHeight, self.minWidth if minW > self.x_size or minH > self.y_size: self.ratioW = 1.0 self.ratioH = 1.0 self.x_size = minW self.y_size = minH # 一度図形を削除し、上記で設定したサイズで再作成 self.body.Select(False, dc) tmp = canvas.selected.index(self.baseBox) del canvas.selected[tmp] self.removeWidget(dc,1) self.createWidget(1) self.baseBox.Select(True, dc) canvas.selected.append(self.baseBox) x_size = self.px_size y_size = self.py_size # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2412  port_x = self.x + (BOX_WIDTH*self.ratioW) - (POLYGON_SIZE*self.ratioW)/3
2413  port_y = self.y + (POLYGON_SIZE*self.ratioH)/2
2414  self.out_dict = {}
2415  for outp in self.out_list :
2416  self.out_dict[outp['name']] = GRtcOut(self, self.ns_dict, self.fullpath,
2417  outp,
2418  port_x, port_y)
2419  port_y = port_y + (POLYGON_SIZE*self.ratioH)*2
2420 
2421  self.portToFlash()
2422 
2423 
2424  def dmove(self, dc, movex, movey):
2425  """コンポーネント図形の移動処理 インポート、アウトポート図形および関連する線も移動 [引数] dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
2426  インポート、アウトポート図形および関連する線も移動
2427 
2428  [引数]
2429  dc -- 描画するデバイス・コンテキストを指定 movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
2430  movex -- x座標の相対移動量を指定 movey -- y座標の相対移動量を指定 [戻り値] void
2431  movey -- y座標の相対移動量を指定 [戻り値] void
2432 
2433  [戻り値]
2434  void
2435  """
2436  canvas = self.body.GetCanvas()
2437 
2438  self.x = self.body.GetX() + movex
2439  self.y = self.body.GetY() + movey
2440  self.body.Erase(dc)
2441  self.body.Move(dc, self.x, self.y)
2442  # インポート、アウトポート図形の移動
2443  for inp in self.in_list:
2444  if inp['name'] in self.in_dict.keys():
2445  self.in_dict[inp['name']].dmove(dc, movex, movey)
2446  for outp in self.out_list:
2447  if outp['name'] in self.out_dict.keys():
2448  self.out_dict[outp['name']].dmove(dc, movex, movey)
2449 
2450 
2451  def selected(self):
2452  """コンポーネント図形の選択処理(色の変更) [引数] なし [戻り値] void
2453 
2454  [引数]
2455  なし
2456 
2457  [戻り値]
2458  void
2459  """
2460  self.baseBox.SetBrush(wx.Brush(wx.NamedColor(SELECTED_COLOR)))
2461  self.body.Flash()
2462  # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示
2463  self.portToFlash()
2464 
2465  def unselected(self,dc):
2466  """コンポーネント図形の非選択処理(色の変更) [引数] dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void
2467 
2468  [引数]
2469  dc -- 描画していたデバイス・コンテキストを指定 [戻り値] void
2470 
2471  [戻り値]
2472  void
2473  """
2474  self.checkCompState()
2475  setBodyColor(self.baseBox, self.state)
2476  # インポート/アウトポート図形をフラッシュ(再描画)し図形を最前面に表示
2477  self.portToFlash()
2478 
2479  def updatePolygonSize(self, x, y, ratioW, ratioH):
2480  """コンポーネント図形(インポート/アウトポート)のサイズ変更処理 コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2481  コンポーネント図形本体のサイズ変更はデフォルト(システム側)で行われる [引数] x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2482 
2483  [引数]
2484  x -- 描画するx座標を指定 y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2485  y -- 描画するy座標を指定 ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2486  ratioW -- サイズ変更するWidthの比率を指定 ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2487  ratioH -- サイズ変更するHeightの比率を指定 [戻り値] void
2488 
2489  [戻り値]
2490  void
2491  """
2492  self.x = x
2493  self.y = y
2494  self.ratioW = ratioW
2495  self.ratioH = ratioH
2496  self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin()
2497 
2498  canvas = self.body.GetCanvas()
2499  dc = wx.ClientDC(canvas)
2500  canvas.PrepareDC(dc)
2501 
2502  # 最小サイズのチェック:初期サイズより小さかったら初期サイズに変更
2503  if self.lastRot == 'TB':
2504  minW, minH = self.minHeight, self.minWidth
2505  else:
2506  minH, minW = self.minHeight, self.minWidth
2507  if minW > self.x_size or minH > self.y_size:
2508  self.ratioW = 1.0
2509  self.ratioH = 1.0
2510  self.x_size = minW
2511  self.y_size = minH
2512  # 一度図形を削除し、上記で設定したサイズで再作成
2513  self.body.Select(False, dc)
2514  tmp = canvas.selected.index(self.baseBox)
2515  del canvas.selected[tmp]
2516  self.removeWidget(dc,1)
2517  self.createWidget(1)
2518  self.baseBox.Select(True, dc)
2519  canvas.selected.append(self.baseBox)
2520 
2521 
2522  x_size = self.px_size
2523  y_size = self.py_size
2524  # インポートが存在する時、インポートのサイズを変更する if len(self.in_dict) > 0: in_pos = self.in_dict[self.in_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if in_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif in_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif in_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif in_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if in_pos == 'Right' or in_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*2 # # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2525  if len(self.in_dict) > 0:
2526  in_pos = self.in_dict[self.in_list[0]['name']].position
2527 
2528  port_x = self.x - self.x_size/2 + x_size -1
2529  port_y = self.y - self.y_size/2 + y_size -1
2530  # ポートのpositionによる位置調整
2531  if in_pos == 'Right':
2532  port_x = self.x + self.x_size/2 + x_size/6
2533  elif in_pos == 'Left':
2534  port_x = self.x - self.x_size/2 - x_size/6
2535  elif in_pos == 'Top':
2536  port_y = self.y - self.y_size/2 - y_size/6
2537  elif in_pos == 'Bottom':
2538  port_y = self.y + self.y_size/2 + y_size/6
2539 
2540  for inp in self.in_list:
2541  if inp['name'] in self.in_dict.keys():
2542  self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH)
2543  # ポートのpositionによる位置調整
2544  if in_pos == 'Right' or in_pos == 'Left':
2545  port_y = port_y + y_size*2
2546  else:
2547  port_x = port_x + x_size*2
2548 #
2549 
2550  # アウトポートが存在する時、アウトポートのサイズを変更する if len(self.out_dict) > 0: out_pos = self.out_dict[self.out_list[0]['name']].position port_x = self.x - self.x_size/2 + x_size -1 port_y = self.y - self.y_size/2 + y_size -1 # ポートのpositionによる位置調整 if out_pos == 'Right': port_x = self.x + self.x_size/2 + x_size/6 elif out_pos == 'Left': port_x = self.x - self.x_size/2 - x_size/6 elif out_pos == 'Top': port_y = self.y - self.y_size/2 - y_size/6 elif out_pos == 'Bottom': port_y = self.y + self.y_size/2 + y_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH) # ポートのpositionによる位置調整 if out_pos == 'Right' or out_pos == 'Left': port_y = port_y + y_size*2 else: port_x = port_x + x_size*self.ratioW*2 # コンポーネント名称の表示位置調整 if self.lastRot == 'LR': self.text_y = self.y + self.y_size/2 + POLYGON_SIZE else: self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 if self.lastRot != 'LR': pos_y = pos_y + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.selected() self.portToFlash() def reversesBody(self): """左右反転(回転)処理 [引数] なし [戻り値] void """ # 左右トグルフラグの更新 self.revTogle = self.revTogle + 1 if self.revTogle % 2 == 0 : self.revTogle = 0 self.x = self.baseBox.GetX() self.y = self.baseBox.GetY() tmp = max(len(self.in_list), len(self.out_list)) center_x = self.baseBox.GetX() center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 else: self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2551  if len(self.out_dict) > 0:
2552  out_pos = self.out_dict[self.out_list[0]['name']].position
2553 
2554  port_x = self.x - self.x_size/2 + x_size -1
2555  port_y = self.y - self.y_size/2 + y_size -1
2556  # ポートのpositionによる位置調整
2557  if out_pos == 'Right':
2558  port_x = self.x + self.x_size/2 + x_size/6
2559  elif out_pos == 'Left':
2560  port_x = self.x - self.x_size/2 - x_size/6
2561  elif out_pos == 'Top':
2562  port_y = self.y - self.y_size/2 - y_size/6
2563  elif out_pos == 'Bottom':
2564  port_y = self.y + self.y_size/2 + y_size/6
2565 
2566  for outp in self.out_list:
2567  if outp['name'] in self.out_dict.keys():
2568  self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, ratioW, ratioH)
2569  # ポートのpositionによる位置調整
2570  if out_pos == 'Right' or out_pos == 'Left':
2571  port_y = port_y + y_size*2
2572  else:
2573  port_x = port_x + x_size*self.ratioW*2
2574 
2575  # コンポーネント名称の表示位置調整
2576  if self.lastRot == 'LR':
2577  self.text_y = self.y + self.y_size/2 + POLYGON_SIZE
2578  else:
2579  self.text_y = self.y + self.y_size/2 + self.py_size
2580  self.text.Erase(dc)
2581  self.text.SetY(self.text_y)
2582  self.text.Flash()
2583 
2584  # ビットマップの表示位置調整
2585  tmpw, tmph = self.bmp.GetBoundingBoxMin()
2586  pos_y = self.y - self.y_size/2 + tmph/2
2587  if self.lastRot != 'LR':
2588  pos_y = pos_y + self.py_size/2
2589  self.bmp.Erase(dc)
2590  self.bmp.SetY(pos_y)
2591  self.bmp.Flash()
2592 
2593  self.selected()
2594  self.portToFlash()
2595 
2596  def reversesBody(self):
2597  """左右反転(回転)処理 [引数] なし [戻り値] void
2598 
2599  [引数]
2600  なし
2601 
2602  [戻り値]
2603  void
2604  """
2605  # 左右トグルフラグの更新
2606  self.revTogle = self.revTogle + 1
2607  if self.revTogle % 2 == 0 :
2608  self.revTogle = 0
2609 
2610  self.x = self.baseBox.GetX()
2611  self.y = self.baseBox.GetY()
2612  tmp = max(len(self.in_list), len(self.out_list))
2613  center_x = self.baseBox.GetX()
2614  center_y = self.baseBox.GetY()
2615  # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え
2616  if self.lastRot == 'LR':
2617  self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin()
2618  self.xy_swap = 0
2619  else:
2620  self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin()
2621  self.xy_swap = 1
2622 
2623  canvas = self.body.GetCanvas()
2624  dc = wx.ClientDC(canvas)
2625  canvas.PrepareDC(dc)
2626  # 一度図形を削除し、上記で設定したサイズで再作成
2627  self.removeWidget(dc,1)
2628  self.createWidget(1)
2629 
2630  # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.px_size else: p_size = self.py_size if self.revTogle == 1: # inport is right side of body port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Left' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Right' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 else : # inport is left side of body port_x = self.x + self.x_size/2 + p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Right' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # port_x = self.x - self.x_size/2 - p_size/6 port_y = self.y - self.y_size/2 + p_size-1 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Left' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_y = port_y + p_size*2 # テキストの表示位置を再計算 self.text_y = self.y + self.y_size/2 + POLYGON_SIZE self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() self.lastRot = 'LR' self.xy_swap = 0 def rotatesBody(self): ## +-90 degrees """上下回転処理 [引数] なし [戻り値] void """ tmp = max(len(self.in_list), len(self.out_list)) self.x = center_x = self.baseBox.GetX() self.y = center_y = self.baseBox.GetY() # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え if self.lastRot == 'LR': self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 1 else: self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin() self.xy_swap = 0 canvas = self.body.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 一度図形を削除し、上記で設定したサイズで再作成 self.removeWidget(dc,1) self.createWidget(1) # 上下トグルフラグの更新 self.rotTogle = self.rotTogle + 1 if self.rotTogle % 2 == 0 : self.rotTogle = 0 # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2631  if self.xy_swap == 1:
2632  p_size = self.px_size
2633  else:
2634  p_size = self.py_size
2635  if self.revTogle == 1: # inport is right side of body
2636  port_x = self.x - self.x_size/2 - p_size/6
2637  port_y = self.y - self.y_size/2 + p_size-1
2638  for inp in self.in_list:
2639  if inp['name'] in self.in_dict.keys():
2640  self.in_dict[inp['name']].position = 'Left'
2641  self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2642  port_y = port_y + p_size*2
2643 #
2644  port_x = self.x + self.x_size/2 + p_size/6
2645  port_y = self.y - self.y_size/2 + p_size-1
2646  for outp in self.out_list:
2647  if outp['name'] in self.out_dict.keys():
2648  self.out_dict[outp['name']].position = 'Right'
2649  self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2650  port_y = port_y + p_size*2
2651 
2652  else : # inport is left side of body
2653  port_x = self.x + self.x_size/2 + p_size/6
2654  port_y = self.y - self.y_size/2 + p_size-1
2655  for inp in self.in_list:
2656  if inp['name'] in self.in_dict.keys():
2657  self.in_dict[inp['name']].position = 'Right'
2658  self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2659  port_y = port_y + p_size*2
2660 #
2661  port_x = self.x - self.x_size/2 - p_size/6
2662  port_y = self.y - self.y_size/2 + p_size-1
2663  for outp in self.out_list:
2664  if outp['name'] in self.out_dict.keys():
2665  self.out_dict[outp['name']].position = 'Left'
2666  self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2667  port_y = port_y + p_size*2
2668 
2669  # テキストの表示位置を再計算
2670  self.text_y = self.y + self.y_size/2 + POLYGON_SIZE
2671  self.text.Erase(dc)
2672  self.text.SetY(self.text_y)
2673  self.text.Flash()
2674 
2675  self.lastRot = 'LR'
2676  self.xy_swap = 0
2677 
2678 
2679  def rotatesBody(self): ## +-90 degrees
2680  """上下回転処理 [引数] なし [戻り値] void
2681 
2682  [引数]
2683  なし
2684 
2685  [戻り値]
2686  void
2687  """
2688  tmp = max(len(self.in_list), len(self.out_list))
2689  self.x = center_x = self.baseBox.GetX()
2690  self.y = center_y = self.baseBox.GetY()
2691  # 最後に左右/上下どちらの回転処理が行われたかでWidth/Heightの入れ替え
2692  if self.lastRot == 'LR':
2693  self.y_size, self.x_size = self.baseBox.GetBoundingBoxMin()
2694  self.xy_swap = 1
2695  else:
2696  self.x_size, self.y_size = self.baseBox.GetBoundingBoxMin()
2697  self.xy_swap = 0
2698 
2699  canvas = self.body.GetCanvas()
2700  dc = wx.ClientDC(canvas)
2701  canvas.PrepareDC(dc)
2702 
2703  # 一度図形を削除し、上記で設定したサイズで再作成
2704  self.removeWidget(dc,1)
2705  self.createWidget(1)
2706 
2707 
2708  # 上下トグルフラグの更新
2709  self.rotTogle = self.rotTogle + 1
2710  if self.rotTogle % 2 == 0 :
2711  self.rotTogle = 0
2712 
2713  # 複数ポートの表示座標を決める基準(POLYGON_SIZE)を決定 if self.xy_swap == 1: p_size = self.py_size else: p_size = self.px_size # インポート/アウトポートのサイズ変更 if self.rotTogle == 1: # inport is top side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Top' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Bottom' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 else : # inport is bottom side of body port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y + self.y_size/2 + p_size/6 for inp in self.in_list: if inp['name'] in self.in_dict.keys(): self.in_dict[inp['name']].position = 'Bottom' self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # port_x = self.x - self.x_size/2 + p_size-1 port_y = self.y - self.y_size/2 - p_size/6 for outp in self.out_list: if outp['name'] in self.out_dict.keys(): self.out_dict[outp['name']].position = 'Top' self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1) port_x = port_x + p_size*2 # テキストの表示位置調整 self.text_y = self.y + self.y_size/2 + self.py_size self.text.Erase(dc) self.text.SetY(self.text_y) self.text.Flash() # ビットマップの表示位置調整 tmpw, tmph = self.bmp.GetBoundingBoxMin() pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2 self.bmp.Erase(dc) self.bmp.SetY(pos_y) self.bmp.Flash() self.lastRot = 'TB' self.xy_swap = 0 #---------------------------------------------------------------------- class MyEvtHandlerBmp(ogl.ShapeEvtHandler): """ビットマップ用のダミーイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerOval(ogl.ShapeEvtHandler): """線移動用の円のイベントクラス""" def __init__(self, log, frame): """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 0 def OnBeginDragLeft(self, x, y, keys=0, attachment=0): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.dragOn = 1 def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # self.base_OnBeginDragLeft(x, y, keys, attachment) shape = self.GetShape() if self.dragOn == 1: # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示 canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty shape.parent.dmove(dc,movex,movey) shape.lastx = shape.GetX() shape.lasty = shape.GetY() canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandlerDummy(ogl.ShapeEvtHandler): """ダミーイベントハンドラ""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
2714  if self.xy_swap == 1:
2715  p_size = self.py_size
2716  else:
2717  p_size = self.px_size
2718  # インポート/アウトポートのサイズ変更
2719  if self.rotTogle == 1: # inport is top side of body
2720  port_x = self.x - self.x_size/2 + p_size-1
2721  port_y = self.y - self.y_size/2 - p_size/6
2722  for inp in self.in_list:
2723  if inp['name'] in self.in_dict.keys():
2724  self.in_dict[inp['name']].position = 'Top'
2725  self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2726  port_x = port_x + p_size*2
2727 #
2728  port_x = self.x - self.x_size/2 + p_size-1
2729  port_y = self.y + self.y_size/2 + p_size/6
2730  for outp in self.out_list:
2731  if outp['name'] in self.out_dict.keys():
2732  self.out_dict[outp['name']].position = 'Bottom'
2733  self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2734  port_x = port_x + p_size*2
2735 
2736  else : # inport is bottom side of body
2737  port_x = self.x - self.x_size/2 + p_size-1
2738  port_y = self.y + self.y_size/2 + p_size/6
2739  for inp in self.in_list:
2740  if inp['name'] in self.in_dict.keys():
2741  self.in_dict[inp['name']].position = 'Bottom'
2742  self.in_dict[inp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2743  port_x = port_x + p_size*2
2744 #
2745  port_x = self.x - self.x_size/2 + p_size-1
2746  port_y = self.y - self.y_size/2 - p_size/6
2747  for outp in self.out_list:
2748  if outp['name'] in self.out_dict.keys():
2749  self.out_dict[outp['name']].position = 'Top'
2750  self.out_dict[outp['name']].updatePolygonSize(port_x, port_y, 1, 1)
2751  port_x = port_x + p_size*2
2752 
2753  # テキストの表示位置調整
2754  self.text_y = self.y + self.y_size/2 + self.py_size
2755  self.text.Erase(dc)
2756  self.text.SetY(self.text_y)
2757  self.text.Flash()
2758 
2759  # ビットマップの表示位置調整
2760  tmpw, tmph = self.bmp.GetBoundingBoxMin()
2761  pos_y = self.y - self.y_size/2 + tmph/2 + self.py_size/2
2762  self.bmp.Erase(dc)
2763  self.bmp.SetY(pos_y)
2764  self.bmp.Flash()
2765 
2766  self.lastRot = 'TB'
2767  self.xy_swap = 0
2768 
2769 #----------------------------------------------------------------------
2770 class MyEvtHandlerBmp(ogl.ShapeEvtHandler):
2771  """ビットマップ用のダミーイベントクラス"""
2772  def __init__(self, log, frame):
2773  """クラスの初期化
2774 
2775  [引数]
2776  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2777  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2778  ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2779 
2780  [戻り値]
2781  void
2782  """
2783  ogl.ShapeEvtHandler.__init__(self)
2784  self.log = log
2785  self.statbarFrame = frame
2786 
2787  def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
2788  """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2789  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2790 
2791  [引数]
2792  x -- イベント時のx座標
2793  y -- イベント時のy座標
2794  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2795  attachment -- アタッチメント [戻り値] void
2796 
2797  [戻り値]
2798  void
2799  """
2800  pass
2801 
2802  def OnLeftClick(self, x, y, keys = 0, attachment = 0):
2803  """マウス左クリック時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2804  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2805 
2806  [引数]
2807  x -- イベント時のx座標
2808  y -- イベント時のy座標
2809  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2810  attachment -- アタッチメント [戻り値] void
2811 
2812  [戻り値]
2813  void
2814  """
2815  pass
2816 
2817  def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
2818  """サイズ変更終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2819  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2820 
2821  [引数]
2822  pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2823  x -- イベント時のx座標
2824  y -- イベント時のy座標
2825  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2826  attachment -- アタッチメント [戻り値] void
2827 
2828  [戻り値]
2829  void
2830  """
2831  pass
2832 
2833  def OnBeginDragLeft(self, x, y, keys, attachment):
2834  """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2835  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2836 
2837  [引数]
2838  x -- イベント時のx座標
2839  y -- イベント時のy座標
2840  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント [戻り値] void
2841  attachment -- アタッチメント [戻り値] void
2842 
2843  [戻り値]
2844  void
2845  """
2846  pass
2847 
2848 #----------------------------------------------------------------------
2849 class MyEvtHandlerOval(ogl.ShapeEvtHandler):
2850  """線移動用の円のイベントクラス"""
2851  def __init__(self, log, frame):
2852  """クラスの初期化(ShapeEvtHandlerの作成) [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2853 
2854  [引数]
2855  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2856  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2857  ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2858 
2859  [戻り値]
2860  void
2861  """
2862  ogl.ShapeEvtHandler.__init__(self)
2863  self.log = log
2864  self.statbarFrame = frame
2865 
2866  def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
2867  """ドラッグ終了時に呼ばれるイベントハンドラ ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2868  ドラッグフラグをoffにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2869 
2870  [引数]
2871  x -- イベント時のx座標
2872  y -- イベント時のy座標
2873  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2874  attachment -- アタッチメント(未使用) [戻り値] void
2875 
2876  [戻り値]
2877  void
2878  """
2879  self.dragOn = 0
2880 
2881  def OnBeginDragLeft(self, x, y, keys=0, attachment=0):
2882  """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2883  ドラッグフラグをonにする [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2884 
2885  [引数]
2886  x -- イベント時のx座標
2887  y -- イベント時のy座標
2888  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2889  attachment -- アタッチメント(未使用) [戻り値] void
2890 
2891  [戻り値]
2892  void
2893  """
2894  self.dragOn = 1
2895 
2896  def OnDragLeft(self, draw, x, y, keys, attachment):
2897  """ドラッグ開始時に呼ばれるイベントハンドラ 移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2898  移動用の円をドラッグで移動(円のdmoveメソッド内で関連する線も移動させる) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2899 
2900  [引数]
2901  x -- イベント時のx座標
2902  y -- イベント時のy座標
2903  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2904  attachment -- アタッチメント(未使用) [戻り値] void
2905 
2906  [戻り値]
2907  void
2908  """
2909 # self.base_OnBeginDragLeft(x, y, keys, attachment)
2910  shape = self.GetShape()
2911 
2912  if self.dragOn == 1:
2913 
2914  # メモリDC(BufferedDC)の生成:メモリ上に絵を描き、Redrawで表に表示
2915  canvas = shape.GetCanvas()
2916  dc = getBufferedDC(canvas)
2917  canvas.PrepareDC(dc)
2918 
2919  movex = x - shape.lastx
2920  movey = y - shape.lasty
2921 
2922  shape.parent.dmove(dc,movex,movey)
2923 
2924  shape.lastx = shape.GetX()
2925  shape.lasty = shape.GetY()
2926 
2927  canvas.Redraw(dc)
2928 
2929 #----------------------------------------------------------------------
2930 class MyEvtHandlerDummy(ogl.ShapeEvtHandler):
2931  """ダミーイベントハンドラ"" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnDragLeft(self, draw, x, y, keys=0, attachment=0): """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ pass #---------------------------------------------------------------------- class MyEvtHandlerLine(ogl.ShapeEvtHandler): """線のイベントクラス""" def __init__(self ): """クラスの初期化 [引数] なし [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) """
2932  def __init__(self, log, frame):
2933  """クラスの初期化
2934 
2935  [引数]
2936  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2937  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2938  ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
2939 
2940  [戻り値]
2941  void
2942  """
2943  ogl.ShapeEvtHandler.__init__(self)
2944  self.log = log
2945  ogl.ShapeEvtHandler.__init__(self)
2946  self.log = log
2947  self.statbarFrame = frame
2948 
2949  def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
2950  """ドラッグ終了時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2951  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2952 
2953  [引数]
2954  x -- イベント時のx座標
2955  y -- イベント時のy座標
2956  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2957  attachment -- アタッチメント(未使用) [戻り値] void
2958 
2959  [戻り値]
2960  void
2961  """
2962  pass
2963 
2964  def OnDragLeft(self, draw, x, y, keys=0, attachment=0):
2965  """ドラッグ時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2966  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2967 
2968  [引数]
2969  x -- イベント時のx座標
2970  y -- イベント時のy座標
2971  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2972  attachment -- アタッチメント(未使用) [戻り値] void
2973 
2974  [戻り値]
2975  void
2976  """
2977  pass
2978 
2979  def OnBeginDragLeft(self, x, y, keys, attachment):
2980  """ドラッグ開始時に呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2981  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2982 
2983  [引数]
2984  x -- イベント時のx座標
2985  y -- イベント時のy座標
2986  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2987  attachment -- アタッチメント(未使用) [戻り値] void
2988 
2989  [戻り値]
2990  void
2991  """
2992  pass
2993 
2994  def OnLeftClick(self, x, y, keys = 0, attachment = 0):
2995  """マウス左クリックに呼ばれるイベントハンドラ 処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2996  処理を未実装(passのみ)でイベントを登録し、デフォルトの動作を抑止 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
2997 
2998  [引数]
2999  x -- イベント時のx座標
3000  y -- イベント時のy座標
3001  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3002  attachment -- アタッチメント(未使用) [戻り値] void
3003 
3004  [戻り値]
3005  void
3006  """
3007  pass
3008 
3009 
3010 #----------------------------------------------------------------------
3011 class MyEvtHandlerLine(ogl.ShapeEvtHandler):
3012  """線のイベントクラス"""
3013  def __init__(self ):
3014  """クラスの初期化
3015 
3016  [引数]
3017  なし
3018 
3019  [戻り値]
3020  void
3021  """
3022  ogl.ShapeEvtHandler.__init__(self)
3023 
3024  def OnLeftClick(self, x, y, keys = 0, attachment = 0):
3025  """マウス左クリック時に呼ばれるイベントハンドラ 線の選択/解除を行う 選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3026  線の選択/解除を行う
3027  選択処理では、移動用の円も作成する [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3028 
3029  [引数]
3030  x -- イベント時のx座標
3031  y -- イベント時のy座標
3032  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3033  attachment -- アタッチメント(未使用) [戻り値] void
3034 
3035  [戻り値]
3036  void
3037  """
3038  shape = self.GetShape()
3039 # print shape.__class__, shape.GetClassName()
3040  canvas = shape.GetCanvas()
3041  dc = wx.ClientDC(canvas)
3042  canvas.PrepareDC(dc)
3043  # 線が選択済み if shape in canvas.selected: # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3044  if shape in canvas.selected:
3045  # 選択状態の解除 for obj in shape.parent.lines: obj.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: obj.parent.unselected(dc) idx = canvas.selected.index(obj) del canvas.selected[idx] # 線が未選択 else: # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3046  for obj in shape.parent.lines:
3047  obj.Select(False, dc)
3048  shape.parent.unselected(dc)
3049  for obj in canvas.selected:
3050  if shape == obj:
3051  obj.parent.unselected(dc)
3052  idx = canvas.selected.index(obj)
3053  del canvas.selected[idx]
3054  # 線が未選択
3055  else:
3056  # 選択状態に移行 redraw = False shapeList = canvas.GetDiagram().GetShapeList() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.parent.selected() for obj in shape.parent.lines: canvas.selected.append(obj) # create oval on line line = shape.parent if (line.coordT == None) or (len(line.coordT) == 2): return # 線移動用の円を生成 num = len(line.coordT) line.oval_dict = {} for oval_id in range(1,num-2): line_pos_0 = line.coordT[oval_id] line_pos_1 = line.coordT[oval_id+1] if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line hight = line_pos_0[1] - line_pos_1[1] pos_y = line_pos_1[1] + (hight/2) pos_x = line_pos_0[0] tag = (oval_id, "oval_width_pos") elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line width = line_pos_0[0] - line_pos_1[0] pos_x = line_pos_1[0] + (width/2) pos_y = line_pos_1[1] tag = (oval_id, "oval_length_pos") line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y) line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y) canvas.Redraw(dc) #---------------------------------------------------------------------- class MyEvtHandler(ogl.ShapeEvtHandler): """コンポーネント図形(四角形)本体のイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # クリック時、プロファイル表示 ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile()) except: except_mess("obj-ref error:") # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3057  redraw = False
3058  shapeList = canvas.GetDiagram().GetShapeList()
3059 
3060  if canvas.selected and keys != 1:
3061  for s in canvas.selected:
3062  s.Select(False, dc)
3063  s.parent.unselected(dc)
3064  canvas.selected = []
3065  canvas.Redraw(dc)
3066 
3067  shape.parent.selected()
3068 
3069  for obj in shape.parent.lines:
3070  canvas.selected.append(obj)
3071 
3072  # create oval on line
3073  line = shape.parent
3074  if (line.coordT == None) or (len(line.coordT) == 2):
3075  return
3076 
3077  # 線移動用の円を生成
3078  num = len(line.coordT)
3079  line.oval_dict = {}
3080  for oval_id in range(1,num-2):
3081  line_pos_0 = line.coordT[oval_id]
3082  line_pos_1 = line.coordT[oval_id+1]
3083  if line_pos_0[0] == line_pos_1[0] and line_pos_0[1] != line_pos_1[1]: # width line
3084  hight = line_pos_0[1] - line_pos_1[1]
3085  pos_y = line_pos_1[1] + (hight/2)
3086  pos_x = line_pos_0[0]
3087  tag = (oval_id, "oval_width_pos")
3088  elif line_pos_0[0] != line_pos_1[0] and line_pos_0[1] == line_pos_1[1] : # length line
3089  width = line_pos_0[0] - line_pos_1[0]
3090  pos_x = line_pos_1[0] + (width/2)
3091  pos_y = line_pos_1[1]
3092  tag = (oval_id, "oval_length_pos")
3093  line.oval_dict[oval_id] = GRectOval(line, tag, pos_x, pos_y)
3094  line.parent.parent.parent.MyAddOval(line.oval_dict[oval_id].body, pos_x, pos_y)
3095 
3096  canvas.Redraw(dc)
3097 
3098 #----------------------------------------------------------------------
3099 
3100 class MyEvtHandler(ogl.ShapeEvtHandler):
3101  """コンポーネント図形(四角形)本体のイベントクラス"""
3102  def __init__(self, log, frame):
3103  """クラスの初期化
3104 
3105  [引数]
3106  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3107  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3108  ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3109 
3110  [戻り値]
3111  void
3112  """
3113  ogl.ShapeEvtHandler.__init__(self)
3114  self.log = log
3115  self.statbarFrame = frame
3116  self.dragOn = 0
3117 
3118  def UpdateStatusBar(self, shape):
3119  """ステータスバーへ表示する情報の更新
3120 
3121  [引数]
3122  shape -- 図形のオブジェクトを指定 [戻り値] void
3123 
3124  [戻り値]
3125  void
3126  """
3127  x,y = shape.GetX(), shape.GetY()
3128  width, height = shape.GetBoundingBoxMax()
3129  self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" %
3130  (x, y, width, height))
3131 
3132 
3133  def OnLeftClick(self, x, y, keys = 0, attachment = 0):
3134  """マウス左クリック時に呼ばれるイベントハンドラ 本体の選択/解除を行う [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3135  本体の選択/解除を行う
3136 
3137  [引数]
3138  x -- イベント時のx座標
3139  y -- イベント時のy座標
3140  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3141  attachment -- アタッチメント(未使用) [戻り値] void
3142 
3143  [戻り値]
3144  void
3145  """
3146  shape = self.GetShape()
3147 # print shape.__class__, shape.GetClassName()
3148  canvas = shape.GetCanvas()
3149  dc = wx.ClientDC(canvas)
3150  canvas.PrepareDC(dc)
3151 
3152  # クリック時、プロファイル表示
3153  ref = self.statbarFrame.myDict.GetObjRefToFullpath(shape.parent.fullpath)
3154  try:
3155  ref = ref._narrow(RTM.RTCBase)
3156  self.statbarFrame.profilepanel.RefreshProfile(ref._get_profile())
3157  except:
3158  except_mess("obj-ref error:")
3159 
3160  # イベントで呼び出された図形が選択済みの場合 if shape in canvas.selected: #if shape.parent.tag == 'body' or shape.parent.tag == 'line': # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3161  if shape in canvas.selected:
3162  #if shape.parent.tag == 'body' or shape.parent.tag == 'line':
3163  # 選択解除 canvas.lineFrom = None shape.Select(False, dc) shape.parent.unselected(dc) for obj in canvas.selected: if shape == obj: idx = canvas.selected.index(obj) del canvas.selected[idx] canvas.Redraw(dc) # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3164  canvas.lineFrom = None
3165  shape.Select(False, dc)
3166  shape.parent.unselected(dc)
3167  for obj in canvas.selected:
3168  if shape == obj:
3169  idx = canvas.selected.index(obj)
3170  del canvas.selected[idx]
3171  canvas.Redraw(dc)
3172  # イベントで呼び出された図形が未選択の場合 else: # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3173  else:
3174  # 選択状態へ移行 canvas.lineFrom = None redraw = False shapeList = canvas.GetDiagram().GetShapeList() shape.Select(True, dc) shape.parent.selected() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) canvas.selected.append(shape) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ if self.dragOn == 1: shape = self.GetShape() # self.base_OnEndDragLeft(x, y, keys, attachment) canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) movex = x - shape.lastx movey = y - shape.lasty # 選択状態の全図形を移動 for obj in canvas.selected: # body/inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() if obj.parent.tag != 'line': obj.Select(True, dc) canvas.Redraw(dc) self.dragOn = 0 self.UpdateStatusBar(shape) def OnSizingEndDragLeft(self, pt, x, y, keys, attch): """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ # デフォルトのサイズ変更イベントハンドラ呼び出し self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3175  canvas.lineFrom = None
3176  redraw = False
3177  shapeList = canvas.GetDiagram().GetShapeList()
3178 
3179  shape.Select(True, dc)
3180  shape.parent.selected()
3181 
3182  if canvas.selected and keys != 1:
3183  for s in canvas.selected:
3184  s.Select(False, dc)
3185  s.parent.unselected(dc)
3186  canvas.selected = []
3187  canvas.Redraw(dc)
3188 
3189  canvas.selected.append(shape)
3190 
3191  self.UpdateStatusBar(shape)
3192 
3193 
3194  def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
3195  """ドラッグ終了時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3196  選択状態の全図形を移動
3197 
3198  [引数]
3199  x -- イベント時のx座標
3200  y -- イベント時のy座標
3201  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3202  attachment -- アタッチメント(未使用) [戻り値] void
3203 
3204  [戻り値]
3205  void
3206  """
3207  if self.dragOn == 1:
3208  shape = self.GetShape()
3209 # self.base_OnEndDragLeft(x, y, keys, attachment)
3210 
3211  canvas = shape.GetCanvas()
3212  dc = wx.ClientDC(canvas)
3213  canvas.PrepareDC(dc)
3214 
3215  movex = x - shape.lastx
3216  movey = y - shape.lasty
3217  # 選択状態の全図形を移動
3218  for obj in canvas.selected:
3219 
3220  # body/inport/outport
3221  obj.parent.dmove(dc,movex,movey)
3222 
3223  obj.lastx = obj.GetX()
3224  obj.lasty = obj.GetY()
3225 
3226  if obj.parent.tag != 'line':
3227  obj.Select(True, dc)
3228 
3229  canvas.Redraw(dc)
3230  self.dragOn = 0
3231 
3232  self.UpdateStatusBar(shape)
3233 
3234  def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
3235  """サイズ変更終了時に呼ばれるイベントハンドラ [引数] pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3236 
3237  [引数]
3238  pt -- コントロールポイント x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3239  x -- イベント時のx座標
3240  y -- イベント時のy座標
3241  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3242  attachment -- アタッチメント(未使用) [戻り値] void
3243 
3244  [戻り値]
3245  void
3246  """
3247  # デフォルトのサイズ変更イベントハンドラ呼び出し
3248  self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
3249 
3250  shape = self.GetShape()
3251  canvas = shape.GetCanvas()
3252  dc = wx.ClientDC(canvas)
3253  canvas.PrepareDC(dc)
3254  # サイズ変更時のWidth,Heightの比率算出 width, height = shape.GetBoundingBoxMax() ratioW = width / shape.parent.lastBBoxWidth ratioH = height / shape.parent.lastBBoxHeight tmpx,tmpy = shape.GetX(), shape.GetY() # サイズ変更 shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH) self.UpdateStatusBar(shape) canvas.Redraw(dc) shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax() def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() if self.dragOn == 1: if shape not in canvas.selected: pass else: width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) # self.base_OnDragLeft(1, x, y, keys, attachment) # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示 dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # 選択済みの図形を移動 movex = x - shape.lastx movey = y - shape.lasty for obj in canvas.selected: obj.DeleteControlPoints() # inport/outport obj.parent.dmove(dc,movex,movey) obj.lastx = obj.GetX() obj.lasty = obj.GetY() canvas.Redraw(dc) def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) if shape not in canvas.selected: shape.DeleteControlPoints() if canvas.selected and keys != 1: for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) shape.Select(True, dc) shape.parent.selected() canvas.selected.append(shape) else: for s in canvas.selected: if s.parent.tag == 'line': s.Select(False, dc) s.parent.unselected(dc) idx = canvas.selected.index(s) del canvas.selected[idx] canvas.Redraw(dc) self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) # self.base_OnBeginDragLeft(x, y, keys, attachment) self.dragOn = 1 #---------------------------------------------------------------------- class MyPortEvtHandler(ogl.ShapeEvtHandler): """ポートのイベントクラス""" def __init__(self, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void """ ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame self.dragOn = 0 def UpdateStatusBar(self, shape): """ステータスバーへ表示する情報の更新 [引数] shape -- 図形のオブジェクトを指定 [戻り値] void """ x,y = shape.GetX(), shape.GetY() width, height = shape.GetBoundingBoxMax() self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" % (x, y, width, height)) def OnLeftClick(self, x, y, keys = 0, attachment = 0): """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() # print shape.__class__, shape.GetClassName() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom == None: canvas.lineFrom = shape elif canvas.lineFrom != shape: if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if shape.parent.tag != checktag: return if shape.parent.fullpath == canvas.lineFrom.parent.fullpath: return canvas.lineTo = shape line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) self.UpdateStatusBar(shape) def OnEndDragLeft(self, x, y, keys = 0, attachment = 0): """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : except_mess("except error:") ref = None if not ref: return if self.dragOn == 1: # shape.parent.parent.blink.Stop() self.dragOn = 0 canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.moveLine.removeWidget(dc) canvas.Redraw(dc) tmpShape = canvas.FindShape(x,y) if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"): return ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None if shape.parent.fullpath == tmpShape[0].parent.fullpath: ref = None except : except_mess("except error:") ref = None if not ref: return if canvas.lineFrom.parent.tag == 'in': checktag = 'out' else: checktag = 'in' if tmpShape[0].parent.tag == checktag: canvas.lineTo = tmpShape[0] line = GRtcLine(canvas,shape.parent) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) else: pass def OnDragLeft(self, draw, x, y, keys, attachment): """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ shape = self.GetShape() if self.dragOn == 1: canvas = shape.GetCanvas() dc = getBufferedDC(canvas) canvas.PrepareDC(dc) # create line canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) canvas.Redraw(dc) else: pass def OnBeginDragLeft(self, x, y, keys, attachment): """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void """ self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) self.dragOn = 1 shape = self.GetShape() ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath) try: ref = ref._narrow(RTM.RTCBase) tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath) if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: ref = None except : ref = None except_mess("except error:") if ref: canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) canvas.lineFrom = shape # make line canvas.moveLine = GRtcLine(canvas, shape.parent) canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y) canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1)) canvas.moveLine.lines[0].Show(True) # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active') # shape.parent.parent.blink.Start(500) else: self.dragOn = 0 #---------------------------------------------------------------------- class RtdSystemDraw(ogl.ShapeCanvas): """図形描画用のキャンバス生成クラス""" def __init__(self, parent, log, frame): """クラスの初期化 [引数] log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void """ ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.x_size = maxWidth self.y_size = maxHeight self.log = log self.frame = frame self.SetBackgroundColour(wx.WHITE) self.diagram = ogl.Diagram() self.save_gdi = [] self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.tooltip = None self.rtc_dict = {} self.rtc_list = [] canvas = self.diagram.GetCanvas() canvas.lineFrom = None canvas.lineTo = None canvas.line_idx = 0 canvas.line = {} canvas.moveLine = None canvas.selected = [] canvas.viewMode = False rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHITE", wx.SOLID) # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3255  width, height = shape.GetBoundingBoxMax()
3256  ratioW = width / shape.parent.lastBBoxWidth
3257  ratioH = height / shape.parent.lastBBoxHeight
3258  tmpx,tmpy = shape.GetX(), shape.GetY()
3259  # サイズ変更
3260  shape.parent.updatePolygonSize(tmpx,tmpy,ratioW,ratioH)
3261  self.UpdateStatusBar(shape)
3262  canvas.Redraw(dc)
3263  shape.parent.lastBBoxWidth, shape.parent.lastBBoxHeight = shape.GetBoundingBoxMax()
3264 
3265  def OnDragLeft(self, draw, x, y, keys, attachment):
3266  """ドラッグ時に呼ばれるイベントハンドラ 選択状態の全図形を移動 [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3267  選択状態の全図形を移動
3268 
3269  [引数]
3270  x -- イベント時のx座標
3271  y -- イベント時のy座標
3272  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3273  attachment -- アタッチメント(未使用) [戻り値] void
3274 
3275  [戻り値]
3276  void
3277  """
3278  shape = self.GetShape()
3279  canvas = shape.GetCanvas()
3280  if self.dragOn == 1:
3281  if shape not in canvas.selected:
3282  pass
3283  else:
3284  width, height = shape.GetBoundingBoxMax()
3285  self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" %
3286  (x, y, width, height))
3287 # self.base_OnDragLeft(1, x, y, keys, attachment)
3288 
3289  # メモリDC(BufferedDC)の生成:メモリ上に絵を描いて、Redrawdeで表に表示
3290  dc = getBufferedDC(canvas)
3291  canvas.PrepareDC(dc)
3292 
3293  # 選択済みの図形を移動
3294  movex = x - shape.lastx
3295  movey = y - shape.lasty
3296  for obj in canvas.selected:
3297  obj.DeleteControlPoints()
3298  # inport/outport
3299  obj.parent.dmove(dc,movex,movey)
3300 
3301  obj.lastx = obj.GetX()
3302  obj.lasty = obj.GetY()
3303 
3304  canvas.Redraw(dc)
3305 
3306  def OnBeginDragLeft(self, x, y, keys, attachment):
3307  """ドラッグ開始時に呼ばれるイベントハンドラ [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3308 
3309  [引数]
3310  x -- イベント時のx座標
3311  y -- イベント時のy座標
3312  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3313  attachment -- アタッチメント(未使用) [戻り値] void
3314 
3315  [戻り値]
3316  void
3317  """
3318  shape = self.GetShape()
3319  canvas = shape.GetCanvas()
3320  dc = wx.ClientDC(canvas)
3321  canvas.PrepareDC(dc)
3322  if shape not in canvas.selected:
3323  shape.DeleteControlPoints()
3324 
3325  if canvas.selected and keys != 1:
3326  for s in canvas.selected:
3327  s.Select(False, dc)
3328  s.parent.unselected(dc)
3329  canvas.selected = []
3330  canvas.Redraw(dc)
3331 
3332  shape.Select(True, dc)
3333  shape.parent.selected()
3334  canvas.selected.append(shape)
3335 
3336  else:
3337  for s in canvas.selected:
3338  if s.parent.tag == 'line':
3339  s.Select(False, dc)
3340  s.parent.unselected(dc)
3341  idx = canvas.selected.index(s)
3342  del canvas.selected[idx]
3343  canvas.Redraw(dc)
3344 
3345  self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
3346 # self.base_OnBeginDragLeft(x, y, keys, attachment)
3347  self.dragOn = 1
3348 
3349 #----------------------------------------------------------------------
3350 
3351 class MyPortEvtHandler(ogl.ShapeEvtHandler):
3352  """ポートのイベントクラス"""
3353  def __init__(self, log, frame):
3354  """クラスの初期化
3355 
3356  [引数]
3357  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3358  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3359  ※上記引数は、demoプログラムの名残:削除可 [戻り値] void
3360 
3361  [戻り値]
3362  void
3363  """
3364  ogl.ShapeEvtHandler.__init__(self)
3365  self.log = log
3366  self.statbarFrame = frame
3367  self.dragOn = 0
3368 
3369  def UpdateStatusBar(self, shape):
3370  """ステータスバーへ表示する情報の更新
3371 
3372  [引数]
3373  shape -- 図形のオブジェクトを指定 [戻り値] void
3374 
3375  [戻り値]
3376  void
3377  """
3378  x,y = shape.GetX(), shape.GetY()
3379  width, height = shape.GetBoundingBoxMax()
3380  self.statbarFrame.SetStatusText("Pos: (%d,%d) Size: (%d, %d)" %
3381  (x, y, width, height))
3382 
3383 
3384  def OnLeftClick(self, x, y, keys = 0, attachment = 0):
3385  """マウス左クリック時に呼ばれるイベントハンドラ 線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3386  線を引く為の、開始点or終了点を設定 終了点を設定後は、2点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3387  終了点を設定後は、2点間で線を引く
3388 
3389  [引数]
3390  x -- イベント時のx座標
3391  y -- イベント時のy座標
3392  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3393  attachment -- アタッチメント(未使用) [戻り値] void
3394 
3395  [戻り値]
3396  void
3397  """
3398  shape = self.GetShape()
3399 # print shape.__class__, shape.GetClassName()
3400  canvas = shape.GetCanvas()
3401  dc = wx.ClientDC(canvas)
3402  canvas.PrepareDC(dc)
3403  ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath)
3404  try:
3405  ref = ref._narrow(RTM.RTCBase)
3406  tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath)
3407  if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0:
3408  ref = None
3409  except :
3410  except_mess("except error:")
3411  ref = None
3412 
3413  if not ref:
3414  return
3415 
3416  if canvas.lineFrom == None:
3417  canvas.lineFrom = shape
3418  elif canvas.lineFrom != shape:
3419  if canvas.lineFrom.parent.tag == 'in':
3420  checktag = 'out'
3421  else:
3422  checktag = 'in'
3423  if shape.parent.tag != checktag:
3424  return
3425  if shape.parent.fullpath == canvas.lineFrom.parent.fullpath:
3426  return
3427 
3428  canvas.lineTo = shape
3429  line = GRtcLine(canvas,shape.parent)
3430  line.setLine2port(canvas, dc)
3431  line.g_outp.connect(line.idx, line.g_outp.subscription_type)
3432 
3433  canvas.lineFrom = None
3434  canvas.lineTo = None
3435  canvas.Redraw(dc)
3436 
3437  self.UpdateStatusBar(shape)
3438 
3439 
3440  def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
3441  """ドラッグ終了時に呼ばれるイベントハンドラ ポート上にマウスカーソルがあれば線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3442  ポート上にマウスカーソルがあれば線を引く
3443 
3444  [引数]
3445  x -- イベント時のx座標
3446  y -- イベント時のy座標
3447  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3448  attachment -- アタッチメント(未使用) [戻り値] void
3449 
3450  [戻り値]
3451  void
3452  """
3453  shape = self.GetShape()
3454  ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath)
3455  try:
3456  ref = ref._narrow(RTM.RTCBase)
3457  tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath)
3458  if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0:
3459  ref = None
3460  except :
3461  except_mess("except error:")
3462  ref = None
3463  if not ref:
3464  return
3465 
3466  if self.dragOn == 1:
3467 # shape.parent.parent.blink.Stop()
3468  self.dragOn = 0
3469  canvas = shape.GetCanvas()
3470  dc = wx.ClientDC(canvas)
3471  canvas.PrepareDC(dc)
3472  canvas.moveLine.removeWidget(dc)
3473  canvas.Redraw(dc)
3474  tmpShape = canvas.FindShape(x,y)
3475  if tmpShape == 0 or not hasattr(tmpShape[0], "parent") or not hasattr(tmpShape[0].parent, "ns_dict"):
3476  return
3477  ref = tmpShape[0].parent.ns_dict.GetObjRefToFullpath(tmpShape[0].parent.fullpath)
3478  try:
3479  ref = ref._narrow(RTM.RTCBase)
3480  tmp = tmpShape[0].parent.ns_dict.GetCompState(tmpShape[0].parent.fullpath)
3481  if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0:
3482  ref = None
3483  if shape.parent.fullpath == tmpShape[0].parent.fullpath:
3484  ref = None
3485  except :
3486  except_mess("except error:")
3487  ref = None
3488  if not ref:
3489  return
3490 
3491  if canvas.lineFrom.parent.tag == 'in':
3492  checktag = 'out'
3493  else:
3494  checktag = 'in'
3495  if tmpShape[0].parent.tag == checktag:
3496  canvas.lineTo = tmpShape[0]
3497  line = GRtcLine(canvas,shape.parent)
3498  line.setLine2port(canvas, dc)
3499  line.g_outp.connect(line.idx, line.g_outp.subscription_type)
3500 
3501  canvas.lineFrom = None
3502  canvas.lineTo = None
3503  canvas.Redraw(dc)
3504  else:
3505  pass
3506 
3507  def OnDragLeft(self, draw, x, y, keys, attachment):
3508  """ドラッグ時に呼ばれるイベントハンドラ マウスカーソルと始点間で線を引く [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3509  マウスカーソルと始点間で線を引く
3510 
3511  [引数]
3512  x -- イベント時のx座標
3513  y -- イベント時のy座標
3514  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3515  attachment -- アタッチメント(未使用) [戻り値] void
3516 
3517  [戻り値]
3518  void
3519  """
3520  shape = self.GetShape()
3521  if self.dragOn == 1:
3522  canvas = shape.GetCanvas()
3523  dc = getBufferedDC(canvas)
3524  canvas.PrepareDC(dc)
3525 
3526  # create line
3527  canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y)
3528  canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1))
3529  canvas.moveLine.lines[0].Show(True)
3530  canvas.Redraw(dc)
3531  else:
3532  pass
3533 
3534  def OnBeginDragLeft(self, x, y, keys, attachment):
3535  """ドラッグ開始時に呼ばれるイベントハンドラ ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3536  ドラッグによる線引き処理の開始(オブジェクトリファレンスが存在する場合) [引数] x -- イベント時のx座標 y -- イベント時のy座標 keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3537 
3538  [引数]
3539  x -- イベント時のx座標
3540  y -- イベント時のy座標
3541  keys -- キー押下状態(SHIFT、CTRL) attachment -- アタッチメント(未使用) [戻り値] void
3542  attachment -- アタッチメント(未使用) [戻り値] void
3543 
3544  [戻り値]
3545  void
3546  """
3547  self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys))
3548  self.dragOn = 1
3549  shape = self.GetShape()
3550  ref = shape.parent.ns_dict.GetObjRefToFullpath(shape.parent.fullpath)
3551  try:
3552  ref = ref._narrow(RTM.RTCBase)
3553  tmp = shape.parent.ns_dict.GetCompState(shape.parent.fullpath)
3554  if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0:
3555  ref = None
3556  except :
3557  ref = None
3558  except_mess("except error:")
3559  if ref:
3560  canvas = shape.GetCanvas()
3561  dc = wx.ClientDC(canvas)
3562  canvas.PrepareDC(dc)
3563  canvas.lineFrom = shape
3564  # make line
3565  canvas.moveLine = GRtcLine(canvas, shape.parent)
3566  canvas.moveLine.setPoints(shape.GetX(), shape.GetY(), x, y)
3567  canvas.moveLine.lines[0].SetPen(wx.Pen(SELECTED_COLOR, 1))
3568  canvas.moveLine.lines[0].Show(True)
3569 # shape.parent.parent.blink.setBlinkState(shape.parent.parent, 'inactive', 'active')
3570 # shape.parent.parent.blink.Start(500)
3571  else:
3572  self.dragOn = 0
3573 
3574 
3575 #----------------------------------------------------------------------
3576 
3577 class RtdSystemDraw(ogl.ShapeCanvas):
3578  """図形描画用のキャンバス生成クラス"""
3579  def __init__(self, parent, log, frame):
3580  """クラスの初期化
3581 
3582  [引数]
3583  log -- ログ出力クラスのオブジェクト frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void
3584  frame -- ステータスバーのオブジェクト ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void
3585  ※上記引数は、demoプログラムの名残:削除可 parent -- 親ウィンドウを指定 [戻り値] void
3586  parent -- 親ウィンドウを指定 [戻り値] void
3587 
3588  [戻り値]
3589  void
3590  """
3591  ogl.ShapeCanvas.__init__(self, parent)
3592 
3593  maxWidth = 1000
3594  maxHeight = 1000
3595 # self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
3596 
3597  self.x_size = maxWidth
3598  self.y_size = maxHeight
3599  self.log = log
3600  self.frame = frame
3601  self.SetBackgroundColour(wx.WHITE)
3602  self.diagram = ogl.Diagram()
3603  self.save_gdi = []
3604  self.SetDiagram(self.diagram)
3605  self.diagram.SetCanvas(self)
3606  self.tooltip = None
3607  self.rtc_dict = {}
3608  self.rtc_list = []
3609  canvas = self.diagram.GetCanvas()
3610  canvas.lineFrom = None
3611  canvas.lineTo = None
3612  canvas.line_idx = 0
3613  canvas.line = {}
3614  canvas.moveLine = None
3615  canvas.selected = []
3616  canvas.viewMode = False
3617 
3618  rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID)
3619  dsBrush = wx.Brush("WHITE", wx.SOLID)
3620 
3621  # ドラッグ&ドロップ:ドロップターゲットの設定 dt = MyTextDropTarget(self, log) self.SetDropTarget(dt) # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3622  dt = MyTextDropTarget(self, log)
3623  self.SetDropTarget(dt)
3624 
3625  # イベントの割付 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) def changeCompColor(self, fullname, state) : """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void """ if fullname in self.rtc_list: # self.rtc_dict[fullname].refresh() self.rtc_dict[fullname].changeBodyColor(state) self.rtc_dict[fullname].state = state def search_g_inp(self, inp_ref) : """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー """ print "len rtc_list:",len(self.rtc_list) for rtc_name in self.rtc_list : g_rtc = self.rtc_dict[rtc_name] ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath) if ref : print "len in_list:",len(g_rtc.in_list) for inp in g_rtc.in_list : print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref'] if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) : print "_is_equivalent is OK!!!" return g_rtc.in_dict[inp['name']] def openFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.OPEN) if dialog.ShowModal() != wx.ID_OK: return None openFileName = dialog.GetPath() dialog.Destroy() return openFileName def loadXML(self): if len(self.rtc_dict) > 0: ret = self.askDialog(strDEL_SYS) if ret != wx.ID_OK: return openFileName = self.openFileDialog() print "open file is :",openFileName if openFileName == None: return # delete self.deleteAllShape() rtxml = RtmParser.RtmParser() dict = rtxml.readXML(openFileName) canvas = self.diagram.GetCanvas() canvas.viewMode = True self.createGRtc_from_dict(dict) def saveFileDialog(self): wildcard = "*.xml |*.xml| *.* |*.*" dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.SAVE) if dialog.ShowModal() != wx.ID_OK: return None saveFileName = dialog.GetPath() dialog.Destroy() return saveFileName def makeDumpData(self): canvas = self.diagram.GetCanvas() dict = {} dict['rtc'] = {} dict['line'] = [] for fullname in self.rtc_list: comp = self.rtc_dict[fullname] name = fullname x_size, y_size = comp.baseBox.GetBoundingBoxMin() if comp.lastRot == 'TB': y_size, x_size = x_size, y_size x = comp.baseBox.GetX() - x_size/2 y = comp.baseBox.GetY() - y_size/2 # print "Comp name:",name," x=",x," y=",y dict['rtc'][name] = {} dict['rtc'][name]['x'] = x dict['rtc'][name]['y'] = y if comp.lastRot == 'LR': if comp.revTogle == 1: dict['rtc'][name]['rot'] = 'Right' else: dict['rtc'][name]['rot'] = 'Left' else: if comp.rotTogle == 1: dict['rtc'][name]['rot'] = 'Top' else: dict['rtc'][name]['rot'] = 'Bottom' # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body # comp.revTogle # 1 or 0 # 1 :inport's is right side of body # comp.lastRot # LR(Left/Right) or TB(Top/Bottom) for line_idx in canvas.line: out_obj = canvas.line[line_idx].g_outp in_obj = canvas.line[line_idx].g_inp tmp = {} # tmp['type'] = tmp['pos'] = canvas.line[line_idx].coordT tmp['in-comp'] = in_obj.fullpath tmp['in-name'] = in_obj.inport['name'] tmp['out-comp'] = out_obj.fullpath tmp['out-name'] = out_obj.outport['name'] dict['line'].append(tmp) return dict def saveXML(self, saveFileName): dict = {} dict = self.makeDumpData() rtxml = RtmParser.RtmParser() rtxml.writeXML(saveFileName, dict) def saveAsXML(self): saveFileName = self.saveFileDialog() if saveFileName == None: return self.saveXML(saveFileName) def refresh(self): """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) for obj in canvas.selected: obj.Select(False, dc) obj.parent.unselected(dc) canvas.selected = [] for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh() for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].refresh_outp() def reConnect(self): """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void """ # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].reConnectLine() def remakeLines(self): # assembly dummy process # return # assembly dummy process for rtc_name in self.rtc_list: self.rtc_dict[rtc_name].remakeLines() def createGRtc_from_dict(self,dict): """ディクショナリーからコンポーネント図形を生成 [引数] dict -- アセンブリのディクショナリー [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) rtc_list = dict['rtc'].keys() self.rtc_dict = {} new_list = [] pos_x = 0 pos_y = 0 for rtc_name in rtc_list: # obj-ref error check try: ref = self.frame.myDict.GetObjRefToFullpath(rtc_name) if ref == None: print 'Component Create error!: %s'%rtc_name continue ref = ref._narrow(RTM.RTCBase) tmp = self.frame.myDict.GetCompState(rtc_name) # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0: # ref = None except: err_mess = 'Component Create error:%s\n'%rtc_name except_mess(err_mess) continue new_list.append(rtc_name) pos_x = dict['rtc'][rtc_name]['x'] pos_y = dict['rtc'][rtc_name]['y'] comp = GRtc(self, rtc_name, pos_x, pos_y) comp.changeBodyColor('virtual') self.rtc_dict[rtc_name] = comp if dict['rtc'][rtc_name]['rot'] == 'Left': comp.reversesBody() elif dict['rtc'][rtc_name]['rot'] == 'Top': comp.rotatesBody() elif dict['rtc'][rtc_name]['rot'] == 'Bottom': comp.rotatesBody() comp.rotatesBody() comp.refresh() if len(new_list) == 0: canvas.viewMode = False return self.rtc_list = new_list for line_num in range(len(dict['line'])): line_dict = dict['line'][line_num] out_comp_name = line_dict['out-comp'] out_name = line_dict['out-name'] in_comp_name = line_dict['in-comp'] in_name = line_dict['in-name'] #error check if not self.rtc_dict.has_key(out_comp_name): print 'Assembly Check: Port Connection Error!:',out_comp_name continue if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name): print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name continue if not self.rtc_dict.has_key(in_comp_name): print 'Assembly Check: Port Connection Error!:',in_comp_name continue if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name): print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name continue outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name] inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name] canvas.lineFrom = outp_obj.body canvas.lineTo = inp_obj.body line = GRtcLine(canvas,outp_obj) line.setLine2port(canvas, dc) line.g_outp.connect(line.idx, line.g_outp.subscription_type) pos = [] pos_list = [] pos_list = string.splitfields(line_dict['pos'],',') for num in range(len(pos_list)/2): pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1]))) #line.move_child line.childMove(dc, pos) canvas.lineFrom = None canvas.lineTo = None canvas.Redraw(dc) def MyAddBmp(self, shape, x, y, pen): """ビットマップ図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) if pen: shape.SetPen(pen) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerBmp(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddOval(self, shape, x, y): """円図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) self.diagram.AddShape(shape) evthandler = MyEvtHandlerOval(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddText(self, shape, x, y, pen, brush=None ): """テキストの登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(False, False) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) self.diagram.AddShape(shape) evthandler = MyEvtHandlerDummy(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) shape.Show(True) return shape def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0): """コンポーネント図形、ポート図形の登録 キャンバス、ダイアグラム、イベントとの関連付け [引数] shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト """ shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) if pen: shape.SetPen(pen) if brush: shape.SetBrush(brush) if text: shape.AddText(text) self.diagram.AddShape(shape) shape.Show(True) if inoutPort == 1: # make in/out port event handler evthandler = MyPortEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) elif inoutPort == 0: # make body event handler evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) return shape def OnDestroy(self, evt): """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void """ # Do some cleanup for shape in self.diagram.GetShapeList(): if shape.GetParent() == None: shape.SetCanvas(None) shape.Destroy() self.diagram.Destroy() def deleteShape(self,obj): """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) obj.parent.removeWidget(dc) if hasattr(obj, "parent") and obj.parent.tag == 'body': rtc_name = obj.parent.fullpath if rtc_name in self.rtc_list: tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] del self.rtc_dict[rtc_name] if hasattr(obj, "parent") and obj.parent.tag == 'line': idx = obj.parent.idx if idx in canvas.line.keys(): del canvas.line[idx] del obj def deleteAllShape(self): """すべての図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) shapeList = canvas.GetDiagram().GetShapeList() for obj in shapeList: self.deleteShape(obj) canvas.selected = [] canvas.line = {} canvas.Redraw(dc) def deleteSelectedShape(self): """選択中の図形を削除する [引数] なし [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for obj in canvas.selected: self.deleteShape(obj) canvas.selected = [] bdc = getBufferedDC(canvas) canvas.PrepareDC(dc) canvas.Redraw(dc) def OnKeyDown(self, evt): """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void """ evtKey = evt.GetKeyCode() # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
3626  self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
3627  self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
3628  self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
3629  self.Bind(wx.EVT_MIDDLE_DOWN, self.OnMiddleDown)
3630  self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
3631  self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
3632 
3633  def changeCompColor(self, fullname, state) :
3634  """コンポーネント単体の色を変更(rtc_state()参照) [引数] fullname -- コンポーネントのフルパス名 [戻り値] void
3635 
3636  [引数]
3637  fullname -- コンポーネントのフルパス名
3638 
3639  [戻り値]
3640  void
3641  """
3642  if fullname in self.rtc_list:
3643 # self.rtc_dict[fullname].refresh()
3644  self.rtc_dict[fullname].changeBodyColor(state)
3645  self.rtc_dict[fullname].state = state
3646 
3647  def search_g_inp(self, inp_ref) :
3648  """インポートの検索 [引数] inp_ref -- インポートのオブジェクトリファレンス [戻り値] g_inp -- インポートのディクショナリー
3649 
3650  [引数]
3651  inp_ref -- インポートのオブジェクトリファレンス
3652 
3653  [戻り値]
3654  g_inp -- インポートのディクショナリー
3655  """
3656  print "len rtc_list:",len(self.rtc_list)
3657  for rtc_name in self.rtc_list :
3658  g_rtc = self.rtc_dict[rtc_name]
3659  ref = g_rtc.ns_dict.GetObjRefToFullpath(g_rtc.fullpath)
3660  if ref :
3661  print "len in_list:",len(g_rtc.in_list)
3662  for inp in g_rtc.in_list :
3663  print "inp_ref:",inp_ref, " == ", g_rtc.in_dict[inp['name']].inport['ref']
3664  if inp_ref._is_equivalent(g_rtc.in_dict[inp['name']].inport['ref']) :
3665  print "_is_equivalent is OK!!!"
3666  return g_rtc.in_dict[inp['name']]
3667 
3668  def openFileDialog(self):
3669  wildcard = "*.xml |*.xml| *.* |*.*"
3670  dialog = wx.FileDialog( self, strOPEN_TITLE, defaultDir=os.getcwd(),
3671  defaultFile="", wildcard=wildcard, style=wx.OPEN)
3672 
3673  if dialog.ShowModal() != wx.ID_OK:
3674  return None
3675 
3676  openFileName = dialog.GetPath()
3677  dialog.Destroy()
3678  return openFileName
3679 
3680  def loadXML(self):
3681  if len(self.rtc_dict) > 0:
3682  ret = self.askDialog(strDEL_SYS)
3683  if ret != wx.ID_OK:
3684  return
3685 
3686  openFileName = self.openFileDialog()
3687  print "open file is :",openFileName
3688  if openFileName == None:
3689  return
3690 
3691  # delete
3692  self.deleteAllShape()
3693 
3694  rtxml = RtmParser.RtmParser()
3695  dict = rtxml.readXML(openFileName)
3696 
3697  canvas = self.diagram.GetCanvas()
3698  canvas.viewMode = True
3699  self.createGRtc_from_dict(dict)
3700 
3701  def saveFileDialog(self):
3702  wildcard = "*.xml |*.xml| *.* |*.*"
3703  dialog = wx.FileDialog( self, strSAVE_AS_TITLE, defaultDir=os.getcwd(),
3704  defaultFile="", wildcard=wildcard, style=wx.SAVE)
3705 
3706  if dialog.ShowModal() != wx.ID_OK:
3707  return None
3708 
3709  saveFileName = dialog.GetPath()
3710  dialog.Destroy()
3711  return saveFileName
3712 
3713  def makeDumpData(self):
3714  canvas = self.diagram.GetCanvas()
3715 
3716  dict = {}
3717  dict['rtc'] = {}
3718  dict['line'] = []
3719  for fullname in self.rtc_list:
3720  comp = self.rtc_dict[fullname]
3721  name = fullname
3722 
3723  x_size, y_size = comp.baseBox.GetBoundingBoxMin()
3724  if comp.lastRot == 'TB':
3725  y_size, x_size = x_size, y_size
3726 
3727  x = comp.baseBox.GetX() - x_size/2
3728  y = comp.baseBox.GetY() - y_size/2
3729 # print "Comp name:",name," x=",x," y=",y
3730  dict['rtc'][name] = {}
3731  dict['rtc'][name]['x'] = x
3732  dict['rtc'][name]['y'] = y
3733 
3734  if comp.lastRot == 'LR':
3735  if comp.revTogle == 1:
3736  dict['rtc'][name]['rot'] = 'Right'
3737  else:
3738  dict['rtc'][name]['rot'] = 'Left'
3739  else:
3740  if comp.rotTogle == 1:
3741  dict['rtc'][name]['rot'] = 'Top'
3742  else:
3743  dict['rtc'][name]['rot'] = 'Bottom'
3744 
3745 # comp.rotTogle # 1 or 0 # 1 :inport's is top side of body
3746 # comp.revTogle # 1 or 0 # 1 :inport's is right side of body
3747 # comp.lastRot # LR(Left/Right) or TB(Top/Bottom)
3748 
3749  for line_idx in canvas.line:
3750  out_obj = canvas.line[line_idx].g_outp
3751  in_obj = canvas.line[line_idx].g_inp
3752  tmp = {}
3753 # tmp['type'] =
3754 
3755  tmp['pos'] = canvas.line[line_idx].coordT
3756  tmp['in-comp'] = in_obj.fullpath
3757  tmp['in-name'] = in_obj.inport['name']
3758  tmp['out-comp'] = out_obj.fullpath
3759  tmp['out-name'] = out_obj.outport['name']
3760  dict['line'].append(tmp)
3761 
3762  return dict
3763 
3764  def saveXML(self, saveFileName):
3765 
3766  dict = {}
3767  dict = self.makeDumpData()
3768 
3769  rtxml = RtmParser.RtmParser()
3770 
3771  rtxml.writeXML(saveFileName, dict)
3772 
3773  def saveAsXML(self):
3774  saveFileName = self.saveFileDialog()
3775  if saveFileName == None:
3776  return
3777 
3778  self.saveXML(saveFileName)
3779 
3780  def refresh(self):
3781  """リフレッシュ処理 コンポーネント及び、表示図形のリフレッシュを行う [引数] なし [戻り値] void
3782  コンポーネント及び、表示図形のリフレッシュを行う
3783 
3784  [引数]
3785  なし
3786 
3787  [戻り値]
3788  void
3789  """
3790  canvas = self.diagram.GetCanvas()
3791  dc = wx.ClientDC(canvas)
3792  canvas.PrepareDC(dc)
3793  for obj in canvas.selected:
3794  obj.Select(False, dc)
3795  obj.parent.unselected(dc)
3796  canvas.selected = []
3797  for rtc_name in self.rtc_list:
3798  self.rtc_dict[rtc_name].refresh()
3799  for rtc_name in self.rtc_list:
3800  self.rtc_dict[rtc_name].refresh_outp()
3801 
3802  def reConnect(self):
3803  """再接続処理 画面上のコンポーネントの再接続処理を呼び出す [引数] なし [戻り値] void
3804  画面上のコンポーネントの再接続処理を呼び出す
3805 
3806  [引数]
3807  なし
3808 
3809  [戻り値]
3810  void
3811  """
3812 # assembly dummy process
3813 # return
3814 # assembly dummy process
3815  for rtc_name in self.rtc_list:
3816  self.rtc_dict[rtc_name].reConnectLine()
3817 
3818  def remakeLines(self):
3819 # assembly dummy process
3820 # return
3821 # assembly dummy process
3822  for rtc_name in self.rtc_list:
3823  self.rtc_dict[rtc_name].remakeLines()
3824 
3825  def createGRtc_from_dict(self,dict):
3826  """ディクショナリーからコンポーネント図形を生成
3827 
3828  [引数]
3829  dict -- アセンブリのディクショナリー
3830 
3831  [戻り値]
3832  void
3833  """
3834  canvas = self.diagram.GetCanvas()
3835  dc = wx.ClientDC(canvas)
3836  canvas.PrepareDC(dc)
3837 
3838  rtc_list = dict['rtc'].keys()
3839  self.rtc_dict = {}
3840  new_list = []
3841  pos_x = 0
3842  pos_y = 0
3843  for rtc_name in rtc_list:
3844 
3845  # obj-ref error check
3846  try:
3847  ref = self.frame.myDict.GetObjRefToFullpath(rtc_name)
3848  if ref == None:
3849  print 'Component Create error!: %s'%rtc_name
3850  continue
3851  ref = ref._narrow(RTM.RTCBase)
3852  tmp = self.frame.myDict.GetCompState(rtc_name)
3853 # if tmp >= RTM.RTComponent.RTC_ABORTING or tmp == 0:
3854 # ref = None
3855  except:
3856  err_mess = 'Component Create error:%s\n'%rtc_name
3857  except_mess(err_mess)
3858  continue
3859 
3860  new_list.append(rtc_name)
3861 
3862  pos_x = dict['rtc'][rtc_name]['x']
3863  pos_y = dict['rtc'][rtc_name]['y']
3864  comp = GRtc(self, rtc_name, pos_x, pos_y)
3865  comp.changeBodyColor('virtual')
3866  self.rtc_dict[rtc_name] = comp
3867 
3868  if dict['rtc'][rtc_name]['rot'] == 'Left':
3869  comp.reversesBody()
3870  elif dict['rtc'][rtc_name]['rot'] == 'Top':
3871  comp.rotatesBody()
3872  elif dict['rtc'][rtc_name]['rot'] == 'Bottom':
3873  comp.rotatesBody()
3874  comp.rotatesBody()
3875 
3876  comp.refresh()
3877 
3878  if len(new_list) == 0:
3879  canvas.viewMode = False
3880  return
3881 
3882  self.rtc_list = new_list
3883 
3884  for line_num in range(len(dict['line'])):
3885  line_dict = dict['line'][line_num]
3886  out_comp_name = line_dict['out-comp']
3887  out_name = line_dict['out-name']
3888 
3889  in_comp_name = line_dict['in-comp']
3890  in_name = line_dict['in-name']
3891 
3892  #error check
3893  if not self.rtc_dict.has_key(out_comp_name):
3894  print 'Assembly Check: Port Connection Error!:',out_comp_name
3895  continue
3896  if not self.rtc_dict[out_comp_name].out_dict.has_key(out_name):
3897  print 'Assembly Check: Port Connection Error!: ',out_comp_name,":",out_name
3898  continue
3899  if not self.rtc_dict.has_key(in_comp_name):
3900  print 'Assembly Check: Port Connection Error!:',in_comp_name
3901  continue
3902  if not self.rtc_dict[in_comp_name].in_dict.has_key(in_name):
3903  print 'Assembly Check: Port Connection Error!: ',in_comp_name,":",in_name
3904  continue
3905 
3906  outp_obj = self.rtc_dict[out_comp_name].out_dict[out_name]
3907  inp_obj = self.rtc_dict[in_comp_name].in_dict[in_name]
3908 
3909  canvas.lineFrom = outp_obj.body
3910  canvas.lineTo = inp_obj.body
3911  line = GRtcLine(canvas,outp_obj)
3912  line.setLine2port(canvas, dc)
3913  line.g_outp.connect(line.idx, line.g_outp.subscription_type)
3914 
3915  pos = []
3916  pos_list = []
3917  pos_list = string.splitfields(line_dict['pos'],',')
3918  for num in range(len(pos_list)/2):
3919  pos.append((string.atof(pos_list[num*2]),string.atof(pos_list[num*2+1])))
3920 
3921  #line.move_child
3922  line.childMove(dc, pos)
3923 
3924  canvas.lineFrom = None
3925  canvas.lineTo = None
3926  canvas.Redraw(dc)
3927 
3928  def MyAddBmp(self, shape, x, y, pen):
3929  """ビットマップ図形の登録
3930  キャンバス、ダイアグラム、イベントとの関連付け
3931 
3932  [引数]
3933  shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト
3934  x -- 表示するx座標
3935  y -- 表示するy座標
3936  pen -- ペン(色、太さ)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト
3937 
3938  [戻り値]
3939  shape -- wx.Shape 図形オブジェクト
3940  """
3941  shape.SetDraggable(False, False)
3942  shape.SetCanvas(self)
3943  if pen: shape.SetPen(pen)
3944  shape.SetX(x)
3945  shape.SetY(y)
3946  self.diagram.AddShape(shape)
3947  evthandler = MyEvtHandlerBmp(self.log, self.frame)
3948  evthandler.SetShape(shape)
3949  evthandler.SetPreviousHandler(shape.GetEventHandler())
3950  shape.SetEventHandler(evthandler)
3951 
3952  shape.Show(True)
3953  return shape
3954 
3955  def MyAddOval(self, shape, x, y):
3956  """円図形の登録
3957  キャンバス、ダイアグラム、イベントとの関連付け
3958 
3959  [引数]
3960  shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 [戻り値] shape -- wx.Shape 図形オブジェクト
3961  x -- 表示するx座標
3962  y -- 表示するy座標
3963 
3964  [戻り値]
3965  shape -- wx.Shape 図形オブジェクト
3966  """
3967  shape.SetDraggable(True, False)
3968  shape.SetCanvas(self)
3969  shape.SetX(x)
3970  shape.SetY(y)
3971  self.diagram.AddShape(shape)
3972  evthandler = MyEvtHandlerOval(self.log, self.frame)
3973  evthandler.SetShape(shape)
3974  evthandler.SetPreviousHandler(shape.GetEventHandler())
3975  shape.SetEventHandler(evthandler)
3976 
3977  shape.Show(True)
3978  return shape
3979 
3980  def MyAddText(self, shape, x, y, pen, brush=None ):
3981  """テキストの登録
3982  キャンバス、ダイアグラム、イベントとの関連付け
3983 
3984  [引数]
3985  shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト
3986  x -- 表示するx座標
3987  y -- 表示するy座標
3988  pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト
3989  burush -- ブラシ(色)を指定 [戻り値] shape -- wx.Shape 図形オブジェクト
3990 
3991  [戻り値]
3992  shape -- wx.Shape 図形オブジェクト
3993  """
3994  shape.SetDraggable(False, False)
3995  shape.SetCanvas(self)
3996  shape.SetX(x)
3997  shape.SetY(y)
3998  if pen: shape.SetPen(pen)
3999  if brush: shape.SetBrush(brush)
4000  self.diagram.AddShape(shape)
4001  evthandler = MyEvtHandlerDummy(self.log, self.frame)
4002  evthandler.SetShape(shape)
4003  evthandler.SetPreviousHandler(shape.GetEventHandler())
4004  shape.SetEventHandler(evthandler)
4005 
4006  shape.Show(True)
4007  return shape
4008 
4009  def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0):
4010  """コンポーネント図形、ポート図形の登録
4011  キャンバス、ダイアグラム、イベントとの関連付け
4012 
4013  [引数]
4014  shape -- ビットマップ図形を指定 x -- 表示するx座標 y -- 表示するy座標 pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト
4015  x -- 表示するx座標
4016  y -- 表示するy座標
4017  pen -- ペン(色、太さ)を指定 burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト
4018  burush -- ブラシ(色)を指定 text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト
4019  text -- 図形に表示する文字列を指定 inoutPort -- ポート指定フラグ 0:コンポーネント本体 / 1:Inpot,Outport [戻り値] shape -- wx.Shape 図形オブジェクト
4020  inoutPort -- ポート指定フラグ
4021  0:コンポーネント本体 / 1:Inpot,Outport
4022 
4023  [戻り値]
4024  shape -- wx.Shape 図形オブジェクト
4025  """
4026  shape.SetDraggable(True, True)
4027  shape.SetCanvas(self)
4028  shape.SetX(x)
4029  shape.SetY(y)
4030  if pen: shape.SetPen(pen)
4031  if brush: shape.SetBrush(brush)
4032  if text: shape.AddText(text)
4033  self.diagram.AddShape(shape)
4034  shape.Show(True)
4035 
4036  if inoutPort == 1: # make in/out port event handler
4037  evthandler = MyPortEvtHandler(self.log, self.frame)
4038  evthandler.SetShape(shape)
4039  evthandler.SetPreviousHandler(shape.GetEventHandler())
4040  shape.SetEventHandler(evthandler)
4041  elif inoutPort == 0: # make body event handler
4042  evthandler = MyEvtHandler(self.log, self.frame)
4043  evthandler.SetShape(shape)
4044  evthandler.SetPreviousHandler(shape.GetEventHandler())
4045  shape.SetEventHandler(evthandler)
4046 
4047  return shape
4048 
4049  def OnDestroy(self, evt):
4050  """ウィンドウ削除イベントハンドラ [引数] evt -- イベント [戻り値] void
4051 
4052  [引数]
4053  evt -- イベント [戻り値] void
4054 
4055  [戻り値]
4056  void
4057  """
4058  # Do some cleanup
4059  for shape in self.diagram.GetShapeList():
4060  if shape.GetParent() == None:
4061  shape.SetCanvas(None)
4062  shape.Destroy()
4063 
4064  self.diagram.Destroy()
4065 
4066  def deleteShape(self,obj):
4067  """図形を削除する [引数] 削除を行うShapeオブジェクト [戻り値] void
4068 
4069  [引数]
4070  削除を行うShapeオブジェクト [戻り値] void
4071 
4072  [戻り値]
4073  void
4074  """
4075  canvas = self.diagram.GetCanvas()
4076  dc = wx.ClientDC(self)
4077  canvas.PrepareDC(dc)
4078  obj.parent.removeWidget(dc)
4079 
4080  if hasattr(obj, "parent") and obj.parent.tag == 'body':
4081  rtc_name = obj.parent.fullpath
4082  if rtc_name in self.rtc_list:
4083  tmp = self.rtc_list.index(rtc_name)
4084  del self.rtc_list[tmp]
4085  del self.rtc_dict[rtc_name]
4086  if hasattr(obj, "parent") and obj.parent.tag == 'line':
4087  idx = obj.parent.idx
4088  if idx in canvas.line.keys():
4089  del canvas.line[idx]
4090 
4091  del obj
4092 
4093  def deleteAllShape(self):
4094  """すべての図形を削除する [引数] なし [戻り値] void
4095 
4096  [引数]
4097  なし
4098 
4099  [戻り値]
4100  void
4101  """
4102  canvas = self.diagram.GetCanvas()
4103  dc = wx.ClientDC(self)
4104  canvas.PrepareDC(dc)
4105 
4106  for s in canvas.selected:
4107  s.Select(False, dc)
4108  s.parent.unselected(dc)
4109 
4110  shapeList = canvas.GetDiagram().GetShapeList()
4111  for obj in shapeList:
4112  self.deleteShape(obj)
4113 
4114  canvas.selected = []
4115  canvas.line = {}
4116 
4117  canvas.Redraw(dc)
4118 
4120  """選択中の図形を削除する [引数] なし [戻り値] void
4121 
4122  [引数]
4123  なし
4124 
4125  [戻り値]
4126  void
4127  """
4128  canvas = self.diagram.GetCanvas()
4129  dc = wx.ClientDC(self)
4130  canvas.PrepareDC(dc)
4131  for obj in canvas.selected:
4132  self.deleteShape(obj)
4133 
4134  canvas.selected = []
4135  bdc = getBufferedDC(canvas)
4136  canvas.PrepareDC(dc)
4137  canvas.Redraw(dc)
4138 
4139 
4140  def OnKeyDown(self, evt):
4141  """キー押下時のイベントハンドラ 選択中の図形を削除する [引数] evt -- イベント [戻り値] void
4142  選択中の図形を削除する [引数] evt -- イベント [戻り値] void
4143 
4144  [引数]
4145  evt -- イベント [戻り値] void
4146 
4147  [戻り値]
4148  void
4149  """
4150  evtKey = evt.GetKeyCode()
4151  # DELETE キーの時、選択されている図形を削除 if evtKey == wx.WXK_DELETE: self.deleteSelectedShape() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) canvas.Redraw(bdc) def OnPopupStart(self, evt): """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_start() def OnPopupStop(self, evt): """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_stop() def OnPopupReset(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_reset() def OnPopupExit(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_exit() def OnPopupKill(self, evt): pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.ref_kill() def OnPopupDelete(self, evt): """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = self.pt tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: tmpShape[0].parent.removeWidget(dc) # rtc_name = tmpShape[0].parent.rtc.ref_key rtc_name = tmpShape[0].parent.fullpath del self.rtc_dict[rtc_name] tmp = self.rtc_list.index(rtc_name) del self.rtc_list[tmp] for obj in canvas.selected: if obj == tmpShape[0]: tmp = canvas.selected.index(tmpShape[0]) del canvas.selected[tmp] bdc = getBufferedDC(canvas) canvas.PrepareDC(bdc) # canvas.Redraw(bdc) canvas.Redraw(dc) def OnPopupSub(self, evt): """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ print "OnPopupSub!!!" def OnPopupDelSelectItem(self, evt): """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteSelectedShape() def OnPopupLoadXML(self, evt): """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.loadXML() def OnPopupSaveDefaultXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ filename = "System%d.xml" % self.frame.drawCurNum self.saveXML(filename) def OnPopupSaveXML(self, evt): """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.saveAsXML() def OnPopupRefresh(self, evt): """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return self.refresh() self.reConnect() def checkOtherConnect(self): ret = False for rtc_name in self.rtc_list: ret = self.rtc_dict[rtc_name].checkOtherConnect() if ret == True: break return ret def askDialog(self, str): """ダイアログの表示機能 ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void """ # yes/no dialog val = wx.ID_OK dlg = RtmDialog(self, -1, str) dlg.CenterOnParent() val = dlg.ShowModal() dlg.Destroy() return val def DelOldConnectAskDialog(self): """ダイアログの表示機能 古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、 ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void """ # assembly dummy # return wx.ID_OK # assembly dummy # yes/no dialog val = wx.ID_OK connect_flag = self.checkOtherConnect() if connect_flag == True: val = askDialog(strASKMESSAGE) return val def OnPopupConnectView(self, evt): """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ canvas = self.diagram.GetCanvas() # yes/no dialog val = self.DelOldConnectAskDialog() if val != wx.ID_OK: return canvas.viewMode = False self.refresh() self.reConnect() def OnPopupDeleteView(self, evt): """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void """ self.deleteAllShape() canvas = self.diagram.GetCanvas() canvas.viewMode = False def makeBodyPopupMenu(self, evt): """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成 コンポーネント図形本体のOn/Off、削除をメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4152  if evtKey == wx.WXK_DELETE:
4153  self.deleteSelectedShape()
4154 
4155  canvas = self.diagram.GetCanvas()
4156  dc = wx.ClientDC(self)
4157  canvas.PrepareDC(dc)
4158  bdc = getBufferedDC(canvas)
4159  canvas.PrepareDC(bdc)
4160  canvas.Redraw(bdc)
4161 
4162  def OnPopupStart(self, evt):
4163  """コンポーネント本体のスタートを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4164 
4165  [引数]
4166  evt -- イベント(wx.CommandEvent)
4167 
4168  [戻り値]
4169  void
4170  """
4171  pt = self.pt
4172  tmpShape = self.FindShape(pt[0],pt[1])
4173  if tmpShape != 0:
4174  tmpShape[0].parent.ref_start()
4175 
4176  def OnPopupStop(self, evt):
4177  """コンポーネント本体のストップを行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4178 
4179  [引数]
4180  evt -- イベント(wx.CommandEvent)
4181 
4182  [戻り値]
4183  void
4184  """
4185  pt = self.pt
4186  tmpShape = self.FindShape(pt[0],pt[1])
4187  if tmpShape != 0:
4188  tmpShape[0].parent.ref_stop()
4189 
4190  def OnPopupReset(self, evt):
4191  pt = self.pt
4192  tmpShape = self.FindShape(pt[0],pt[1])
4193  if tmpShape != 0:
4194  tmpShape[0].parent.ref_reset()
4195 
4196  def OnPopupExit(self, evt):
4197  pt = self.pt
4198  tmpShape = self.FindShape(pt[0],pt[1])
4199  if tmpShape != 0:
4200  tmpShape[0].parent.ref_exit()
4201 
4202  def OnPopupKill(self, evt):
4203  pt = self.pt
4204  tmpShape = self.FindShape(pt[0],pt[1])
4205  if tmpShape != 0:
4206  tmpShape[0].parent.ref_kill()
4207 
4208  def OnPopupDelete(self, evt):
4209  """コンポーネント本体の削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4210 
4211  [引数]
4212  evt -- イベント(wx.CommandEvent)
4213 
4214  [戻り値]
4215  void
4216  """
4217  canvas = self.diagram.GetCanvas()
4218  dc = wx.ClientDC(self)
4219  canvas.PrepareDC(dc)
4220  pt = self.pt
4221  tmpShape = self.FindShape(pt[0],pt[1])
4222  if tmpShape != 0:
4223  tmpShape[0].parent.removeWidget(dc)
4224 
4225 # rtc_name = tmpShape[0].parent.rtc.ref_key
4226  rtc_name = tmpShape[0].parent.fullpath
4227  del self.rtc_dict[rtc_name]
4228  tmp = self.rtc_list.index(rtc_name)
4229  del self.rtc_list[tmp]
4230 
4231  for obj in canvas.selected:
4232  if obj == tmpShape[0]:
4233  tmp = canvas.selected.index(tmpShape[0])
4234  del canvas.selected[tmp]
4235  bdc = getBufferedDC(canvas)
4236  canvas.PrepareDC(bdc)
4237 # canvas.Redraw(bdc)
4238  canvas.Redraw(dc)
4239 
4240  def OnPopupSub(self, evt):
4241  """サブメニューの実験用ダミーイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4242 
4243  [引数]
4244  evt -- イベント(wx.CommandEvent)
4245 
4246  [戻り値]
4247  void
4248  """
4249  print "OnPopupSub!!!"
4250 
4251  def OnPopupDelSelectItem(self, evt):
4252  """選択されたアイテムの削除を行うイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4253 
4254  [引数]
4255  evt -- イベント(wx.CommandEvent)
4256 
4257  [戻り値]
4258  void
4259  """
4260  self.deleteSelectedShape()
4261 
4262  def OnPopupLoadXML(self, evt):
4263  """XMLファイル(comp_data.xml)を読み込むイベントハンドラ [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4264 
4265  [引数]
4266  evt -- イベント(wx.CommandEvent)
4267 
4268  [戻り値]
4269  void
4270  """
4271  self.loadXML()
4272 
4273  def OnPopupSaveDefaultXML(self, evt):
4274  """XMLファイル(アセンブリ)を書き込むイベントハンドラ 上書き保存 ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4275  上書き保存
4276  ファイル名:System?.xml ・・・ ? には画面番号が入る [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4277 
4278  [引数]
4279  evt -- イベント(wx.CommandEvent)
4280 
4281  [戻り値]
4282  void
4283  """
4284  filename = "System%d.xml" % self.frame.drawCurNum
4285  self.saveXML(filename)
4286 
4287  def OnPopupSaveXML(self, evt):
4288  """XMLファイル(アセンブリ)を書き込むイベントハンドラ ファイル名変更で保存 ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4289  ファイル名変更で保存
4290  ファイル名は、ダイアログでユーザ任意指定 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4291 
4292  [引数]
4293  evt -- イベント(wx.CommandEvent)
4294 
4295  [戻り値]
4296  void
4297  """
4298  self.saveAsXML()
4299 
4300  def OnPopupRefresh(self, evt):
4301  """Refresh処理を行うイベントハンドラ 古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4302  古い接続(コンポーネント上にだけsubuscribe情報がある。画面に線が表示されていない状態)が
4303  あるときに、ok/cancelダイアログを表示し、再接続と最新のステータスで色を変更する [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4304 
4305  [引数]
4306  evt -- イベント(wx.CommandEvent)
4307 
4308  [戻り値]
4309  void
4310  """
4311  canvas = self.diagram.GetCanvas()
4312  # yes/no dialog
4313  val = self.DelOldConnectAskDialog()
4314  if val != wx.ID_OK:
4315  return
4316 
4317  self.refresh()
4318  self.reConnect()
4319 
4321  ret = False
4322  for rtc_name in self.rtc_list:
4323  ret = self.rtc_dict[rtc_name].checkOtherConnect()
4324  if ret == True:
4325  break
4326  return ret
4327 
4328  def askDialog(self, str):
4329  """ダイアログの表示機能
4330  ok/cancel ダイアログを表示する [引数] str --- ダイアログに表示するメッセージ [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) void
4331 
4332  [引数]
4333  str --- ダイアログに表示するメッセージ
4334 
4335  [戻り値]
4336  val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL)
4337  void
4338  """
4339 
4340  # yes/no dialog
4341  val = wx.ID_OK
4342  dlg = RtmDialog(self, -1, str)
4343  dlg.CenterOnParent()
4344  val = dlg.ShowModal()
4345  dlg.Destroy()
4346 
4347  return val
4348 
4350  """ダイアログの表示機能
4351  古い接続(コンポーネント上にsubscribe情報があり画面上には線が表示されていない)があれば、
4352  ok/cancel ダイアログを表示する [引数] なし [戻り値] val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL) 古い情報がない時は、wx.ID_OKを返す void
4353 
4354  [引数]
4355  なし
4356 
4357  [戻り値]
4358  val --- ダイアログの戻り値(wx.ID_OK/wx.ID_CANCEL)
4359  古い情報がない時は、wx.ID_OKを返す
4360  void
4361  """
4362 # assembly dummy
4363 # return wx.ID_OK
4364 # assembly dummy
4365  # yes/no dialog
4366  val = wx.ID_OK
4367  connect_flag = self.checkOtherConnect()
4368  if connect_flag == True:
4369  val = askDialog(strASKMESSAGE)
4370  return val
4371 
4372  def OnPopupConnectView(self, evt):
4373  """Connectメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4374  アセンブリファイル読み込み後の接続(subscribe)処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4375 
4376  [引数]
4377  evt -- イベント(wx.CommandEvent)
4378 
4379  [戻り値]
4380  void
4381  """
4382  canvas = self.diagram.GetCanvas()
4383  # yes/no dialog
4384  val = self.DelOldConnectAskDialog()
4385  if val != wx.ID_OK:
4386  return
4387 
4388  canvas.viewMode = False
4389  self.refresh()
4390  self.reConnect()
4391 
4392  def OnPopupDeleteView(self, evt):
4393  """Deleteメニューの処理を行うイベントハンドラ アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4394  アセンブリファイル読み込み後の表示画像の全削除処理 [引数] evt -- イベント(wx.CommandEvent) [戻り値] void
4395 
4396  [引数]
4397  evt -- イベント(wx.CommandEvent)
4398 
4399  [戻り値]
4400  void
4401  """
4402  self.deleteAllShape()
4403  canvas = self.diagram.GetCanvas()
4404  canvas.viewMode = False
4405 
4406  def makeBodyPopupMenu(self, evt):
4407  """コンポーネント上のポップアップメニュー(コンテキストメニュー)作成
4408  コンポーネント図形本体のOn/Off、削除をメニュー表示
4409 
4410  [引数]
4411  evt -- イベント(wx.MouseEvent)を指定 [戻り値] void
4412 
4413  [戻り値]
4414  void
4415  """
4416  # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない
4417  # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID1"): self.popupID1 = wx.NewId() # start menu self.popupID2 = wx.NewId() # stop menu self.popupID3 = wx.NewId() # delete menu self.popupID4 = wx.NewId() # reset menu self.popupID5 = wx.NewId() # exit menu self.popupID6 = wx.NewId() # kill menu self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1) self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2) self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3) self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4) self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5) self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6) menu = wx.Menu() menu.Append(self.popupID1, strSTART) menu.Append(self.popupID2, strSTOP) menu.Append(self.popupID4, strRESET) menu.Append(self.popupID5, strEXIT) menu.Append(self.popupID6, strKILL) menu.AppendSeparator() menu.Append(self.popupID3, strDELITEM) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeBackgroundPopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 削除、ロード、セーブのメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4418  self.pt = evt.GetPosition()
4419  if not hasattr(self, "popupID1"):
4420  self.popupID1 = wx.NewId() # start menu
4421  self.popupID2 = wx.NewId() # stop menu
4422  self.popupID3 = wx.NewId() # delete menu
4423  self.popupID4 = wx.NewId() # reset menu
4424  self.popupID5 = wx.NewId() # exit menu
4425  self.popupID6 = wx.NewId() # kill menu
4426 
4427  self.Bind(wx.EVT_MENU, self.OnPopupStart, id = self.popupID1)
4428  self.Bind(wx.EVT_MENU, self.OnPopupStop, id = self.popupID2)
4429  self.Bind(wx.EVT_MENU, self.OnPopupDelete, id = self.popupID3)
4430  self.Bind(wx.EVT_MENU, self.OnPopupReset, id = self.popupID4)
4431  self.Bind(wx.EVT_MENU, self.OnPopupExit, id = self.popupID5)
4432  self.Bind(wx.EVT_MENU, self.OnPopupKill, id = self.popupID6)
4433 
4434 
4435  menu = wx.Menu()
4436  menu.Append(self.popupID1, strSTART)
4437  menu.Append(self.popupID2, strSTOP)
4438  menu.Append(self.popupID4, strRESET)
4439  menu.Append(self.popupID5, strEXIT)
4440  menu.Append(self.popupID6, strKILL)
4441  menu.AppendSeparator()
4442  menu.Append(self.popupID3, strDELITEM)
4443 
4444  self.PopupMenu(menu, evt.GetPosition())
4445  menu.Destroy()
4446 
4447  def makeBackgroundPopupMenu(self, evt ):
4448  """バックグランド上のポップアップメニュー(コンテキストメニュー)作成
4449  削除、ロード、セーブのメニュー表示
4450 
4451  [引数]
4452  evt -- イベント(wx.MouseEvent)を指定 [戻り値] void
4453 
4454  [戻り値]
4455  void
4456  """
4457  # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない
4458  # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupIDa"): self.popupIDa = wx.NewId() # selected item delete menu self.popupIDb = wx.NewId() # refresh menu self.popupIDc = wx.NewId() # xml file load menu self.popupIDd = wx.NewId() # xml file save menu self.popupIDe = wx.NewId() # xml file save as menu self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa) self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb) self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc) self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd) self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe) menu = wx.Menu() menu.Append(self.popupIDa, strDEL_SELECT) menu.AppendSeparator() menu.Append(self.popupIDb, strREFRESH) menu.AppendSeparator() menu.Append(self.popupIDc, strOPEN) menu.Append(self.popupIDd, strSAVE) menu.Append(self.popupIDe, strSAVE_AS) # assembly disable # menu.FindItemById(self.popupIDc).Enable(False) # menu.FindItemById(self.popupIDd).Enable(False) # menu.FindItemById(self.popupIDe).Enable(False) # assembly disable self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def makeViewModePopupMenu(self, evt ): """バックグランド上のポップアップメニュー(コンテキストメニュー)作成 Connect、Delete のメニュー表示 [引数] evt -- イベント(wx.MouseEvent)を指定 [戻り値] void """ # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4459  self.pt = evt.GetPosition()
4460  if not hasattr(self, "popupIDa"):
4461  self.popupIDa = wx.NewId() # selected item delete menu
4462  self.popupIDb = wx.NewId() # refresh menu
4463  self.popupIDc = wx.NewId() # xml file load menu
4464  self.popupIDd = wx.NewId() # xml file save menu
4465  self.popupIDe = wx.NewId() # xml file save as menu
4466 
4467  self.Bind(wx.EVT_MENU, self.OnPopupDelSelectItem,id = self.popupIDa)
4468  self.Bind(wx.EVT_MENU, self.OnPopupRefresh, id = self.popupIDb)
4469  self.Bind(wx.EVT_MENU, self.OnPopupLoadXML, id = self.popupIDc)
4470  self.Bind(wx.EVT_MENU, self.OnPopupSaveDefaultXML, id = self.popupIDd)
4471  self.Bind(wx.EVT_MENU, self.OnPopupSaveXML, id = self.popupIDe)
4472 
4473  menu = wx.Menu()
4474  menu.Append(self.popupIDa, strDEL_SELECT)
4475  menu.AppendSeparator()
4476  menu.Append(self.popupIDb, strREFRESH)
4477  menu.AppendSeparator()
4478  menu.Append(self.popupIDc, strOPEN)
4479  menu.Append(self.popupIDd, strSAVE)
4480  menu.Append(self.popupIDe, strSAVE_AS)
4481 # assembly disable
4482 # menu.FindItemById(self.popupIDc).Enable(False)
4483 # menu.FindItemById(self.popupIDd).Enable(False)
4484 # menu.FindItemById(self.popupIDe).Enable(False)
4485 # assembly disable
4486 
4487 
4488  self.PopupMenu(menu, evt.GetPosition())
4489  menu.Destroy()
4490 
4491  def makeViewModePopupMenu(self, evt ):
4492  """バックグランド上のポップアップメニュー(コンテキストメニュー)作成
4493  Connect、Delete のメニュー表示
4494 
4495  [引数]
4496  evt -- イベント(wx.MouseEvent)を指定 [戻り値] void
4497 
4498  [戻り値]
4499  void
4500  """
4501  # メニュー関連のイベントはCommandEventで、マウスカーソル座標を取得出来ない
4502  # ここでは、座標をself.ptに格納し直後のメニューイベントで使用する self.pt = evt.GetPosition() if not hasattr(self, "popupID01"): self.popupID01 = wx.NewId() # selected item delete menu self.popupID02 = wx.NewId() # xml file load menu self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01) self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02) menu = wx.Menu() menu.Append(self.popupID01, strASM_CONNECT) menu.AppendSeparator() menu.Append(self.popupID02, strASM_DELETE) self.PopupMenu(menu, evt.GetPosition()) menu.Destroy() def OnRightDown(self, evt): """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightDown") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0: if hasattr(tmpShape[0], 'parent'): # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4503  self.pt = evt.GetPosition()
4504  if not hasattr(self, "popupID01"):
4505  self.popupID01 = wx.NewId() # selected item delete menu
4506  self.popupID02 = wx.NewId() # xml file load menu
4507 
4508  self.Bind(wx.EVT_MENU, self.OnPopupConnectView,id = self.popupID01)
4509  self.Bind(wx.EVT_MENU, self.OnPopupDeleteView, id = self.popupID02)
4510 
4511  menu = wx.Menu()
4512  menu.Append(self.popupID01, strASM_CONNECT)
4513  menu.AppendSeparator()
4514  menu.Append(self.popupID02, strASM_DELETE)
4515 
4516  self.PopupMenu(menu, evt.GetPosition())
4517  menu.Destroy()
4518 
4519  def OnRightDown(self, evt):
4520  """右クリック・ダウンのイベントハンドラ マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う コンポーネント本体上では、ポップアップメニューの表示を行う [引数] evt -- イベント [戻り値] void
4521  マウスカーソルがInport/Outport上だと、ツールチップ(バルーンヘルプ)の表示を行う
4522  コンポーネント本体上では、ポップアップメニューの表示を行う
4523 
4524  [引数]
4525  evt -- イベント [戻り値] void
4526 
4527  [戻り値]
4528  void
4529  """
4530  self.log.write("OnRightDown")
4531  canvas = self.diagram.GetCanvas()
4532  dc = wx.ClientDC(self)
4533  canvas.PrepareDC(dc)
4534  pt = evt.GetPosition()
4535  tmpShape = self.FindShape(pt[0],pt[1])
4536  if tmpShape != 0:
4537  if hasattr(tmpShape[0], 'parent'):
4538  # Inport/Outportの処理 if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out': # ツールチップの作成 self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc) self.tooltip.body.SetCanvas(canvas) self.diagram.AddShape(self.tooltip.body) self.tooltip.body.Show(True) # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4539  if tmpShape[0].parent.tag == 'in' or tmpShape[0].parent.tag == 'out':
4540  # ツールチップの作成
4541  self.tooltip = makeToolTip(tmpShape[0].parent,pt,dc)
4542 
4543  self.tooltip.body.SetCanvas(canvas)
4544  self.diagram.AddShape(self.tooltip.body)
4545  self.tooltip.body.Show(True)
4546  # コンポーネント本体の処理 elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False: self.makeBodyPopupMenu(evt) else: if canvas.viewMode == False: self.makeBackgroundPopupMenu(evt) else: self.makeViewModePopupMenu(evt) canvas.Redraw(dc) evt.Skip() def OnRightUp(self, evt): """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void """ self.log.write("OnRightUp") canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) pt = evt.GetPosition() if self.tooltip != None: # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4547  elif tmpShape[0].parent.tag == 'body' and canvas.viewMode == False:
4548  self.makeBodyPopupMenu(evt)
4549  else:
4550  if canvas.viewMode == False:
4551  self.makeBackgroundPopupMenu(evt)
4552  else:
4553  self.makeViewModePopupMenu(evt)
4554 
4555  canvas.Redraw(dc)
4556  evt.Skip()
4557 
4558  def OnRightUp(self, evt):
4559  """右クリック・アップのイベントハンドラ ツールチップ(バルーンヘルプ)の削除を行う [引数] evt -- イベント [戻り値] void
4560  ツールチップ(バルーンヘルプ)の削除を行う
4561 
4562  [引数]
4563  evt -- イベント [戻り値] void
4564 
4565  [戻り値]
4566  void
4567  """
4568  self.log.write("OnRightUp")
4569  canvas = self.diagram.GetCanvas()
4570  dc = wx.ClientDC(self)
4571  canvas.PrepareDC(dc)
4572  pt = evt.GetPosition()
4573  if self.tooltip != None:
4574  # ツールチップの削除 self.tooltip.removeWidget(dc) del self.tooltip self.tooltip = None canvas.Redraw(dc) evt.Skip() def OnLeftDown(self, evt): """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape == 0: canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) else: evt.Skip() def OnMiddleDown(self, evt): """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void """ pt = evt.GetPosition() isShift = evt.ShiftDown() canvas = self.diagram.GetCanvas() dc = wx.ClientDC(self) canvas.PrepareDC(dc) for s in canvas.selected: s.Select(False, dc) s.parent.unselected(dc) canvas.selected = [] canvas.Redraw(dc) tmpShape = self.FindShape(pt[0],pt[1]) if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button self.log.write("OnMiddleDown: " ) tmpShape[0].parent.reversesBody() elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button self.log.write("OnMiddleDown + Shift Key: " ) tmpShape[0].parent.rotatesBody() else: evt.Skip() canvas.Redraw(dc) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() wx.lib.colourdb.updateColourDB() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- # The OGL library holds some resources that need to be freed before # the app shuts down. class __Cleanup: def __del__(self, cleanup=ogl.OGLCleanUp): cleanup() # When this module gets cleaned up by Python then __cu will be cleaned # up and it's __dell__ is called, which will then call ogl.OGLCleanUp. __cu = __Cleanup() overview = """\ The Object Graphics Library is a library supporting the creation and manipulation of simple and complex graphic images on a canvas. """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4575  self.tooltip.removeWidget(dc)
4576  del self.tooltip
4577  self.tooltip = None
4578  canvas.Redraw(dc)
4579  evt.Skip()
4580 
4581  def OnLeftDown(self, evt):
4582  """左クリック・ダウンのイベントハンドラ キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void
4583  キャンバス上の図形がない空間で左クリックされたら図形選択を解除する [引数] evt -- イベント [戻り値] void
4584 
4585  [引数]
4586  evt -- イベント [戻り値] void
4587 
4588  [戻り値]
4589  void
4590  """
4591  pt = evt.GetPosition()
4592  tmpShape = self.FindShape(pt[0],pt[1])
4593  if tmpShape == 0:
4594  canvas = self.diagram.GetCanvas()
4595  dc = wx.ClientDC(self)
4596  canvas.PrepareDC(dc)
4597  for s in canvas.selected:
4598  s.Select(False, dc)
4599  s.parent.unselected(dc)
4600  canvas.selected = []
4601  canvas.Redraw(dc)
4602  else:
4603  evt.Skip()
4604 
4605  def OnMiddleDown(self, evt):
4606  """マウス中ボタン・ダウンのイベントハンドラ コンポーネント図形の本体上で押されたら、回転処理を行う [引数] evt -- イベント [戻り値] void
4607  コンポーネント図形の本体上で押されたら、回転処理を行う
4608 
4609  [引数]
4610  evt -- イベント [戻り値] void
4611 
4612  [戻り値]
4613  void
4614  """
4615  pt = evt.GetPosition()
4616  isShift = evt.ShiftDown()
4617  canvas = self.diagram.GetCanvas()
4618  dc = wx.ClientDC(self)
4619  canvas.PrepareDC(dc)
4620  for s in canvas.selected:
4621  s.Select(False, dc)
4622  s.parent.unselected(dc)
4623  canvas.selected = []
4624  canvas.Redraw(dc)
4625 
4626  tmpShape = self.FindShape(pt[0],pt[1])
4627  if tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift != True: ## Middle Button
4628  self.log.write("OnMiddleDown: " )
4629  tmpShape[0].parent.reversesBody()
4630  elif tmpShape != 0 and tmpShape[0].parent.tag == 'body' and isShift == True: ## Shift Key Down & Middle Button
4631  self.log.write("OnMiddleDown + Shift Key: " )
4632  tmpShape[0].parent.rotatesBody()
4633  else:
4634  evt.Skip()
4635 
4636  canvas.Redraw(dc)
4637 
4638 #----------------------------------------------------------------------
4639 
4640 def runTest(frame, nb, log):
4641  # This creates some pens and brushes that the OGL library uses.
4642  # It should be called after the app object has been created, but
4643  # before OGL is used.
4644  ogl.OGLInitialize()
4645  wx.lib.colourdb.updateColourDB()
4646  win = TestWindow(nb, log, frame)
4647 
4648  return win
4649 
4650 #----------------------------------------------------------------------
4651 
4652 # The OGL library holds some resources that need to be freed before
4653 # the app shuts down.
4655  def __del__(self, cleanup=ogl.OGLCleanUp):
4656  cleanup()
4657 
4658 # When this module gets cleaned up by Python then __cu will be cleaned
4659 # up and it's __dell__ is called, which will then call ogl.OGLCleanUp.
4660 __cu = __Cleanup()
4661 
4662 
4663 overview = """\
4664 The Object Graphics Library is a library supporting the creation and
4665 manipulation of simple and complex graphic images on a canvas.
4666 
4667 """
4668 
4669 if __name__ == '__main__':
4670  import sys,os
4671  import run
4672  run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
4673 
def __init__(self, parent, points)
def __del__(self, cleanup=ogl.OGLCleanUp)
def OnPopupDelSelectItem(self, evt)
def OnSizingEndDragLeft(self, pt, x, y, keys, attch)
def OnDragLeft(self, draw, x, y, keys, attachment)
def disconnectToObjref(self, subscr_list)
def __init__(self, log, frame)
def removeWidget(self, dc, rot=0)
def OnPopupConnectView(self, evt)
def MyAddShape(self, shape, x, y, pen, brush, text, inoutPort=0)
def delLineIdx(self, idx)
def dmove(self, dc, movex, movey)
def MyAddBmp(self, shape, x, y, pen)
def saveXML(self, saveFileName)
def OnBeginDragLeft(self, x, y, keys, attachment)
def disconnect(self, line_idx)
def removeWidget(self, dc)
def OnEndDragLeft(self, x, y, keys=0, attachment=0)
def createWidget(self, rot)
def connect2(self, line_idx, subscription_type)
def updateInportPolygon(self, points)
def runTest(frame, nb, log)
def dmove(self, dc, d_x, d_y)
def setBodyColor(shape, colorFlag)
def __init__(self, parent, ns_dict, fullpath, inp, pos_x, pos_y)
def dmove(self, dc, movex, movey)
def OnEndDragLeft(self, x, y, keys=0, attachment=0)
def UpdateStatusBar(self, shape)
def MyAddOval(self, shape, x, y)
def childMove(self, dc, pos_new)
def checkOtherConnect(self)
def unselected(self, dc)
def dmove(self, dc, movex, movey)
def __init__(self, canvas, parent)
def getConfig(self, name)
def OnLeftClick(self, x, y, keys=0, attachment=0)
def __init__(self, log, frame)
def MyAddText(self, shape, x, y, pen, brush=None)
def setPoints(self, startX, startY, endX, endY)
def OnBeginDragLeft(self, x, y, keys=0, attachment=0)
def makeBackgroundPopupMenu(self, evt)
def OnBeginDragLeft(self, x, y, keys, attachment)
def __init__(self, parent, points)
def OnSizingEndDragLeft(self, pt, x, y, keys, attch)
def __init__(self, parent, pt, dc)
def setLine2port(self, canvas, dc)
def __init__(self, parent, tag, pos_x, pos_y)
def __init__(self, log, frame)
def getConfig(self, name)
def __init__(self, log, frame)
def __init__(self, parent, log)
def OnDragOver(self, x, y, d)
def __init__(self, parent, width, height)
def __init__(self, parent, log, frame)
def updatePolygonSize(self, x, y, ratioW, ratioH)
def connect(self, line_idx, subscription_type)
def OnDropText(self, x, y, text)
def OnLeftClick(self, x, y, keys=0, attachment=0)
def __init__(self, parent, canvas)
def setEndPoint(self, dc, shape, movex, movey)
def makeBodyPopupMenu(self, evt)
def OnPopupSaveDefaultXML(self, evt)
bmp
ビットマップの作成
void append(SDOPackage::NVList &dest, const SDOPackage::NVList &src)
Append an element to NVList.
Definition: NVUtil.cpp:354
def checkCompState(self)
def setPoints(self, startX, startY, endX, endY)
def OnLeftClick(self, x, y, keys=0, attachment=0)
def OnDragLeft(self, draw, x, y, keys, attachment)
def __init__(self, parent, pos_x, pos_y, width, height)
def updatePolygonSize(self, x, y, ratioW, ratioH)
def makeViewModePopupMenu(self, evt)
def setStartPoint(self, dc, movex, movey)
def getBufferedDC(canvas)
def OnPopupDeleteView(self, evt)
def __init__(self, parent, ns_dict, fullpath, outp, pos_x, pos_y)
def updatePolygonSize(self, x, y, ratioW, ratioH)
def unselected(self, dc)
def disconnect(self, line_idx)
def delLineIdx(self, idx)
def OnBeginDragLeft(self, x, y, keys, attachment)
def OnBeginDragLeft(self, x, y, keys, attachment)
def removeWidget(self, dc, rot=0)
def unselected(self, dc)
def checkConnect(self, inp_obj, subscr_list)
def __init__(self, parent, fullpath, pos_x, pos_y)
def OnDragLeft(self, draw, x, y, keys, attachment)
def search_g_inp(self, inp_ref)
def __init__(self, log, frame)
def removeWidget(self, dc)
def OnLeftClick(self, x, y, keys=0, attachment=0)
def changeCoordT(self, id, new_p1, new_p2)
def changeCompColor(self, fullname, state)
def removeWidget(self, dc, rot=0)
def OnDragLeft(self, draw, x, y, keys=0, attachment=0)
def __init__(self, parent, width, height)
def createGRtc_from_dict(self, dict)
def checkConnect2(self, line, subscr_list)
def OnLeftClick(self, x, y, keys=0, attachment=0)
def OnEndDragLeft(self, x, y, keys=0, attachment=0)
def connect(self, line_idx)
def OnEndDragLeft(self, x, y, keys=0, attachment=0)
def changeBodyColor(self, state)
def unselected(self, dc)
def remove(self, dc, canvas)
def updateOutportPolygon(self, points)
def dmove(self, dc, movex, movey)
def OnEndDragLeft(self, x, y, keys=0, attachment=0)
def except_mess(mess)
Definition: RtmDialog.py:100


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Jun 6 2019 19:26:00