1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
# Name: tools.py
# Purpose: XRC editor, toolbar
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 19.03.2003
# RCS-ID: $Id: tools.py 67456 2011-04-13 18:02:41Z RD $
from globals import *
from component import Manager, DEFAULT_POS
import view
import images
import wx.lib.foldpanelbar as fpb
#if wx.Platform in ['__WXMAC__', '__WXMSW__']:
# Mac and Win are better off with generic
import wx.lib.buttons
BitmapButton = wx.lib.buttons.GenBitmapButton
#else:
# wx.BitmapButton.SetBezelWidth = lambda self, w: None
class ToolPanel(wx.PyPanel):
'''Manages a Listbook with tool bitmap buttons.'''
defaultPos = wx.GBPosition(*DEFAULT_POS)
def __init__(self, parent):
if wx.Platform == '__WXGTK__':
wx.PyPanel.__init__(self, parent, -1,
style=wx.RAISED_BORDER|wx.WANTS_CHARS)
else:
wx.PyPanel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
self.bg = wx.Colour(115, 180, 215)
# Top sizer
sizer = wx.BoxSizer(wx.VERTICAL)
# Use toolbook or foldpanelbar depending of preferences
if g.conf.toolPanelType == 'TB':
self.tp = wx.Toolbook(self, -1, style=wx.BK_TOP)
sizer.Add(self.tp, 1, wx.EXPAND)
# Image list
thumbSize = g.conf.toolThumbSize
il = wx.ImageList(thumbSize, thumbSize, True)
# Default Id 0
il.Add(images.ToolPanel_Default.GetImage().Scale(thumbSize, thumbSize).ConvertToBitmap())
self.il = il
self.tp.AssignImageList(il)
elif g.conf.toolPanelType == 'FPB':
self.tp = fpb.FoldPanelBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
agwStyle=fpb.FPB_VERTICAL)
sizer.Add(self.tp, 1, wx.EXPAND)
self.panels = []
for name in Manager.panelNames:
panelData = Manager.getPanelData(name)
if not panelData: continue
try:
im = Manager.panelImages[name]
imageId = il.Add(im.Scale(thumbSize, thumbSize).ConvertToBitmap())
except:
imageId = 0
panel = self.AddPanel(name)
self.panels.append(panel)
for pos,span,comp,bmp in panelData:
self.AddButton(panel, pos, span, comp.id, bmp, comp.klass)
panel.Fit()
if g.conf.toolPanelType == 'TB':
self.tp.AddPage(panel, '', imageId=imageId)
else:
p = self.tp.AddFoldPanel(name, collapsed=False)
p.SetBackgroundColour(self.bg)
panel.Reparent(p)
p.AddWindow(panel, fpb.FPB_ALIGN_WIDTH)
self.tp.Fit()
self.SetSizer(sizer)
# Allow to be resized in horizontal direction only
# Events
# wx.EVT_KEY_DOWN(self, self.OnKeyDown)
# wx.EVT_KEY_UP(self, self.OnKeyUp)
self.drag = None
def DoGetBestSize(self):
# Do our own DoGetBestSize because the FoldPanelBar doesn't
h = w = 0
for p in self.panels:
ems = p.GetEffectiveMinSize()
w = max(w, ems.width)
h = max(h, ems.height)
h += 64
return wx.Size(w,h)
def AddButton(self, panel, pos, span, id, bmp, text):
button = BitmapButton(panel, id, bmp,
style=wx.NO_BORDER)# | wx.WANTS_CHARS)
button.SetBezelWidth(0)
# wx.EVT_KEY_DOWN(button, self.OnKeyDown)
# wx.EVT_KEY_UP(button, self.OnKeyUp)
button.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDownOnButton)
button.Bind(wx.EVT_MOTION, self.OnMotionOnButton)
button.Bind(wx.EVT_BUTTON, self.OnButton)
button.SetToolTipString(text)
# Look for an available place if not specified
r0,c0 = 0,0
if pos != self.defaultPos:
if panel.sizer.CheckForIntersectionPos(pos, span):
r0,c0 = pos # start from pos
pos = self.defaultPos # reset to default
if pos == self.defaultPos:
# Find the smallest position we can insert into
try:
for r in range(r0, panel.size.rowspan):
for c in range(c0, panel.size.colspan):
if not panel.sizer.CheckForIntersectionPos((r,c), span):
pos = (r,c)
raise StopIteration
except StopIteration:
pass
if pos == self.defaultPos: # insert new col/row
if panel.size.colspan + span[0] <= panel.size.rowspan + span[1]:
pos = (0,panel.size.colspan)
else:
pos = (panel.size.rowspan,0)
assert pos[0] >= 0 and pos[1] >= 0, 'invalid position'
panel.sizer.Add(button, pos, span, wx.ALIGN_CENTRE)
panel.controls[id] = button
panel.size.rowspan = max(panel.size.rowspan, pos[0]+span[0])
panel.size.colspan = max(panel.size.colspan, pos[1]+span[1])
def AddPanel(self, name):
# Each group is inside box
panel = wx.Panel(self.tp)
panel.SetBackgroundColour(self.bg)
panel.name = name
panel.controls = {}
panel.size = wx.GBSpan(1, 1) # current size
topSizer = wx.BoxSizer()
panel.sizer = wx.GridBagSizer(0, 0)
panel.sizer.SetEmptyCellSize((24, 24))
topSizer.Add(panel.sizer, 1, wx.EXPAND | wx.ALL, 5)
panel.SetSizer(topSizer)
return panel
# Mouse events for DnD and append/insert mode
def OnLeftDownOnButton(self, evt):
self.posDown = evt.GetPosition()
self.btnDown = evt.GetEventObject()
forceSibling = evt.ControlDown()
forceInsert = evt.ShiftDown()
g.Presenter.updateCreateState(forceSibling, forceInsert)
evt.Skip()
def OnButton(self, evt):
if not self.drag: evt.Skip()
self.drag = False
if view.frame.miniFrame:
if not g.useAUI and not g.conf.embedPanel:
view.frame.miniFrame.Raise()
else:
view.frame.Raise()
def OnMotionOnButton(self, evt):
# Detect dragging
if evt.Dragging() and evt.LeftIsDown():
d = evt.GetPosition() - self.posDown
if max(abs(d[0]), abs(d[1])) >= 5:
if self.btnDown.HasCapture():
# Generate up event to release mouse
evt = wx.MouseEvent(wx.EVT_LEFT_UP.typeId)
#evt.SetId(self.btnDown.GetId())
# Set flag to prevent normal button operation
self.drag = True
self.btnDown.ProcessEvent(evt)
self.StartDrag()
evt.Skip()
def StartDrag(self):
bm = self.btnDown.GetBitmapLabel()
# wxGTK requires wxIcon cursor, wxWIN and wxMAC require wxCursor
if wx.Platform == '__WXGTK__':
icon = wx.EmptyIcon()
icon.CopyFromBitmap(bm)
dragSource = wx.DropSource(self, icon)
else:
curs = wx.CursorFromImage(wx.ImageFromBitmap(bm))
dragSource = wx.DropSource(self, curs)
do = MyDataObject(str(self.btnDown.GetId()))
dragSource.SetData(do)
view.frame.SetStatusText('Release the mouse button over the test window')
dragSource.DoDragDrop()
view.testWin.RemoveHighlightDT()
view.testWin.EmptyTrash()
# Process key events
def OnKeyDown(self, evt):
print evt.GetEventObject(), evt.GetKeyCode()
evt.Skip()
return
if evt.GetKeyCode() == wx.WXK_CONTROL:
g.tree.ctrl = True
elif evt.GetKeyCode() == wx.WXK_SHIFT:
g.tree.shift = True
self.UpdateIfNeeded()
evt.Skip()
def OnKeyUp(self, evt):
if evt.GetKeyCode() == wx.WXK_CONTROL:
g.tree.ctrl = False
elif evt.GetKeyCode() == wx.WXK_SHIFT:
g.tree.shift = False
self.UpdateIfNeeded()
evt.Skip()
def OnMouse(self, evt):
# Update control and shift states
g.tree.ctrl = evt.ControlDown()
g.tree.shift = evt.ShiftDown()
self.UpdateIfNeeded()
evt.Skip()
# Update UI after key presses, if necessary
def UpdateIfNeeded(self):
tree = g.tree
if self.ctrl != tree.ctrl or self.shift != tree.shift:
# Enabling is needed only for ctrl
if self.ctrl != tree.ctrl: self.UpdateUI()
self.ctrl = tree.ctrl
self.shift = tree.shift
if tree.ctrl:
status = 'SBL'
elif tree.shift:
status = 'INS'
else:
status = ''
g.frame.SetStatusText(status, 1)
|