| |
2621 |
class ORMShape(Data._dbObject):
|
| |
2622 |
pass
|
| |
2623 |
# add methods to shape object
|
| |
2624 |
def Follow(self): # identify which objects you follow
|
| |
2625 |
pass # overriden in subtypes
|
| |
2626 |
def AddFollower(self, follower_shape):
|
| |
2627 |
self.followers.append(follower_shape)
|
| |
2628 |
def RemoveFollower(self, follower_shape):
|
| |
2629 |
pass
|
| |
2630 |
def SetTempPos(self, x, y):
|
| |
2631 |
self._SetInShell('TempX', x)
|
| |
2632 |
self._SetInShell('TempY', y)
|
| |
2633 |
def GetPos(self):
|
| |
2634 |
return self.TempX, self.TempY
|
| |
2635 |
def CommitPos(self): # need error check - what if they don't exist
|
| |
2636 |
self.PosX = self.TempX
|
| |
2637 |
self.PosY = self.TempY
|
| |
2638 |
## #self.followers.append(follower_shape)
|
| |
2639 |
## shape._SetInShell('followers', [])
|
| |
2640 |
## shape._SetInShell('AddFollower', AddFollower)
|
| |
2641 |
## shape._SetInShell('RemoveFollower', RemoveFollower)
|
| |
2642 |
|
| |
2643 |
class ORMBox(ORMShape):
|
| |
2644 |
def AdjustEnd(self, other_end): # use separate x & y or a tuple?
|
| |
2645 |
'''x & y are for the other end of the line'''
|
| |
2646 |
centerx, centery = self.GetPos()
|
| |
2647 |
r = self.canvas.pdc.GetIdBounds(self.dcid)
|
| |
2648 |
x, y = wx.lib.ogl.FindEndForBox(r.GetWidth(), r.GetHeight(), centerx, centery, other_end[0], other_end[1])
|
| |
2649 |
return int(x), int(y)
|
| |
2650 |
|
| |
2651 |
class ORMCircle(ORMShape):
|
| |
2652 |
def AdjustEnd(self, other_end): # use separate x & y or a tuple?
|
| |
2653 |
'''x & y are for the other end of the line'''
|
| |
2654 |
r = self.canvas.pdc.GetIdBounds(self.dcid)
|
| |
2655 |
# width == height
|
| |
2656 |
centerx, centery = self.GetPos()
|
| |
2657 |
x, y = wx.lib.ogl.FindEndForCircle(r.GetWidth()/2, centerx, centery, other_end[0], other_end[1])
|
| |
2658 |
return int(x), int(y)
|
| |
2659 |
|
| |
2660 |
class ORMConnector(ORMShape):
|
| |
2661 |
def AdjustEnd(self, other_end): # use separate x & y or a tuple?
|
| |
2662 |
'''x & y are for the other end of the line'''
|
| |
2663 |
# r = self.canvas.pdc.GetIdBounds(self.dcid)
|
| |
2664 |
# x, y = wx.lib.ogl.FindEndForBox(r.GetWidth(), r.GetHeight(), self.PosX, self.PosY, other_end[0], other_end[1])
|
| |
2665 |
# return int(x), int(y)
|
| |
2666 |
return self.GetPos()
|
| |
2667 |
|
| |
2668 |
class ORMObjectShape(ORMBox):
|
| |
2669 |
def Draw(self, dc):
|
| |
2670 |
orm_object = self.Get('Target')
|
| |
2671 |
x, y = self.GetPos()
|
| |
2672 |
## x = self.PosX # treat this as the center of the shape
|
| |
2673 |
## y = self.PosY
|
| |
2674 |
|
| |
2675 |
dc.ClearId(self.dcid)
|
| |
2676 |
dc.SetId(self.dcid)
|
| |
2677 |
|
| |
2678 |
# text = orm_object.Text or 'empty note'
|
| |
2679 |
lines = []
|
| |
2680 |
word = orm_object.Name or 'default name'
|
| |
2681 |
if orm_object.Independent:
|
| |
2682 |
work += "!"
|
| |
2683 |
if orm_object.Derived:
|
| |
2684 |
work += orm_object.Derived
|
| |
2685 |
lines.append(word)
|
| |
2686 |
word = orm_object.RefMode or ''
|
| |
2687 |
if word:
|
| |
2688 |
word = '(' + word + ')'
|
| |
2689 |
lines.append(word)
|
| |
2690 |
|
| |
2691 |
sizes = [ self.canvas.GetFullTextExtent(line)[0:2] for line in lines ] # pull out only w and h
|
| |
2692 |
w = 5
|
| |
2693 |
h = 0
|
| |
2694 |
for line_w,line_h in sizes:
|
| |
2695 |
w = max(w, line_w)
|
| |
2696 |
h += line_h
|
| |
2697 |
box_w = w + 8
|
| |
2698 |
box_h = h + 6
|
| |
2699 |
|
| |
2700 |
if orm_object.Type == 'Entity':
|
| |
2701 |
pen = self.canvas.CachedPen(1, 1, wx.SOLID)
|
| |
2702 |
else:
|
| |
2703 |
pen = self.canvas.CachedPen(1, 1, wx.DOT)
|
| |
2704 |
dc.SetPen(pen)
|
| |
2705 |
# dc.SetBrush(self.RandomBrush())
|
| |
2706 |
dc.SetBrush(self.canvas.CachedBrush('White'))
|
| |
2707 |
if debug: print 'round rectangle dimensions',x, y, box_w, box_h
|
| |
2708 |
box_x = x - box_w/2
|
| |
2709 |
box_y = y - box_h/2
|
| |
2710 |
# dc.DrawRoundedRectangle(box_x,box_y,box_w,box_h,8)
|
| |
2711 |
dc.DrawRoundedRectangle(box_x,box_y,box_w,box_h,6)
|
| |
2712 |
|
| |
2713 |
dc.SetFont(self.canvas.GetFont())
|
| |
2714 |
# dc.SetTextForeground(self.RandomColor())
|
| |
2715 |
# dc.SetTextBackground(self.RandomColor())
|
| |
2716 |
dc.SetTextForeground('Black')
|
| |
2717 |
dc.SetTextBackground('White')
|
| |
2718 |
dc.DrawText(lines[0], x - sizes[0][0]/2, box_y+3) # center text in box
|
| |
2719 |
dc.DrawText(lines[1], x - sizes[1][0]/2, box_y+box_h/2+1)
|
| |
2720 |
|
| |
2721 |
r = wx.Rect(box_x,box_y,box_w,box_h)
|
| |
2722 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2723 |
dc.SetIdBounds(self.dcid,r) # bounds inclose all of the drawing??
|
| |
2724 |
|
| |
2725 |
class ORMFactShape(ORMBox):
|
| |
2726 |
def Draw(self, dc):
|
| |
2727 |
orm_object = self.Get('Target')
|
| |
2728 |
x, y = self.GetPos()
|
| |
2729 |
## x = self.PosX # treat this as the center of the shape
|
| |
2730 |
## y = self.PosY
|
| |
2731 |
|
| |
2732 |
dc.ClearId(self.dcid)
|
| |
2733 |
dc.SetId(self.dcid)
|
| |
2734 |
|
| |
2735 |
role_box_size = 12
|
| |
2736 |
alignment = self.Orientation or 0
|
| |
2737 |
# eventually allow any of 4 orientations (90 degree rotations)
|
| |
2738 |
if alignment == 0:
|
| |
2739 |
w = (role_box_size) * (orm_object.Nary)
|
| |
2740 |
h = role_box_size
|
| |
2741 |
box_w = w + 6
|
| |
2742 |
box_h = h + 6
|
| |
2743 |
|
| |
2744 |
pen = self.canvas.CachedPen(1, 1, wx.SOLID)
|
| |
2745 |
dc.SetPen(pen)
|
| |
2746 |
dc.SetBrush(self.canvas.CachedBrush('White'))
|
| |
2747 |
for i in range(orm_object.Nary):
|
| |
2748 |
dc.DrawRectangle(x+i*role_box_size,y,role_box_size+1,h)
|
| |
2749 |
|
| |
2750 |
r = wx.Rect(x,y,box_w,box_h)
|
| |
2751 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2752 |
dc.SetIdBounds(self.dcid,r)
|
| |
2753 |
|
| |
2754 |
class ORMNoteShape(ORMBox):
|
| |
2755 |
def Draw(self, dc):
|
| |
2756 |
orm_object = self.Get('Target')
|
| |
2757 |
x, y = self.GetPos()
|
| |
2758 |
## x = self.PosX # treat this as the center of the shape
|
| |
2759 |
## y = self.PosY
|
| |
2760 |
|
| |
2761 |
dc.ClearId(self.dcid)
|
| |
2762 |
dc.SetId(self.dcid)
|
| |
2763 |
|
| |
2764 |
text = orm_object.Text or 'empty note'
|
| |
2765 |
lines = text.splitlines()
|
| |
2766 |
sizes = [ self.canvas.GetFullTextExtent(line)[0:2] for line in lines ] # pull out only w and h
|
| |
2767 |
w = 5
|
| |
2768 |
h = 0
|
| |
2769 |
for line_w,line_h in sizes:
|
| |
2770 |
w = max(w, line_w)
|
| |
2771 |
h += line_h
|
| |
2772 |
box_w = w + 6
|
| |
2773 |
box_h = h + 6
|
| |
2774 |
box_x = x - box_w/2
|
| |
2775 |
box_y = y - box_h/2
|
| |
2776 |
|
| |
2777 |
pen = self.canvas.CachedPen(1, 1, wx.DOT)
|
| |
2778 |
dc.SetPen(pen)
|
| |
2779 |
# dc.SetBrush(self.RandomBrush())
|
| |
2780 |
dc.SetBrush(self.canvas.CachedBrush('White'))
|
| |
2781 |
dc.DrawRectangle(box_x,box_y,box_w,box_h)
|
| |
2783 |
dc.SetFont(self.canvas.GetFont())
|
| |
2784 |
# dc.SetTextForeground(self.RandomColor())
|
| |
2785 |
dc.SetTextForeground('Black')
|
| |
2786 |
dc.SetTextBackground('White')
|
| |
2787 |
w = 3; h = 2
|
| |
2788 |
for i in range(len(lines)):
|
| |
2789 |
line = lines[i]
|
| |
2790 |
line_w, line_h = sizes[i]
|
| |
2791 |
dc.DrawText(line, box_x+w, box_y+h)
|
| |
2792 |
h += line_h
|
| |
2793 |
|
| |
2794 |
r = wx.Rect(box_x,box_y,box_w,box_h)
|
| |
2795 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2796 |
dc.SetIdBounds(self.dcid,r)
|
| |
2797 |
|
| |
2798 |
class ORMConstraintShape(ORMCircle):
|
| |
2799 |
''' external constraint?'''
|
| |
2800 |
def Draw(self, dc):
|
| |
2801 |
orm_object = self.Get('Target')
|
| |
2802 |
x, y = self.GetPos()
|
| |
2803 |
## x = self.PosX # treat this as the center of the shape
|
| |
2804 |
## y = self.PosY
|
| |
2805 |
|
| |
2806 |
dc.ClearId(self.dcid)
|
| |
2807 |
dc.SetId(self.dcid)
|
| |
2808 |
|
| |
2809 |
box_w = 20
|
| |
2810 |
box_h = box_w
|
| |
2811 |
box_x = x - box_w/2
|
| |
2812 |
box_y = y - box_h/2
|
| |
2813 |
|
| |
2814 |
pen = self.canvas.CachedPen(1, 1, wx.SOLID)
|
| |
2815 |
dc.SetPen(pen)
|
| |
2816 |
dc.SetBrush(self.canvas.CachedBrush('White'))
|
| |
2817 |
dc.DrawCircle(x,y,box_w/2)
|
| |
2818 |
|
| |
2819 |
## dc.SetFont(self.canvas.GetFont())
|
| |
2820 |
## dc.SetTextForeground('Black')
|
| |
2821 |
## dc.SetTextBackground('White')
|
| |
2822 |
##
|
| |
2823 |
## w = 3; h = 2
|
| |
2824 |
## for i in range(len(lines)):
|
| |
2825 |
## line = lines[i]
|
| |
2826 |
## line_w, line_h = sizes[i]
|
| |
2827 |
## dc.DrawText(line, box_x+w, box_y+h)
|
| |
2828 |
## h += line_h
|
| |
2829 |
|
| |
2830 |
r = wx.Rect(box_x,box_y,box_w,box_h)
|
| |
2831 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2832 |
dc.SetIdBounds(self.dcid,r)
|
| |
2833 |
|
| |
2834 |
class ORMRoleShape(ORMConnector):
|
| |
2835 |
def Follow(self):
|
| |
2836 |
nodea = self.Get('NodeA') # these objects might not already be in the diagram
|
| |
2837 |
nodeb = self.Get('NodeB')
|
| |
2838 |
# if not already in the diagram , then create the nodes
|
| |
2839 |
print 'nodea type', nodea.__class__
|
| |
2840 |
if not isinstance(nodea, ORMShape):
|
| |
2841 |
self.canvas.CreateNode(self.canvas.pdc, nodea)
|
| |
2842 |
print 'nodeb type', nodeb.__class__
|
| |
2843 |
if not isinstance(nodeb, ORMShape):
|
| |
2844 |
self.canvas.CreateNode(self.canvas.pdc, nodeb)
|
| |
2845 |
nodea.AddFollower(self) # must be the right subtype to have this method
|
| |
2846 |
nodeb.AddFollower(self)
|
| |
2847 |
|
| |
2848 |
def Draw(self, dc):
|
| |
2849 |
orm_object = self.Get('Target')
|
| |
2850 |
x = self.PosX # treat this as the center of the shape
|
| |
2851 |
y = self.PosY
|
| |
2852 |
nodea = self.Get('NodeA') # these objects might not already be in the diagram
|
| |
2853 |
nodeb = self.Get('NodeB')
|
| |
2854 |
|
| |
2855 |
enda = (nodea.PosX, nodea.PosY)
|
| |
2856 |
endb = (nodeb.PosX, nodeb.PosY)
|
| |
2857 |
enda, endb = nodea.AdjustEnd(endb), nodeb.AdjustEnd(enda)
|
| |
2858 |
|
| |
2859 |
dc.ClearId(self.dcid)
|
| |
2860 |
dc.SetId(self.dcid)
|
| |
2861 |
|
| |
2862 |
minx = min(enda[0], endb[0])
|
| |
2863 |
maxx = max(enda[0], endb[0])
|
| |
2864 |
miny = min(enda[1], endb[1])
|
| |
2865 |
maxy = max(enda[1], endb[1])
|
| |
2866 |
|
| |
2867 |
box_w = maxx - minx + 6
|
| |
2868 |
box_h = maxy - miny + 6
|
| |
2869 |
|
| |
2870 |
pen = self.canvas.CachedPen(1, 1, wx.SOLID)
|
| |
2871 |
dc.SetPen(pen)
|
| |
2872 |
dc.DrawLine(enda[0], enda[1], endb[0], endb[1])
|
| |
2873 |
self.SetTempPos((enda[0]+endb[0]) / 2, (enda[1] + endb[1]) / 2)
|
| |
2874 |
# need to add logic to draw the role name
|
| |
2875 |
# need to save the calculated PosX and PosY
|
| |
2876 |
|
| |
2877 |
r = wx.Rect(minx,miny,box_w,box_h)
|
| |
2878 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2879 |
dc.SetIdBounds(self.dcid,r)
|
| |
2880 |
|
| |
2881 |
class ORMNoteConnectorShape(ORMConnector):
|
| |
2882 |
def Follow(self):
|
| |
2883 |
nodea = self.Get('NodeA')
|
| |
2884 |
nodeb = self.Get('NodeB')
|
| |
2885 |
# if not already in the diagram , then create the nodes
|
| |
2886 |
if not isinstance(nodea, ORMShape):
|
| |
2887 |
shape.canvas.CreateNode(self.canvas.pdc, nodea)
|
| |
2888 |
if not isinstance(nodeb, ORMShape):
|
| |
2889 |
shape.canvas.CreateNode(self.canvas.pdc, nodeb)
|
| |
2890 |
nodea.AddFollower(self) # must be the right subtype to have this method
|
| |
2891 |
nodeb.AddFollower(self)
|
| |
2892 |
|
| |
2893 |
def Draw(self, dc):
|
| |
2894 |
orm_object = self.Get('Target')
|
| |
2895 |
x = self.PosX # treat this as the center of the shape
|
| |
2896 |
y = self.PosY
|
| |
2897 |
nodea = self.Get('NodeA')
|
| |
2898 |
nodeb = self.Get('NodeB')
|
| |
2899 |
|
| |
2900 |
dc.ClearId(self.dcid)
|
| |
2901 |
dc.SetId(self.dcid)
|
| |
2902 |
|
| |
2903 |
enda = (nodea.PosX, nodea.PosY)
|
| |
2904 |
endb = (nodeb.PosX, nodeb.PosY)
|
| |
2905 |
enda, endb = nodea.AdjustEnd(endb), nodeb.AdjustEnd(enda)
|
| |
2906 |
|
| |
2907 |
minx = min(enda[0], endb[0])
|
| |
2908 |
maxx = max(enda[0], endb[0])
|
| |
2909 |
miny = min(enda[1], endb[1])
|
| |
2910 |
maxy = max(enda[1], endb[1])
|
| |
2911 |
|
| |
2912 |
box_w = maxx - minx + 6
|
| |
2913 |
box_h = maxy - miny + 6
|
| |
2914 |
|
| |
2915 |
pen = self.canvas.CachedPen(1, 1, wx.DOT)
|
| |
2916 |
dc.SetPen(pen)
|
| |
2917 |
dc.DrawLine(enda[0], enda[1], endb[0], endb[1])
|
| |
2918 |
self.SetTempPos((enda[0]+endb[0]) / 2, (enda[1] + endb[1]) / 2)
|
| |
2919 |
|
| |
2920 |
r = wx.Rect(minx,miny,box_w,box_h)
|
| |
2921 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2922 |
dc.SetIdBounds(self.dcid,r)
|
| |
2923 |
|
| |
2924 |
class ORMConstraintConnectorShape(ORMConnector):
|
| |
2925 |
def Follow(self):
|
| |
2926 |
nodea = self.Get('NodeA')
|
| |
2927 |
nodeb = self.Get('NodeB')
|
| |
2928 |
# if not already in the diagram , then create the nodes
|
| |
2929 |
if not isinstance(nodea, ORMShape):
|
| |
2930 |
shape.canvas.CreateNode(self.canvas.pdc, nodea)
|
| |
2931 |
if not isinstance(nodeb, ORMShape):
|
| |
2932 |
shape.canvas.CreateNode(self.canvas.pdc, nodeb)
|
| |
2933 |
nodea.AddFollower(self) # must be the right subtype to have this method
|
| |
2934 |
nodeb.AddFollower(self)
|
| |
2935 |
|
| |
2936 |
def Draw(self, dc):
|
| |
2937 |
orm_object = self.Get('Target')
|
| |
2938 |
x = self.PosX # treat this as the center of the shape
|
| |
2939 |
y = self.PosY
|
| |
2940 |
nodea = self.Get('NodeA')
|
| |
2941 |
nodeb = self.Get('NodeB')
|
| |
2942 |
|
| |
2943 |
dc.ClearId(self.dcid)
|
| |
2944 |
dc.SetId(self.dcid)
|
| |
2945 |
|
| |
2946 |
enda = (nodea.PosX, nodea.PosY)
|
| |
2947 |
endb = (nodeb.PosX, nodeb.PosY)
|
| |
2948 |
enda, endb = nodea.AdjustEnd(endb), nodeb.AdjustEnd(enda)
|
| |
2949 |
|
| |
2950 |
minx = min(enda[0], endb[0])
|
| |
2951 |
maxx = max(enda[0], endb[0])
|
| |
2952 |
miny = min(enda[1], endb[1])
|
| |
2953 |
maxy = max(enda[1], endb[1])
|
| |
2954 |
|
| |
2955 |
box_w = maxx - minx + 6
|
| |
2956 |
box_h = maxy - miny + 6
|
| |
2957 |
|
| |
2958 |
pen = self.canvas.CachedPen(1, 1, wx.SOLID)
|
| |
2959 |
dc.SetPen(pen)
|
| |
2960 |
dc.DrawLine(enda[0], enda[1], endb[0], endb[1])
|
| |
2961 |
self.SetTempPos((enda[0]+endb[0]) / 2, (enda[1] + endb[1]) / 2)
|
| |
2962 |
|
| |
2963 |
r = wx.Rect(minx,miny,box_w,box_h)
|
| |
2964 |
r.Inflate(pen.GetWidth(),pen.GetWidth())
|
| |
2965 |
dc.SetIdBounds(self.dcid,r)
|
| |
2966 |
|
| |
2967 |
# -------------
|