Commit 83242a06378ed7faead941c0c4be8731ebf54ef7

Authored by tfmoraes
1 parent eb522836

ENH: the gradient widget has been rewritten

invesalius/data/slice_.py
... ... @@ -188,15 +188,11 @@ class Slice(object):
188 188 self.SetMaskEditionThreshold(index, threshold_range)
189 189  
190 190 def __set_current_mask_threshold(self, evt_pubsub):
191   - session = ses.Session()
192   - #FIXME: find a better way to implement this
193   - if (self.num_gradient >= 2) or \
194   - (session.project_status != const.PROJ_OPEN):
195   - threshold_range = evt_pubsub.data
196   - index = self.current_mask.index
197   - self.SetMaskThreshold(index, threshold_range)
198   - #Clear edited points
199   - self.current_mask.edited_points = {}
  191 + threshold_range = evt_pubsub.data
  192 + index = self.current_mask.index
  193 + self.SetMaskThreshold(index, threshold_range)
  194 + #Clear edited points
  195 + self.current_mask.edited_points = {}
200 196 self.num_gradient += 1
201 197  
202 198 def __set_current_mask_colour(self, pubsub_evt):
... ...
invesalius/gui/task_slice.py
... ... @@ -318,7 +318,7 @@ class MaskProperties(wx.Panel):
318 318 self.combo_thresh = combo_thresh
319 319  
320 320 ## LINE 4
321   - gradient = grad.GradientSlider(self, -1, -5000, 5000, 0, 5000,
  321 + gradient = grad.GradientCtrl(self, -1, -5000, 5000, 0, 5000,
322 322 (0, 255, 0, 100))
323 323 self.gradient = gradient
324 324  
... ... @@ -476,17 +476,17 @@ class MaskProperties(wx.Panel):
476 476  
477 477 def OnComboThresh(self, evt):
478 478 (thresh_min, thresh_max) = Project().threshold_modes[evt.GetString()]
479   - self.gradient.SetMinValue(thresh_min, True)
480   - self.gradient.SetMaxValue(thresh_max, True)
  479 + self.gradient.SetMinValue(thresh_min)
  480 + self.gradient.SetMaxValue(thresh_max)
  481 + self.OnSlideChanged(None)
481 482  
482 483 def OnSlideChanged(self, evt):
483 484 thresh_min = self.gradient.GetMinValue()
484 485 thresh_max = self.gradient.GetMaxValue()
485   - if self.bind_evt_gradient:
486   - ps.Publisher().sendMessage('Set threshold values',
487   - (thresh_min, thresh_max))
488   - session = ses.Session()
489   - session.ChangeProject()
  486 + ps.Publisher().sendMessage('Set threshold values',
  487 + (thresh_min, thresh_max))
  488 + session = ses.Session()
  489 + session.ChangeProject()
490 490  
491 491 def OnSelectColour(self, evt):
492 492 colour = evt.GetValue()
... ... @@ -549,7 +549,7 @@ class EditionTools(wx.Panel):
549 549 text_thresh = wx.StaticText(self, -1, _("Brush threshold range:"))
550 550  
551 551 ## LINE 4
552   - gradient_thresh = grad.GradientSlider(self, -1, 0, 5000, 0, 5000,
  552 + gradient_thresh = grad.GradientCtrl(self, -1, 0, 5000, 0, 5000,
553 553 (0, 0, 255, 100))
554 554 self.gradient_thresh = gradient_thresh
555 555 self.bind_evt_gradient = True
... ...
invesalius/gui/widgets/gradient.py
... ... @@ -19,547 +19,315 @@
19 19 # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
20 20 # detalhes.
21 21 #--------------------------------------------------------------------------
22   -
23 22 import sys
24 23  
25 24 import numpy
26 25 import wx
27   -import wx.lib.intctrl
28   -import wx.lib.pubsub as ps
29   -
30   -MINBORDER=1
31   -MAXBORDER=2
32 26  
33   -class SliderData(object):
34   - def __init__(self, minRange, maxRange, minValue, maxValue, colour):
35   - """
36   - minRange: The minimum value accepted.
37   - maxRange: The maximum value accepted.
38   - minValue: initial minimum value.
39   - maxValue: initial maximum value.
40   - colour: the colour associated, must be in RGBA form.
41   - """
42   - self.minRange = minRange
43   - self.maxRange = maxRange
44   - self.minValue = minValue
45   - self.maxValue = maxValue
46   - self.colour = colour
47   - self.wasChanged = True
  27 +from wx.lib import intctrl
48 28  
49   - def GetMinValue(self):
50   - return self.minValue
  29 +PUSH_WIDTH = 7
51 30  
52   - def GetMaxValue(self):
53   - return self.maxValue
54   -
55   - def SetMinValue(self, value):
56   - if value < self.minRange:
57   - value = self.minRange
58   - self.minValue = value
59   - self.wasChanged = True
60   -
61   - def SetMaxValue(self, value):
62   - if value > self.maxRange:
63   - value = self.maxRange
64   - self.maxValue = value
65   - self.wasChanged = True
66   -
67   - def GetMinRange(self):
68   - return self.minRange
69   -
70   - def GetMaxRange(self):
71   - return self.maxRange
72   -
73   - def SetMinRange(self, value):
74   - if value < self.minValue:
75   - self.SetMinValue(value)
76   - self.minRange = value
77   - self.wasChanged = True
  31 +myEVT_SLIDER_CHANGE = wx.NewEventType()
  32 +EVT_SLIDER_CHANGE = wx.PyEventBinder(myEVT_SLIDER_CHANGE, 1)
78 33  
79   - def SetMaxRange(self, value):
80   - if value > self.maxValue:
81   - self.SetMaxValue(value)
82   - self.maxRange = value
83   - self.wasChanged = True
  34 +myEVT_THRESHOLD_CHANGE = wx.NewEventType()
  35 +EVT_THRESHOLD_CHANGE = wx.PyEventBinder(myEVT_THRESHOLD_CHANGE, 1)
84 36  
85   - def GetColour(self):
86   - return self.colour
  37 +class SliderEvent(wx.PyCommandEvent):
  38 + def __init__(self , evtType, id, minRange, maxRange, minValue, maxValue):
  39 + wx.PyCommandEvent.__init__(self, evtType, id,)
  40 + self.min_range = minRange
  41 + self.max_range = maxRange
  42 + self.minimun = minValue
  43 + self.maximun = maxValue
87 44  
88   - def SetColour(self, colour):
  45 +class GradientSlider(wx.Panel):
  46 + def __init__(self, parent, id, minRange, maxRange, minValue, maxValue, colour):
  47 + super(GradientSlider, self).__init__(parent, id, size = (100, 25))
  48 + self._bind_events_wx()
  49 +
  50 + self.min_range = minRange
  51 + self.max_range = maxRange
  52 + self.minimun = minValue
  53 + self.maximun = maxValue
89 54 self.colour = colour
90   - self.wasChanged = True
91   -
92   - def GetRange(self):
93   - return self.maxRange - self.minRange
94   -
95   -
96   -class SliderControler(object):
97   - def __init__(self, slider):
98   - self.slider = slider
99   - ps.Publisher().subscribe(self.SetMinValue, "ChangeMinValue")
100   - ps.Publisher().subscribe(self.SetMaxValue, "ChangeMaxValue")
101   -
102   - def SetMinValue(self, data):
103   - self.slider.SetMinValue(data.data)
  55 + self.selected = 0
104 56  
105   - def SetMaxValue(self, data):
106   - self.slider.SetMaxValue(data.data)
  57 + self.CalculateControlPositions()
107 58  
108   - def GetMinValue(self):
109   - return self.slider.GetMinValue()
  59 + def _bind_events_wx(self):
  60 + self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
  61 + self.Bind(wx.EVT_LEFT_UP, self.OnRelease)
  62 + self.Bind(wx.EVT_PAINT, self.OnPaint)
  63 + self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround)
  64 + self.Bind(wx.EVT_MOTION, self.OnMotion)
  65 + self.Bind(wx.EVT_SIZE, self.OnSize)
110 66  
111   - def GetMaxValue(self):
112   - return self.slider.GetMaxValue()
  67 + def OnPaint(self, evt):
  68 + dc = wx.BufferedPaintDC(self)
  69 + dc.Clear()
  70 +
  71 + w, h = self.GetSize()
  72 + width_gradient = w - 2*PUSH_WIDTH
  73 + height_gradient = h
  74 + x_init_gradient = PUSH_WIDTH
  75 + y_init_gradient = 0
  76 +
  77 + x_init_push1 = self.min_position - PUSH_WIDTH
  78 + x_init_push2 = self.max_position
  79 +
  80 + width_transparency = self.max_position - self.min_position
  81 +
  82 + pen = wx.Pen((0, 0, 0))
  83 + brush = wx.Brush((0, 0, 0))
  84 + dc.SetPen(pen)
  85 + dc.SetBrush(brush)
  86 + dc.DrawRectangle(0, 0, PUSH_WIDTH, h)
  87 +
  88 + pen = wx.Pen((255, 255, 255))
  89 + brush = wx.Brush((255, 255, 255))
  90 + dc.SetPen(pen)
  91 + dc.SetBrush(brush)
  92 + dc.DrawRectangle(x_init_gradient + width_gradient, 0, PUSH_WIDTH, h)
  93 +
  94 + dc.GradientFillLinear((x_init_gradient, y_init_gradient,
  95 + width_gradient, height_gradient),
  96 + (0, 0, 0), (255,255, 255))
  97 +
  98 + n = wx.RendererNative_Get()
  99 + n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h))
  100 + n.DrawPushButton(self, dc, (x_init_push2, 0, PUSH_WIDTH, h))
113 101  
  102 + bytes = numpy.array(self.colour * width_transparency * h, 'B')
  103 + try:
  104 + slider = wx.BitmapFromBufferRGBA(width_transparency, h, bytes)
  105 + except:
  106 + pass
  107 + else:
  108 + dc.DrawBitmap(slider, self.min_position, 0, True)
114 109  
115   -class SliderBorder(object):
116   - def __init__(self, pos, width, WindowWidth, type):
117   - """
118   - pos: initial border's position
119   - width: border's width
120   - """
121   - self.pos = pos
122   - self.width = width
123   - self.WindowWidth = WindowWidth
124   - self.type = type
  110 + def OnEraseBackGround(self, evt):
  111 + pass
125 112  
126   - def IsOver(self, x):
127   - """
128   - Is the mouse over border?
129   - """
130   - return self.pos <= x <= self.pos + self.width
  113 + def OnMotion(self, evt):
  114 + x = evt.GetX()
  115 + w, h = self.GetSize()
  116 + if self.selected == 1:
  117 + x -= self._delta
  118 + if x - PUSH_WIDTH < 0:
  119 + x = PUSH_WIDTH
  120 + elif x >= self.max_position:
  121 + x = self.max_position
  122 +
  123 + value = self._min_position_to_minimun(x)
  124 + self.minimun = value
  125 + self.min_position = x
  126 + self.Refresh()
  127 + self._generate_event()
  128 +
  129 + elif self.selected == 2:
  130 + x -= self._delta
  131 + if x + PUSH_WIDTH > w:
  132 + x = w - PUSH_WIDTH
  133 + elif x < self.min_position:
  134 + x = self.min_position
  135 +
  136 + value = self._max_position_to_maximun(x)
  137 + self.maximun = value
  138 + self.max_position = x
  139 + self.Refresh()
  140 + self._generate_event()
  141 +
  142 + elif self.selected == 3:
  143 + x -= self._delta
  144 + slider_size = self.max_position - self.min_position
  145 + diff_values = self.maximun - self.minimun
  146 +
  147 + if x - PUSH_WIDTH < 0:
  148 + min_x = PUSH_WIDTH
  149 + self.minimun = self._min_position_to_minimun(min_x)
  150 + self.maximun = self.minimun + diff_values
  151 + self.CalculateControlPositions()
  152 +
  153 + elif x + slider_size + PUSH_WIDTH > w:
  154 + max_x = w - PUSH_WIDTH
  155 + self.maximun = self._max_position_to_maximun(max_x)
  156 + self.minimun = self.maximun - diff_values
  157 + self.CalculateControlPositions()
131 158  
132   - def DoSlide(self, slide):
133   - """
134   - Move the border
135   - """
136   - self.pos += slide
137   - if self.type == MINBORDER and self.pos < 0:
138   - self.pos = 0
139   - elif self.type == MAXBORDER and self.pos+self.width >= self.WindowWidth:
140   - self.pos = self.WindowWidth - self.width
  159 + else:
  160 + min_x = x
  161 + self.minimun = self._min_position_to_minimun(min_x)
  162 + self.maximun = self.minimun + diff_values
  163 + self.CalculateControlPositions()
141 164  
142   - def SetPosition(self, pos):
143   - """
144   - Move the border
145   - """
146   - self.pos = pos
147   - if self.type == MINBORDER and self.pos < 0:
148   - self.pos = 0
149   - elif self.type == MAXBORDER and self.pos+self.width >= self.WindowWidth:
150   - self.pos = self.WindowWidth - self.width
  165 + self.Refresh()
  166 + self._generate_event()
  167 + evt.Skip()
  168 +
  169 +
  170 + def OnClick(self, evt):
  171 + x = evt.GetX()
  172 + if self.min_position - PUSH_WIDTH <= x <= self.min_position:
  173 + self.selected = 1
  174 + self._delta = x - self.min_position
  175 + elif self.max_position <= x <= self.max_position + PUSH_WIDTH:
  176 + self.selected = 2
  177 + self._delta = x - self.max_position
  178 + elif self.min_position <= x <= self.max_position:
  179 + self.selected = 3
  180 + self._delta = x - self.min_position
  181 + evt.Skip()
  182 +
  183 + def OnRelease(self, evt):
  184 + self.selected = 0
  185 + evt.Skip()
  186 +
  187 + def OnSize(self, evt):
  188 + self.CalculateControlPositions()
  189 + self.Refresh()
  190 + evt.Skip()
151 191  
152   - def GetCursor(self):
  192 + def CalculateControlPositions(self):
153 193 """
154   - This function returns the cursor related to the SliderBorder
  194 + Calculates the Min and Max control position based on the size of this
  195 + widget.
155 196 """
156   - return wx.StockCursor(wx.CURSOR_SIZEWE)
157   -
158   - def SetWindowWidth(self, width):
159   - self.WindowWith = width
160   -
161   - def GetPosition(self):
162   - return self.pos
  197 + w, h = self.GetSize()
  198 + window_width = w - 2*PUSH_WIDTH
  199 + proportion = window_width / float(self.max_range - self.min_range)
163 200  
  201 + self.min_position = int(round((self.minimun - self.min_range) * \
  202 + proportion)) + PUSH_WIDTH
  203 + self.max_position = int(round((self.maximun - self.min_range) * \
  204 + proportion)) + PUSH_WIDTH
  205 + print self.min_position, self.max_position
164 206  
165   -class SliderControl(object):
166   - def __init__(self, sliderData, width, height):
167   - """
168   - sliderData: associated sliderData, where the info is.
169   - width: SliderControl's width
170   - height: SliderControl's height
171   - """
172   - self.width = width
173   - self.height = height
174   - self.imgSlider = None
175   - self.SliderData = sliderData
176   - self.ToResize = False
177   - ps.Publisher().subscribe(self.SetMinValue, "SetMinValue")
178   -
179   - def Resize(self, WindowWidth, WindowHeight):
180   - """
181   - Occurs when parent panel resizes, then the slider resize too keeping the
182   - proportion
183   - """
184   - self.WindowWidth = WindowWidth
185   - self.MinBorder.SetWindowWidth(WindowWidth)
186   - self.MaxBorder.SetWindowWidth(WindowWidth)
187   - proportion = WindowWidth/float(self.SliderData.GetRange())
188   - self.MinPoint = int(round((self.SliderData.GetMinValue() -\
189   - self.SliderData.minRange) * proportion))
190   - self.MaxPoint = int(round((self.SliderData.GetMaxValue() -\
191   - self.SliderData.minRange)* proportion))
192   - self.width = self.MaxPoint - self.MinPoint
193   - self.height = WindowHeight
194   - self.ToResize = True
195   -
196   - def GetSliderControl(self):
197   - """
198   - Returns the slider control
199   - """
200   - if not self.imgSlider or self.ToResize or self.SliderData.wasChanged:
201   - bytes = numpy.array(self.SliderData.GetColour() * self.width * self.height, 'B')
202   - self.imgSlider = wx.BitmapFromBufferRGBA(self.width, self.height, bytes)
203   - self.ToResize = False
204   - self.SliderData.wasChanged = False
205   - return self.imgSlider
206   -
207   - def GetCursor(self):
208   - """
209   - Returns the slider associated to the SliderControl
  207 + def _max_position_to_maximun(self, max_position):
  208 + """
  209 + Calculates the min and max value based on the control positions.
210 210 """
211   - return wx.StockCursor(wx.CURSOR_ARROW)
  211 + w, h = self.GetSize()
  212 + window_width = w - 2*PUSH_WIDTH
  213 + proportion = window_width / float(self.max_range - self.min_range)
212 214  
213   - def DoSlide(self, slide):
214   - """
215   - Moves the SliderControl with associated borders
216   - """
217   - if slide + self.MinPoint >= 0 \
218   - and slide + self.MaxPoint <= self.WindowWidth:
219   - self.MinPoint += slide
220   - self.MaxPoint = self.MinPoint + self.width
221   - self.SetMinValueByMinPoint()
222   - self.SetMaxValueByMaxPoint()
223   - self.MinBorder.DoSlide(slide)
224   - self.MaxBorder.DoSlide(slide)
225   -
226   - def IsOver(self, x):
227   - """
228   - The mouse cursor is over me?
229   - """
230   - return self.MinPoint <= x <= self.MaxPoint
231   -
232   - def SetMinValueByMinPoint(self):
233   - """
234   - Sets the minimum slider value based on the min point position
235   - """
236   - proportion = self.WindowWidth/float(self.SliderData.GetRange())
237   - self.SliderData.SetMinValue(int(round(self.MinPoint/proportion +\
238   - self.SliderData.minRange)))
  215 + maximun = int(round((max_position - PUSH_WIDTH)/proportion + \
  216 + self.min_range))
239 217  
240   - def SetMaxValueByMaxPoint(self):
241   - """
242   - Sets the maximum slider values based on the max point position
243   - """
244   - proportion = self.WindowWidth/float(self.SliderData.GetRange())
245   - self.SliderData.SetMaxValue(int(round(self.MaxPoint/proportion +\
246   - self.SliderData.minRange)))
247   -
248   - def SetMaxPointByMaxValue(self):
249   - # proportion = self.WindowWidth/float(self.SliderData.GetRange())
250   - #self.SetMaxPoint(int((self.SliderData.GetMaxValue() \
251   - # -self.SliderData.minRange)*proportion))
252   - self.MaxBorder.pos = self.MaxPoint
253   -
254   - def SetMinPointByMinValue(self):
255   - # proportion = self.WindowWidth/float(self.SliderData.GetRange())
256   - #self.SetMinPoint(int((self.SliderData.GetMinValue() \
257   - # -self.SliderData.minRange)*proportion))
258   - self.MinBorder.pos = self.MinPoint
259   -
260   - def SetMinPoint(self, x):
261   - """
262   - Sets the min point position in pixels
263   - """
264   - self.MinPoint = x
265   - self.width = self.MaxPoint - self.MinPoint
266   - self.SetMinValueByMinPoint()
267   - self.ToResize = True
  218 + return maximun
268 219  
269   - def SetMaxPoint(self, x):
270   - """
271   - Sets the max point position in pixels
272   - """
273   - self.MaxPoint = x
274   - self.width = self.MaxPoint - self.MinPoint
275   - self.SetMaxValueByMaxPoint()
276   - self.ToResize = True
277   -
278   - def SetMinValue(self, min):
279   - self.SliderData.SetMinValue(min)
280   - proportion = self.WindowWidth/float(self.SliderData.GetRange())
281   - self.MinPoint = int(round((min - self.SliderData.minRange) * proportion))
282   - self.width = self.MaxPoint - self.MinPoint
283   - self.ToResize = True
284   - self.MinBorder.pos = self.MinPoint
285   -
286   - def SetMaxValue(self, max):
287   - self.SliderData.SetMaxValue(max)
288   - proportion = self.WindowWidth/float(self.SliderData.GetRange())
289   - self.MaxPoint = int(round((max - self.SliderData.minRange) * proportion))
290   - self.width = self.MaxPoint - self.MinPoint
291   - self.ToResize = True
292   - self.MaxBorder.pos = self.MaxPoint - self.MaxBorder.width
293   -
294   - def SetMinBorder(self, border):
295   - """
296   - Hello, I'm the min border. I do the hard work to squeeze and stretch
297   - the slider body together with my brother max border.
298   - """
299   - self.MinBorder = border
  220 + def _min_position_to_minimun(self, min_position):
  221 + w, h = self.GetSize()
  222 + window_width = w - 2*PUSH_WIDTH
  223 + proportion = window_width / float(self.max_range - self.min_range)
300 224  
301   - def SetMaxBorder(self, border):
302   - """
303   - And I'm the max border. I do the same work of my brother, I'm in the
304   - right side, while he is in left side.
305   - """
306   - self.MaxBorder = border
  225 + minimun = int(round((min_position - PUSH_WIDTH)/proportion + \
  226 + self.min_range))
307 227  
308   - def Calculate(self, object):
309   - """
310   - Calculate the new min or max point based on the border brothers position.
311   - """
312   - if object is self.MinBorder:
313   - self.SetMinPoint(object.pos)
314   - elif object is self.MaxBorder:
315   - self.SetMaxPoint(object.pos)
316   -
317   -
318   -class GradientPanel(wx.Panel):
319   - def __init__(self, parent, id, sliderData):
320   - super(GradientPanel, self).__init__(parent, id, size=wx.Size(200,50))
321   - self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
322   - self.SetMinSize((100, 20))
323   - self.imgGradient = None
324   - self.SliderData = sliderData
325   - self.Slider = SliderControl(self.SliderData, 1, 1)
326   - self.BorderMin = SliderBorder(self.SliderData.GetMinValue(), 7,
327   - self.GetSize().GetWidth(),
328   - MINBORDER)
329   - self.BorderMax = SliderBorder(self.SliderData.GetMaxValue()-10, 7,
330   - self.GetSize().GetWidth(),
331   - MAXBORDER)
332   - self.Slider.SetMinBorder(self.BorderMin)
333   - self.Slider.SetMaxBorder(self.BorderMax)
334   - self._DoBinds()
335   - self.Show()
  228 + return minimun
336 229  
337   - def _DoBinds(self):
338   - self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
339   - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
340   - self.Bind(wx.EVT_PAINT, self.OnPaint)
341   - self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround)
342   - self.Bind(wx.EVT_MOTION, self.OnMotion)
343   - self.Bind(wx.EVT_SIZE, self.OnSize)
344   - self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
345   -
346   - def GetMin(self):
347   - return self.SliderData.GetMinValue()
348   -
349   - def GetMax(self):
350   - return self.SliderData.GetMaxValue()
  230 + def SetColour(self, colour):
  231 + self.colour = colour
351 232  
352   - def SetMinValue(self, min):
353   - self.Slider.SetMinValue(min)
  233 + def SetMinRange(self, min_range):
  234 + self.min_range = min_range
  235 + self.CalculateControlPositions()
354 236 self.Refresh()
355 237  
356   - def SetMaxValue(self, max):
357   - self.Slider.SetMaxValue(max)
  238 + def SetMaxRange(self, max_range):
  239 + self.max_range = max_range
  240 + self.CalculateControlPositions()
358 241 self.Refresh()
359 242  
360   - def GetObjectAt(self, x):
361   - """
362   - Is there a object(border or slider) at this x position? Then return it
363   - to me.
364   - """
365   - if self.BorderMin.IsOver(x):
366   - return self.BorderMin
367   - elif self.BorderMax.IsOver(x):
368   - return self.BorderMax
369   - elif self.Slider.IsOver(x):
370   - return self.Slider
371   - else:
372   - return None
373   -
374   - def DrawSliderControl(self, dc):
375   - try:
376   - dc.DrawBitmap(self.Slider.GetSliderControl(),
377   - self.Slider.MinPoint, 0, True)
378   - except (ValueError, RuntimeError):
379   - print "ERROR"
380   -
381   - def DrawSliderBorders(self, dc):
382   - n = wx.RendererNative_Get()
383   - n.DrawPushButton(self, dc, (self.BorderMin.pos, 0,
384   - self.BorderMin.width,
385   - self.Slider.height))
386   - n.DrawPushButton(self, dc, (self.BorderMax.pos, 0,
387   - self.BorderMax.width,
388   - self.Slider.height))
389   -
390   - def OnPaint(self, e):
391   - """
392   - Occurs when panel must be refreshed, it redraw the sliderControl and
393   - borders.
394   - """
395   - dc = wx.BufferedPaintDC(self)
396   - dc.Clear()
397   - w,h = self.GetSize()
398   - dc.GradientFillLinear((0, 0, w, h), (0, 0, 0), (255, 255, 255))
399   - self.DrawSliderControl(dc)
400   - self.DrawSliderBorders(dc)
401   -
402   - def OnEraseBackGround(self, e):
403   - pass
404   -
405   - def OnSize(self, e):
406   - """
407   - OMG! Incredible how I fatten and become thin easily, then I must adjust my
408   - clothes(SliderControl and the borders).
409   - """
410   - w,h = self.GetSize()
411   - if w > 0:
412   - self.Slider.Resize(w, h)
413   - self.BorderMin.pos = self.Slider.MinPoint
414   - self.BorderMax.pos = self.Slider.MaxPoint - self.BorderMax.width
415   - self.Refresh()
416   - e.Skip()
417   -
418   - def OnClick(self, e):
419   - """
420   - Occurs when the user click in the panel. It verifies if the click was
421   - over an object and memorise the mouse position to do the slide.
422   - """
423   - self.SelectedObject = self.GetObjectAt(e.GetX())
424   - self.MousePositionX = e.GetX()
  243 + def SetMinimun(self, minimun):
  244 + self.minimun = minimun
  245 + self.CalculateControlPositions()
  246 + self.Refresh()
425 247  
426   - def OnLeftUp(self, e):
427   - """
428   - Occurs when left mouse button is freed then the selected object must be
429   - freed too.
430   - """
431   - self.SelectedObject = None
  248 + def SetMaximun(self, maximun):
  249 + self.maximun = maximun
  250 + self.CalculateControlPositions()
  251 + self.Refresh()
432 252  
433   - def OnMotion(self, e):
434   - """
435   - This is where the slide occurs ...
436   - """
437   - x = e.GetX()
438   - # but the user must be dragging a selected object
439   - if e.Dragging() and self.SelectedObject:
440   - slide = x - self.MousePositionX
441   - self.MousePositionX += slide
442   - self.SetCursor(self.SelectedObject.GetCursor())
443   - if isinstance(self.SelectedObject, SliderControl):
444   - self.SelectedObject.DoSlide(slide)
445   - else:
446   - self.SelectedObject.SetPosition(x)
447   - self.Slider.Calculate(self.SelectedObject)
448   - if self.GetMin() >= self.GetMax():
449   - self.SetMinValue(self.GetMax()-1)
450   - self.Slider.SetMinPointByMinValue()
451   - # dc = wx.ClientDC(self)
452   - evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId())
453   - self.GetEventHandler().ProcessEvent(evt)
454   - self.Refresh()
455   - # else only the mouse cursor must be changed based on the object the
456   - # mouse is over
457   - else:
458   - try:
459   - self.SetCursor(self.GetObjectAt(x).GetCursor())
460   - except AttributeError:
461   - self.SetCursor(wx.NullCursor)
462   -
463   - def OnMouseWheel(self, e):
464   - v = e.GetWheelRotation()/e.GetWheelDelta()
465   - self.SliderData.SetMinValue(self.SliderData.GetMinValue()+v)
466   - self.SliderData.SetMaxValue(self.SliderData.GetMaxValue()+v)
467   - evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId())
  253 + def _generate_event(self):
  254 + evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId(), self.min_range,
  255 + self.max_range, self.minimun, self.maximun)
468 256 self.GetEventHandler().ProcessEvent(evt)
469   - self.Refresh()
470 257  
471 258  
472   -class GradientSlider(wx.Panel):
473   - def __init__(self, parent, id, minRange, maxRange, min, max, colour):
474   - super(GradientSlider, self).__init__(parent, id)
475   - self.slided = 0
  259 +class GradientCtrl(wx.Panel):
  260 + def __init__(self, parent, id, minRange, maxRange, minValue, maxValue, colour):
  261 + super(GradientCtrl, self).__init__(parent, id)
476 262 self.sizer = wx.BoxSizer(wx.HORIZONTAL)
477 263 self.SetSizer(self.sizer)
478 264 self.sizer.Fit(self)
479 265 self.SetAutoLayout(1)
480   - self.SliderData = SliderData(minRange, maxRange, min, max, colour)
481   - self.transparency = colour[3]
482   - self.DrawControls()
483   - #ps.Publisher().subscribe(self.SetMinValue, ('SetMinValue'))
  266 + self.min_range = minRange
  267 + self.max_range = maxRange
  268 + self.minimun = minValue
  269 + self.maximun = maxValue
  270 + self.colour = colour
  271 + self._draw_controls()
  272 + self._bind_events_wx()
  273 + self.SetBackgroundColour((0, 255, 0))
484 274 self.Show()
485   - self.__bind_events()
486   -
487   - def __bind_events(self):
488   - ps.Publisher().subscribe(self.SetColour, 'Change Gradient Colour')
489   - ps.Publisher().subscribe(self.SetMinValue, 'Change Gradient MinValue')
490   - ps.Publisher().subscribe(self.SetMaxValue, 'Change Gradient MaxValue')
491   -
492   - def DrawControls(self):
493   - """self.SpinMin = wx.SpinCtrl(parent=self,
494   - id=-1,
495   - initial=self.SliderData.minValue,
496   - min=self.SliderData.minRange,
497   - max=self.SliderData.maxRange,
498   - size=wx.Size(55,15))
499   - self.SpinMin.SetValue(self.SliderData.minValue) # needed in MacOS 10.5.5
500   -
501   - for child in self.SpinMin.GetChildren():
502   - if isinstance(child, wx.TextCtrl):
503   - child.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
504   -
505   - self.SpinMax = wx.SpinCtrl(parent=self,
506   - id=-1,
507   - initial=self.SliderData.maxValue,
508   - min=self.SliderData.minRange,
509   - max=self.SliderData.maxRange,
510   - size=wx.Size(55,15))
511   - self.SpinMax.SetValue(self.SliderData.maxValue) # needed in MacOS 10.5.5
512   -
513   - for child in self.SpinMax.GetChildren():
514   - if isinstance(child, wx.TextCtrl):
515   - child.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)"""
516   -
517   -
518   - self.SpinMin = wx.lib.intctrl.IntCtrl(self, size=(40,20), style=wx.TE_PROCESS_ENTER)
519   - #self.SpinMin.SetLimited(True)
520   - self.SpinMin.SetBounds(self.SliderData.minRange, self.SliderData.maxRange)
  275 +
  276 + def _draw_controls(self):
  277 + self.gradient_slider = GradientSlider(self, -1, self.min_range,
  278 + self.max_range, self.minimun,
  279 + self.maximun, self.colour)
  280 +
  281 + self.spin_min = intctrl.IntCtrl(self, size=(40,20),
  282 + style=wx.TE_PROCESS_ENTER)
  283 + self.spin_min.SetValue(self.minimun)
521 284 if sys.platform != 'win32':
522   - self.SpinMin.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
523   - self.SpinMin.SetValue(self.SliderData.minValue)
  285 + self.spin_min.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
524 286  
525   - self.SpinMax = wx.lib.intctrl.IntCtrl(self, size=(40,20), style=wx.TE_PROCESS_ENTER)
526   - #self.SpinMax.SetLimited(True)
527   - self.SpinMax.SetBounds(self.SliderData.minRange, self.SliderData.maxRange)
  287 + self.spin_max = intctrl.IntCtrl(self, size=(40,20),
  288 + style=wx.TE_PROCESS_ENTER)
  289 + self.spin_max.SetValue(self.maximun)
528 290 if sys.platform != 'win32':
529   - self.SpinMax.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
530   - self.SpinMax.SetValue(self.SliderData.maxValue)
531   -
532   - self.GradientPanel = GradientPanel(self, -1, self.SliderData)
533   - self.sizer.Add(self.SpinMin, 0, wx.CENTRE)#, wx.EXPAND)
534   - self.sizer.AddSpacer(5)
535   - self.sizer.Add(self.GradientPanel, 2, wx.CENTRE)#, wx.EXPAND)
536   - self.sizer.AddSpacer(5)
537   - self.sizer.Add(self.SpinMax, 0, wx.CENTRE)#, wx.EXPAND)
538   - self._DoBinds()
539   -
540   - def _DoBinds(self):
541   - self.SpinMin.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue)
542   - self.SpinMin.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange)
543   - self.SpinMin.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMinChange)
544   - self.SpinMin.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel)
545   -
546   - self.SpinMax.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue)
547   - self.SpinMax.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange)
548   - self.SpinMax.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMaxChange)
549   - self.SpinMax.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel)
550   -
551   - self.Bind(EVT_SLIDER_CHANGE, self.OnSlider, self.GradientPanel)
  291 + self.spin_max.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
  292 +
  293 + sizer = wx.BoxSizer(wx.HORIZONTAL)
  294 + sizer.Add(self.spin_min, 0, wx.EXPAND)
  295 + sizer.Add(self.gradient_slider, 1, wx.EXPAND)
  296 + sizer.Add(self.spin_max, 0, wx.EXPAND)
  297 + self.sizer.Add(sizer, 1, wx.EXPAND)
  298 +
  299 + def _bind_events_wx(self):
  300 + self.gradient_slider.Bind(EVT_SLIDER_CHANGE, self.OnSlider)
  301 +
  302 + # self.spin_min.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue)
  303 + self.spin_min.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange)
  304 + self.spin_min.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMinChange)
  305 + self.spin_min.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel)
  306 +
  307 + # self.spin_max.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue)
  308 + self.spin_max.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange)
  309 + self.spin_max.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMaxChange)
  310 + self.spin_max.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel)
  311 +
  312 + def OnSlider(self, evt):
  313 + self.spin_min.SetValue(evt.minimun)
  314 + self.spin_max.SetValue(evt.maximun)
  315 + self.minimun = evt.minimun
  316 + self.maximun = evt.maximun
  317 + self._GenerateEvent()
552 318  
553 319 def _FireSpinMinChange(self, evt):
554   - value = int(self.SpinMin.GetValue())
  320 + value = int(self.spin_min.GetValue())
555 321 if value != self.GetMinValue():
556   - self.GradientPanel.SetMinValue(value)
  322 + self.gradient_slider.SetMinimun(value)
  323 + self.minimun = value
557 324 self._GenerateEvent()
558 325  
559 326 def _FireSpinMaxChange(self, evt):
560   - value = int(self.SpinMax.GetValue())
  327 + value = int(self.spin_max.GetValue())
561 328 if value != self.GetMaxValue():
562   - self.GradientPanel.SetMaxValue(value)
  329 + self.gradient_slider.SetMaximun(value)
  330 + self.maximun = value
563 331 self._GenerateEvent()
564 332  
565 333 def OnMinMouseWheel(self, e):
... ... @@ -570,97 +338,56 @@ class GradientSlider(wx.Panel):
570 338 v = self.GetMaxValue() + e.GetWheelRotation()/e.GetWheelDelta()
571 339 self.SetMaxValue(v)
572 340  
  341 + def SetColour(self, colour):
  342 + colour = colour + [90,]
  343 + self.colour = colour
  344 + self.gradient_slider.SetColour(colour)
  345 + self.gradient_slider.Refresh()
  346 +
  347 + def SetMaxRange(self, value):
  348 + self.spin_min.SetMax(value)
  349 + self.spin_max.SetMax(value)
  350 + self.gradient_slider.SetMaxRange(value)
  351 +
  352 + def SetMinRange(self, value):
  353 + self.spin_min.SetMin(value)
  354 + self.spin_max.SetMin(value)
  355 + self.gradient_slider.SetMinRange(value)
  356 +
  357 + def SetMaxValue(self, value):
  358 + value = int(value)
  359 + self.spin_max.SetValue(value)
  360 + self.gradient_slider.SetMaximun(value)
  361 + self.maximun = value
  362 +
  363 + def SetMinValue(self, value):
  364 + value = int(value)
  365 + self.spin_min.SetValue(value)
  366 + self.gradient_slider.SetMinimun(value)
  367 + self.minimun = value
  368 +
573 369 def ChangeMinValue(self, e):
574 370 # Why do I need to change slide min value if it has been changed for
575 371 # the user?
576 372 print "ChangeMinValue", self.slided
577 373 if not self.slided:
578   - self.GradientPanel.SetMinValue(int(self.SpinMin.GetValue()))
  374 + self.gradient_slider.SetMinValue(int(self.spin_min.GetValue()))
579 375 self._GenerateEvent()
580 376  
581 377 def ChangeMaxValue(self, e):
582 378 # Why do I need to change slide min value if it has been changed for
583 379 # the user?
584 380 if not self.slided:
585   - self.GradientPanel.SetMaxValue(int(self.SpinMax.GetValue()))
  381 + self.gradient_slider.SetMaxValue(int(self.spin_max.GetValue()))
586 382 self._GenerateEvent()
587 383  
588   - def OnSlider(self, e):
589   - self.slided = 1
590   - self.SpinMin.SetValue(int(self.SliderData.GetMinValue()))
591   - self.SpinMax.SetValue(int(self.SliderData.GetMaxValue()))
592   - self.slided = 0
593   - self._GenerateEvent()
594   -
595   - def SetMinValue(self, value, do_event=False):
596   - try:
597   - value = value.data
598   - except AttributeError:
599   - pass
600   - self.slided = 0 if do_event else 1
601   - self.GradientPanel.SetMinValue(value)
602   - self.SpinMin.SetValue(int(value))
603   - self.GradientPanel.Refresh()
604   -
605   - def SetMaxValue(self, value, do_event=False):
606   - try:
607   - value = value.data
608   - except AttributeError:
609   - pass
610   - self.slided = 0 if do_event else 1
611   - self.GradientPanel.SetMaxValue(value)
612   - self.SpinMax.SetValue(int(value))
613   - self.GradientPanel.Refresh()
614   -
615   - def SetMaxRange(self, value):
616   - self.SliderData.SetMaxRange(value)
617   - self.SpinMin.SetMax(value)
618   - self.SpinMax.SetMax(value)
619   - self.GradientPanel.Refresh()
620   -
621   - def SetMinRange(self, value):
622   - self.SliderData.SetMinRange(value)
623   - self.SpinMin.SetMin(value)
624   - self.SpinMax.SetMin(value)
625   - self.GradientPanel.Refresh()
626   -
627 384 def GetMaxValue(self):
628   - return self.SliderData.GetMaxValue()
  385 + return self.maximun
629 386  
630 387 def GetMinValue(self):
631   - return self.SliderData.GetMinValue()
632   -
633   - def GetSliderData(self):
634   - """
635   - Returns the associated SliderData.
636   - """
637   - return self.SliderData
638   -
639   - def SetColour(self, colour, transparency=None):
640   - """
641   - Set colour of the slider, the colour must be in RGB format.
642   - And values varying 0-255.
643   - """
644   - if transparency is not None:
645   - A = transparency
646   - else:
647   - A = self.transparency
648   - (R,G,B) = colour
649   - self.SliderData.SetColour((R,G,B,A))
650   - self.GradientPanel.Refresh()
  388 + return self.minimun
651 389  
652 390 def _GenerateEvent(self):
653   - evt = SliderEvent(myEVT_THRESHOLD_CHANGE, self.GetId())
  391 + evt = SliderEvent(myEVT_THRESHOLD_CHANGE, self.GetId(), self.min_range,
  392 + self.max_range, self.minimun, self.maximun)
654 393 self.GetEventHandler().ProcessEvent(evt)
655   -
656   -class SliderEvent(wx.PyCommandEvent):
657   - def __init__(self , evtType, id):
658   - wx.PyCommandEvent.__init__(self, evtType, id)
659   -
660   -myEVT_SLIDER_CHANGE = wx.NewEventType()
661   -# This event occurs when the user do slide, used only internaly
662   -EVT_SLIDER_CHANGE = wx.PyEventBinder(myEVT_SLIDER_CHANGE, 1)
663   -
664   -myEVT_THRESHOLD_CHANGE = wx.NewEventType()
665   -# This event occurs when the user change the threshold.
666   -EVT_THRESHOLD_CHANGE = wx.PyEventBinder(myEVT_THRESHOLD_CHANGE, 1)
... ...