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$
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 
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 
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.rot