From 83242a06378ed7faead941c0c4be8731ebf54ef7 Mon Sep 17 00:00:00 2001 From: tfmoraes Date: Thu, 20 May 2010 13:18:05 +0000 Subject: [PATCH] ENH: the gradient widget has been rewritten --- invesalius/data/slice_.py | 14 +++++--------- invesalius/gui/task_slice.py | 18 +++++++++--------- invesalius/gui/widgets/gradient.py | 847 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 files changed, 301 insertions(+), 578 deletions(-) diff --git a/invesalius/data/slice_.py b/invesalius/data/slice_.py index 555b74a..c7ebefe 100644 --- a/invesalius/data/slice_.py +++ b/invesalius/data/slice_.py @@ -188,15 +188,11 @@ class Slice(object): self.SetMaskEditionThreshold(index, threshold_range) def __set_current_mask_threshold(self, evt_pubsub): - session = ses.Session() - #FIXME: find a better way to implement this - if (self.num_gradient >= 2) or \ - (session.project_status != const.PROJ_OPEN): - threshold_range = evt_pubsub.data - index = self.current_mask.index - self.SetMaskThreshold(index, threshold_range) - #Clear edited points - self.current_mask.edited_points = {} + threshold_range = evt_pubsub.data + index = self.current_mask.index + self.SetMaskThreshold(index, threshold_range) + #Clear edited points + self.current_mask.edited_points = {} self.num_gradient += 1 def __set_current_mask_colour(self, pubsub_evt): diff --git a/invesalius/gui/task_slice.py b/invesalius/gui/task_slice.py index 7c5e85f..5f82794 100644 --- a/invesalius/gui/task_slice.py +++ b/invesalius/gui/task_slice.py @@ -318,7 +318,7 @@ class MaskProperties(wx.Panel): self.combo_thresh = combo_thresh ## LINE 4 - gradient = grad.GradientSlider(self, -1, -5000, 5000, 0, 5000, + gradient = grad.GradientCtrl(self, -1, -5000, 5000, 0, 5000, (0, 255, 0, 100)) self.gradient = gradient @@ -476,17 +476,17 @@ class MaskProperties(wx.Panel): def OnComboThresh(self, evt): (thresh_min, thresh_max) = Project().threshold_modes[evt.GetString()] - self.gradient.SetMinValue(thresh_min, True) - self.gradient.SetMaxValue(thresh_max, True) + self.gradient.SetMinValue(thresh_min) + self.gradient.SetMaxValue(thresh_max) + self.OnSlideChanged(None) def OnSlideChanged(self, evt): thresh_min = self.gradient.GetMinValue() thresh_max = self.gradient.GetMaxValue() - if self.bind_evt_gradient: - ps.Publisher().sendMessage('Set threshold values', - (thresh_min, thresh_max)) - session = ses.Session() - session.ChangeProject() + ps.Publisher().sendMessage('Set threshold values', + (thresh_min, thresh_max)) + session = ses.Session() + session.ChangeProject() def OnSelectColour(self, evt): colour = evt.GetValue() @@ -549,7 +549,7 @@ class EditionTools(wx.Panel): text_thresh = wx.StaticText(self, -1, _("Brush threshold range:")) ## LINE 4 - gradient_thresh = grad.GradientSlider(self, -1, 0, 5000, 0, 5000, + gradient_thresh = grad.GradientCtrl(self, -1, 0, 5000, 0, 5000, (0, 0, 255, 100)) self.gradient_thresh = gradient_thresh self.bind_evt_gradient = True diff --git a/invesalius/gui/widgets/gradient.py b/invesalius/gui/widgets/gradient.py index b80a87a..4f82bd0 100755 --- a/invesalius/gui/widgets/gradient.py +++ b/invesalius/gui/widgets/gradient.py @@ -19,547 +19,315 @@ # PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais # detalhes. #-------------------------------------------------------------------------- - import sys import numpy import wx -import wx.lib.intctrl -import wx.lib.pubsub as ps - -MINBORDER=1 -MAXBORDER=2 -class SliderData(object): - def __init__(self, minRange, maxRange, minValue, maxValue, colour): - """ - minRange: The minimum value accepted. - maxRange: The maximum value accepted. - minValue: initial minimum value. - maxValue: initial maximum value. - colour: the colour associated, must be in RGBA form. - """ - self.minRange = minRange - self.maxRange = maxRange - self.minValue = minValue - self.maxValue = maxValue - self.colour = colour - self.wasChanged = True +from wx.lib import intctrl - def GetMinValue(self): - return self.minValue +PUSH_WIDTH = 7 - def GetMaxValue(self): - return self.maxValue - - def SetMinValue(self, value): - if value < self.minRange: - value = self.minRange - self.minValue = value - self.wasChanged = True - - def SetMaxValue(self, value): - if value > self.maxRange: - value = self.maxRange - self.maxValue = value - self.wasChanged = True - - def GetMinRange(self): - return self.minRange - - def GetMaxRange(self): - return self.maxRange - - def SetMinRange(self, value): - if value < self.minValue: - self.SetMinValue(value) - self.minRange = value - self.wasChanged = True +myEVT_SLIDER_CHANGE = wx.NewEventType() +EVT_SLIDER_CHANGE = wx.PyEventBinder(myEVT_SLIDER_CHANGE, 1) - def SetMaxRange(self, value): - if value > self.maxValue: - self.SetMaxValue(value) - self.maxRange = value - self.wasChanged = True +myEVT_THRESHOLD_CHANGE = wx.NewEventType() +EVT_THRESHOLD_CHANGE = wx.PyEventBinder(myEVT_THRESHOLD_CHANGE, 1) - def GetColour(self): - return self.colour +class SliderEvent(wx.PyCommandEvent): + def __init__(self , evtType, id, minRange, maxRange, minValue, maxValue): + wx.PyCommandEvent.__init__(self, evtType, id,) + self.min_range = minRange + self.max_range = maxRange + self.minimun = minValue + self.maximun = maxValue - def SetColour(self, colour): +class GradientSlider(wx.Panel): + def __init__(self, parent, id, minRange, maxRange, minValue, maxValue, colour): + super(GradientSlider, self).__init__(parent, id, size = (100, 25)) + self._bind_events_wx() + + self.min_range = minRange + self.max_range = maxRange + self.minimun = minValue + self.maximun = maxValue self.colour = colour - self.wasChanged = True - - def GetRange(self): - return self.maxRange - self.minRange - - -class SliderControler(object): - def __init__(self, slider): - self.slider = slider - ps.Publisher().subscribe(self.SetMinValue, "ChangeMinValue") - ps.Publisher().subscribe(self.SetMaxValue, "ChangeMaxValue") - - def SetMinValue(self, data): - self.slider.SetMinValue(data.data) + self.selected = 0 - def SetMaxValue(self, data): - self.slider.SetMaxValue(data.data) + self.CalculateControlPositions() - def GetMinValue(self): - return self.slider.GetMinValue() + def _bind_events_wx(self): + self.Bind(wx.EVT_LEFT_DOWN, self.OnClick) + self.Bind(wx.EVT_LEFT_UP, self.OnRelease) + self.Bind(wx.EVT_PAINT, self.OnPaint) + self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround) + self.Bind(wx.EVT_MOTION, self.OnMotion) + self.Bind(wx.EVT_SIZE, self.OnSize) - def GetMaxValue(self): - return self.slider.GetMaxValue() + def OnPaint(self, evt): + dc = wx.BufferedPaintDC(self) + dc.Clear() + + w, h = self.GetSize() + width_gradient = w - 2*PUSH_WIDTH + height_gradient = h + x_init_gradient = PUSH_WIDTH + y_init_gradient = 0 + + x_init_push1 = self.min_position - PUSH_WIDTH + x_init_push2 = self.max_position + + width_transparency = self.max_position - self.min_position + + pen = wx.Pen((0, 0, 0)) + brush = wx.Brush((0, 0, 0)) + dc.SetPen(pen) + dc.SetBrush(brush) + dc.DrawRectangle(0, 0, PUSH_WIDTH, h) + + pen = wx.Pen((255, 255, 255)) + brush = wx.Brush((255, 255, 255)) + dc.SetPen(pen) + dc.SetBrush(brush) + dc.DrawRectangle(x_init_gradient + width_gradient, 0, PUSH_WIDTH, h) + + dc.GradientFillLinear((x_init_gradient, y_init_gradient, + width_gradient, height_gradient), + (0, 0, 0), (255,255, 255)) + + n = wx.RendererNative_Get() + n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h)) + n.DrawPushButton(self, dc, (x_init_push2, 0, PUSH_WIDTH, h)) + bytes = numpy.array(self.colour * width_transparency * h, 'B') + try: + slider = wx.BitmapFromBufferRGBA(width_transparency, h, bytes) + except: + pass + else: + dc.DrawBitmap(slider, self.min_position, 0, True) -class SliderBorder(object): - def __init__(self, pos, width, WindowWidth, type): - """ - pos: initial border's position - width: border's width - """ - self.pos = pos - self.width = width - self.WindowWidth = WindowWidth - self.type = type + def OnEraseBackGround(self, evt): + pass - def IsOver(self, x): - """ - Is the mouse over border? - """ - return self.pos <= x <= self.pos + self.width + def OnMotion(self, evt): + x = evt.GetX() + w, h = self.GetSize() + if self.selected == 1: + x -= self._delta + if x - PUSH_WIDTH < 0: + x = PUSH_WIDTH + elif x >= self.max_position: + x = self.max_position + + value = self._min_position_to_minimun(x) + self.minimun = value + self.min_position = x + self.Refresh() + self._generate_event() + + elif self.selected == 2: + x -= self._delta + if x + PUSH_WIDTH > w: + x = w - PUSH_WIDTH + elif x < self.min_position: + x = self.min_position + + value = self._max_position_to_maximun(x) + self.maximun = value + self.max_position = x + self.Refresh() + self._generate_event() + + elif self.selected == 3: + x -= self._delta + slider_size = self.max_position - self.min_position + diff_values = self.maximun - self.minimun + + if x - PUSH_WIDTH < 0: + min_x = PUSH_WIDTH + self.minimun = self._min_position_to_minimun(min_x) + self.maximun = self.minimun + diff_values + self.CalculateControlPositions() + + elif x + slider_size + PUSH_WIDTH > w: + max_x = w - PUSH_WIDTH + self.maximun = self._max_position_to_maximun(max_x) + self.minimun = self.maximun - diff_values + self.CalculateControlPositions() - def DoSlide(self, slide): - """ - Move the border - """ - self.pos += slide - if self.type == MINBORDER and self.pos < 0: - self.pos = 0 - elif self.type == MAXBORDER and self.pos+self.width >= self.WindowWidth: - self.pos = self.WindowWidth - self.width + else: + min_x = x + self.minimun = self._min_position_to_minimun(min_x) + self.maximun = self.minimun + diff_values + self.CalculateControlPositions() - def SetPosition(self, pos): - """ - Move the border - """ - self.pos = pos - if self.type == MINBORDER and self.pos < 0: - self.pos = 0 - elif self.type == MAXBORDER and self.pos+self.width >= self.WindowWidth: - self.pos = self.WindowWidth - self.width + self.Refresh() + self._generate_event() + evt.Skip() + + + def OnClick(self, evt): + x = evt.GetX() + if self.min_position - PUSH_WIDTH <= x <= self.min_position: + self.selected = 1 + self._delta = x - self.min_position + elif self.max_position <= x <= self.max_position + PUSH_WIDTH: + self.selected = 2 + self._delta = x - self.max_position + elif self.min_position <= x <= self.max_position: + self.selected = 3 + self._delta = x - self.min_position + evt.Skip() + + def OnRelease(self, evt): + self.selected = 0 + evt.Skip() + + def OnSize(self, evt): + self.CalculateControlPositions() + self.Refresh() + evt.Skip() - def GetCursor(self): + def CalculateControlPositions(self): """ - This function returns the cursor related to the SliderBorder + Calculates the Min and Max control position based on the size of this + widget. """ - return wx.StockCursor(wx.CURSOR_SIZEWE) - - def SetWindowWidth(self, width): - self.WindowWith = width - - def GetPosition(self): - return self.pos + w, h = self.GetSize() + window_width = w - 2*PUSH_WIDTH + proportion = window_width / float(self.max_range - self.min_range) + self.min_position = int(round((self.minimun - self.min_range) * \ + proportion)) + PUSH_WIDTH + self.max_position = int(round((self.maximun - self.min_range) * \ + proportion)) + PUSH_WIDTH + print self.min_position, self.max_position -class SliderControl(object): - def __init__(self, sliderData, width, height): - """ - sliderData: associated sliderData, where the info is. - width: SliderControl's width - height: SliderControl's height - """ - self.width = width - self.height = height - self.imgSlider = None - self.SliderData = sliderData - self.ToResize = False - ps.Publisher().subscribe(self.SetMinValue, "SetMinValue") - - def Resize(self, WindowWidth, WindowHeight): - """ - Occurs when parent panel resizes, then the slider resize too keeping the - proportion - """ - self.WindowWidth = WindowWidth - self.MinBorder.SetWindowWidth(WindowWidth) - self.MaxBorder.SetWindowWidth(WindowWidth) - proportion = WindowWidth/float(self.SliderData.GetRange()) - self.MinPoint = int(round((self.SliderData.GetMinValue() -\ - self.SliderData.minRange) * proportion)) - self.MaxPoint = int(round((self.SliderData.GetMaxValue() -\ - self.SliderData.minRange)* proportion)) - self.width = self.MaxPoint - self.MinPoint - self.height = WindowHeight - self.ToResize = True - - def GetSliderControl(self): - """ - Returns the slider control - """ - if not self.imgSlider or self.ToResize or self.SliderData.wasChanged: - bytes = numpy.array(self.SliderData.GetColour() * self.width * self.height, 'B') - self.imgSlider = wx.BitmapFromBufferRGBA(self.width, self.height, bytes) - self.ToResize = False - self.SliderData.wasChanged = False - return self.imgSlider - - def GetCursor(self): - """ - Returns the slider associated to the SliderControl + def _max_position_to_maximun(self, max_position): + """ + Calculates the min and max value based on the control positions. """ - return wx.StockCursor(wx.CURSOR_ARROW) + w, h = self.GetSize() + window_width = w - 2*PUSH_WIDTH + proportion = window_width / float(self.max_range - self.min_range) - def DoSlide(self, slide): - """ - Moves the SliderControl with associated borders - """ - if slide + self.MinPoint >= 0 \ - and slide + self.MaxPoint <= self.WindowWidth: - self.MinPoint += slide - self.MaxPoint = self.MinPoint + self.width - self.SetMinValueByMinPoint() - self.SetMaxValueByMaxPoint() - self.MinBorder.DoSlide(slide) - self.MaxBorder.DoSlide(slide) - - def IsOver(self, x): - """ - The mouse cursor is over me? - """ - return self.MinPoint <= x <= self.MaxPoint - - def SetMinValueByMinPoint(self): - """ - Sets the minimum slider value based on the min point position - """ - proportion = self.WindowWidth/float(self.SliderData.GetRange()) - self.SliderData.SetMinValue(int(round(self.MinPoint/proportion +\ - self.SliderData.minRange))) + maximun = int(round((max_position - PUSH_WIDTH)/proportion + \ + self.min_range)) - def SetMaxValueByMaxPoint(self): - """ - Sets the maximum slider values based on the max point position - """ - proportion = self.WindowWidth/float(self.SliderData.GetRange()) - self.SliderData.SetMaxValue(int(round(self.MaxPoint/proportion +\ - self.SliderData.minRange))) - - def SetMaxPointByMaxValue(self): - # proportion = self.WindowWidth/float(self.SliderData.GetRange()) - #self.SetMaxPoint(int((self.SliderData.GetMaxValue() \ - # -self.SliderData.minRange)*proportion)) - self.MaxBorder.pos = self.MaxPoint - - def SetMinPointByMinValue(self): - # proportion = self.WindowWidth/float(self.SliderData.GetRange()) - #self.SetMinPoint(int((self.SliderData.GetMinValue() \ - # -self.SliderData.minRange)*proportion)) - self.MinBorder.pos = self.MinPoint - - def SetMinPoint(self, x): - """ - Sets the min point position in pixels - """ - self.MinPoint = x - self.width = self.MaxPoint - self.MinPoint - self.SetMinValueByMinPoint() - self.ToResize = True + return maximun - def SetMaxPoint(self, x): - """ - Sets the max point position in pixels - """ - self.MaxPoint = x - self.width = self.MaxPoint - self.MinPoint - self.SetMaxValueByMaxPoint() - self.ToResize = True - - def SetMinValue(self, min): - self.SliderData.SetMinValue(min) - proportion = self.WindowWidth/float(self.SliderData.GetRange()) - self.MinPoint = int(round((min - self.SliderData.minRange) * proportion)) - self.width = self.MaxPoint - self.MinPoint - self.ToResize = True - self.MinBorder.pos = self.MinPoint - - def SetMaxValue(self, max): - self.SliderData.SetMaxValue(max) - proportion = self.WindowWidth/float(self.SliderData.GetRange()) - self.MaxPoint = int(round((max - self.SliderData.minRange) * proportion)) - self.width = self.MaxPoint - self.MinPoint - self.ToResize = True - self.MaxBorder.pos = self.MaxPoint - self.MaxBorder.width - - def SetMinBorder(self, border): - """ - Hello, I'm the min border. I do the hard work to squeeze and stretch - the slider body together with my brother max border. - """ - self.MinBorder = border + def _min_position_to_minimun(self, min_position): + w, h = self.GetSize() + window_width = w - 2*PUSH_WIDTH + proportion = window_width / float(self.max_range - self.min_range) - def SetMaxBorder(self, border): - """ - And I'm the max border. I do the same work of my brother, I'm in the - right side, while he is in left side. - """ - self.MaxBorder = border + minimun = int(round((min_position - PUSH_WIDTH)/proportion + \ + self.min_range)) - def Calculate(self, object): - """ - Calculate the new min or max point based on the border brothers position. - """ - if object is self.MinBorder: - self.SetMinPoint(object.pos) - elif object is self.MaxBorder: - self.SetMaxPoint(object.pos) - - -class GradientPanel(wx.Panel): - def __init__(self, parent, id, sliderData): - super(GradientPanel, self).__init__(parent, id, size=wx.Size(200,50)) - self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) - self.SetMinSize((100, 20)) - self.imgGradient = None - self.SliderData = sliderData - self.Slider = SliderControl(self.SliderData, 1, 1) - self.BorderMin = SliderBorder(self.SliderData.GetMinValue(), 7, - self.GetSize().GetWidth(), - MINBORDER) - self.BorderMax = SliderBorder(self.SliderData.GetMaxValue()-10, 7, - self.GetSize().GetWidth(), - MAXBORDER) - self.Slider.SetMinBorder(self.BorderMin) - self.Slider.SetMaxBorder(self.BorderMax) - self._DoBinds() - self.Show() + return minimun - def _DoBinds(self): - self.Bind(wx.EVT_LEFT_DOWN, self.OnClick) - self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackGround) - self.Bind(wx.EVT_MOTION, self.OnMotion) - self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) - - def GetMin(self): - return self.SliderData.GetMinValue() - - def GetMax(self): - return self.SliderData.GetMaxValue() + def SetColour(self, colour): + self.colour = colour - def SetMinValue(self, min): - self.Slider.SetMinValue(min) + def SetMinRange(self, min_range): + self.min_range = min_range + self.CalculateControlPositions() self.Refresh() - def SetMaxValue(self, max): - self.Slider.SetMaxValue(max) + def SetMaxRange(self, max_range): + self.max_range = max_range + self.CalculateControlPositions() self.Refresh() - def GetObjectAt(self, x): - """ - Is there a object(border or slider) at this x position? Then return it - to me. - """ - if self.BorderMin.IsOver(x): - return self.BorderMin - elif self.BorderMax.IsOver(x): - return self.BorderMax - elif self.Slider.IsOver(x): - return self.Slider - else: - return None - - def DrawSliderControl(self, dc): - try: - dc.DrawBitmap(self.Slider.GetSliderControl(), - self.Slider.MinPoint, 0, True) - except (ValueError, RuntimeError): - print "ERROR" - - def DrawSliderBorders(self, dc): - n = wx.RendererNative_Get() - n.DrawPushButton(self, dc, (self.BorderMin.pos, 0, - self.BorderMin.width, - self.Slider.height)) - n.DrawPushButton(self, dc, (self.BorderMax.pos, 0, - self.BorderMax.width, - self.Slider.height)) - - def OnPaint(self, e): - """ - Occurs when panel must be refreshed, it redraw the sliderControl and - borders. - """ - dc = wx.BufferedPaintDC(self) - dc.Clear() - w,h = self.GetSize() - dc.GradientFillLinear((0, 0, w, h), (0, 0, 0), (255, 255, 255)) - self.DrawSliderControl(dc) - self.DrawSliderBorders(dc) - - def OnEraseBackGround(self, e): - pass - - def OnSize(self, e): - """ - OMG! Incredible how I fatten and become thin easily, then I must adjust my - clothes(SliderControl and the borders). - """ - w,h = self.GetSize() - if w > 0: - self.Slider.Resize(w, h) - self.BorderMin.pos = self.Slider.MinPoint - self.BorderMax.pos = self.Slider.MaxPoint - self.BorderMax.width - self.Refresh() - e.Skip() - - def OnClick(self, e): - """ - Occurs when the user click in the panel. It verifies if the click was - over an object and memorise the mouse position to do the slide. - """ - self.SelectedObject = self.GetObjectAt(e.GetX()) - self.MousePositionX = e.GetX() + def SetMinimun(self, minimun): + self.minimun = minimun + self.CalculateControlPositions() + self.Refresh() - def OnLeftUp(self, e): - """ - Occurs when left mouse button is freed then the selected object must be - freed too. - """ - self.SelectedObject = None + def SetMaximun(self, maximun): + self.maximun = maximun + self.CalculateControlPositions() + self.Refresh() - def OnMotion(self, e): - """ - This is where the slide occurs ... - """ - x = e.GetX() - # but the user must be dragging a selected object - if e.Dragging() and self.SelectedObject: - slide = x - self.MousePositionX - self.MousePositionX += slide - self.SetCursor(self.SelectedObject.GetCursor()) - if isinstance(self.SelectedObject, SliderControl): - self.SelectedObject.DoSlide(slide) - else: - self.SelectedObject.SetPosition(x) - self.Slider.Calculate(self.SelectedObject) - if self.GetMin() >= self.GetMax(): - self.SetMinValue(self.GetMax()-1) - self.Slider.SetMinPointByMinValue() - # dc = wx.ClientDC(self) - evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId()) - self.GetEventHandler().ProcessEvent(evt) - self.Refresh() - # else only the mouse cursor must be changed based on the object the - # mouse is over - else: - try: - self.SetCursor(self.GetObjectAt(x).GetCursor()) - except AttributeError: - self.SetCursor(wx.NullCursor) - - def OnMouseWheel(self, e): - v = e.GetWheelRotation()/e.GetWheelDelta() - self.SliderData.SetMinValue(self.SliderData.GetMinValue()+v) - self.SliderData.SetMaxValue(self.SliderData.GetMaxValue()+v) - evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId()) + def _generate_event(self): + evt = SliderEvent(myEVT_SLIDER_CHANGE, self.GetId(), self.min_range, + self.max_range, self.minimun, self.maximun) self.GetEventHandler().ProcessEvent(evt) - self.Refresh() -class GradientSlider(wx.Panel): - def __init__(self, parent, id, minRange, maxRange, min, max, colour): - super(GradientSlider, self).__init__(parent, id) - self.slided = 0 +class GradientCtrl(wx.Panel): + def __init__(self, parent, id, minRange, maxRange, minValue, maxValue, colour): + super(GradientCtrl, self).__init__(parent, id) self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(self.sizer) self.sizer.Fit(self) self.SetAutoLayout(1) - self.SliderData = SliderData(minRange, maxRange, min, max, colour) - self.transparency = colour[3] - self.DrawControls() - #ps.Publisher().subscribe(self.SetMinValue, ('SetMinValue')) + self.min_range = minRange + self.max_range = maxRange + self.minimun = minValue + self.maximun = maxValue + self.colour = colour + self._draw_controls() + self._bind_events_wx() + self.SetBackgroundColour((0, 255, 0)) self.Show() - self.__bind_events() - - def __bind_events(self): - ps.Publisher().subscribe(self.SetColour, 'Change Gradient Colour') - ps.Publisher().subscribe(self.SetMinValue, 'Change Gradient MinValue') - ps.Publisher().subscribe(self.SetMaxValue, 'Change Gradient MaxValue') - - def DrawControls(self): - """self.SpinMin = wx.SpinCtrl(parent=self, - id=-1, - initial=self.SliderData.minValue, - min=self.SliderData.minRange, - max=self.SliderData.maxRange, - size=wx.Size(55,15)) - self.SpinMin.SetValue(self.SliderData.minValue) # needed in MacOS 10.5.5 - - for child in self.SpinMin.GetChildren(): - if isinstance(child, wx.TextCtrl): - child.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) - - self.SpinMax = wx.SpinCtrl(parent=self, - id=-1, - initial=self.SliderData.maxValue, - min=self.SliderData.minRange, - max=self.SliderData.maxRange, - size=wx.Size(55,15)) - self.SpinMax.SetValue(self.SliderData.maxValue) # needed in MacOS 10.5.5 - - for child in self.SpinMax.GetChildren(): - if isinstance(child, wx.TextCtrl): - child.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)""" - - - self.SpinMin = wx.lib.intctrl.IntCtrl(self, size=(40,20), style=wx.TE_PROCESS_ENTER) - #self.SpinMin.SetLimited(True) - self.SpinMin.SetBounds(self.SliderData.minRange, self.SliderData.maxRange) + + def _draw_controls(self): + self.gradient_slider = GradientSlider(self, -1, self.min_range, + self.max_range, self.minimun, + self.maximun, self.colour) + + self.spin_min = intctrl.IntCtrl(self, size=(40,20), + style=wx.TE_PROCESS_ENTER) + self.spin_min.SetValue(self.minimun) if sys.platform != 'win32': - self.SpinMin.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) - self.SpinMin.SetValue(self.SliderData.minValue) + self.spin_min.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) - self.SpinMax = wx.lib.intctrl.IntCtrl(self, size=(40,20), style=wx.TE_PROCESS_ENTER) - #self.SpinMax.SetLimited(True) - self.SpinMax.SetBounds(self.SliderData.minRange, self.SliderData.maxRange) + self.spin_max = intctrl.IntCtrl(self, size=(40,20), + style=wx.TE_PROCESS_ENTER) + self.spin_max.SetValue(self.maximun) if sys.platform != 'win32': - self.SpinMax.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) - self.SpinMax.SetValue(self.SliderData.maxValue) - - self.GradientPanel = GradientPanel(self, -1, self.SliderData) - self.sizer.Add(self.SpinMin, 0, wx.CENTRE)#, wx.EXPAND) - self.sizer.AddSpacer(5) - self.sizer.Add(self.GradientPanel, 2, wx.CENTRE)#, wx.EXPAND) - self.sizer.AddSpacer(5) - self.sizer.Add(self.SpinMax, 0, wx.CENTRE)#, wx.EXPAND) - self._DoBinds() - - def _DoBinds(self): - self.SpinMin.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue) - self.SpinMin.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange) - self.SpinMin.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMinChange) - self.SpinMin.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel) - - self.SpinMax.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue) - self.SpinMax.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange) - self.SpinMax.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMaxChange) - self.SpinMax.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel) - - self.Bind(EVT_SLIDER_CHANGE, self.OnSlider, self.GradientPanel) + self.spin_max.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.spin_min, 0, wx.EXPAND) + sizer.Add(self.gradient_slider, 1, wx.EXPAND) + sizer.Add(self.spin_max, 0, wx.EXPAND) + self.sizer.Add(sizer, 1, wx.EXPAND) + + def _bind_events_wx(self): + self.gradient_slider.Bind(EVT_SLIDER_CHANGE, self.OnSlider) + + # self.spin_min.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMinValue) + self.spin_min.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMinChange) + self.spin_min.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMinChange) + self.spin_min.Bind(wx.EVT_MOUSEWHEEL, self.OnMinMouseWheel) + + # self.spin_max.Bind(wx.lib.intctrl.EVT_INT, self.ChangeMaxValue) + self.spin_max.Bind(wx.EVT_KILL_FOCUS, self._FireSpinMaxChange) + self.spin_max.Bind(wx.EVT_TEXT_ENTER, self._FireSpinMaxChange) + self.spin_max.Bind(wx.EVT_MOUSEWHEEL, self.OnMaxMouseWheel) + + def OnSlider(self, evt): + self.spin_min.SetValue(evt.minimun) + self.spin_max.SetValue(evt.maximun) + self.minimun = evt.minimun + self.maximun = evt.maximun + self._GenerateEvent() def _FireSpinMinChange(self, evt): - value = int(self.SpinMin.GetValue()) + value = int(self.spin_min.GetValue()) if value != self.GetMinValue(): - self.GradientPanel.SetMinValue(value) + self.gradient_slider.SetMinimun(value) + self.minimun = value self._GenerateEvent() def _FireSpinMaxChange(self, evt): - value = int(self.SpinMax.GetValue()) + value = int(self.spin_max.GetValue()) if value != self.GetMaxValue(): - self.GradientPanel.SetMaxValue(value) + self.gradient_slider.SetMaximun(value) + self.maximun = value self._GenerateEvent() def OnMinMouseWheel(self, e): @@ -570,97 +338,56 @@ class GradientSlider(wx.Panel): v = self.GetMaxValue() + e.GetWheelRotation()/e.GetWheelDelta() self.SetMaxValue(v) + def SetColour(self, colour): + colour = colour + [90,] + self.colour = colour + self.gradient_slider.SetColour(colour) + self.gradient_slider.Refresh() + + def SetMaxRange(self, value): + self.spin_min.SetMax(value) + self.spin_max.SetMax(value) + self.gradient_slider.SetMaxRange(value) + + def SetMinRange(self, value): + self.spin_min.SetMin(value) + self.spin_max.SetMin(value) + self.gradient_slider.SetMinRange(value) + + def SetMaxValue(self, value): + value = int(value) + self.spin_max.SetValue(value) + self.gradient_slider.SetMaximun(value) + self.maximun = value + + def SetMinValue(self, value): + value = int(value) + self.spin_min.SetValue(value) + self.gradient_slider.SetMinimun(value) + self.minimun = value + def ChangeMinValue(self, e): # Why do I need to change slide min value if it has been changed for # the user? print "ChangeMinValue", self.slided if not self.slided: - self.GradientPanel.SetMinValue(int(self.SpinMin.GetValue())) + self.gradient_slider.SetMinValue(int(self.spin_min.GetValue())) self._GenerateEvent() def ChangeMaxValue(self, e): # Why do I need to change slide min value if it has been changed for # the user? if not self.slided: - self.GradientPanel.SetMaxValue(int(self.SpinMax.GetValue())) + self.gradient_slider.SetMaxValue(int(self.spin_max.GetValue())) self._GenerateEvent() - def OnSlider(self, e): - self.slided = 1 - self.SpinMin.SetValue(int(self.SliderData.GetMinValue())) - self.SpinMax.SetValue(int(self.SliderData.GetMaxValue())) - self.slided = 0 - self._GenerateEvent() - - def SetMinValue(self, value, do_event=False): - try: - value = value.data - except AttributeError: - pass - self.slided = 0 if do_event else 1 - self.GradientPanel.SetMinValue(value) - self.SpinMin.SetValue(int(value)) - self.GradientPanel.Refresh() - - def SetMaxValue(self, value, do_event=False): - try: - value = value.data - except AttributeError: - pass - self.slided = 0 if do_event else 1 - self.GradientPanel.SetMaxValue(value) - self.SpinMax.SetValue(int(value)) - self.GradientPanel.Refresh() - - def SetMaxRange(self, value): - self.SliderData.SetMaxRange(value) - self.SpinMin.SetMax(value) - self.SpinMax.SetMax(value) - self.GradientPanel.Refresh() - - def SetMinRange(self, value): - self.SliderData.SetMinRange(value) - self.SpinMin.SetMin(value) - self.SpinMax.SetMin(value) - self.GradientPanel.Refresh() - def GetMaxValue(self): - return self.SliderData.GetMaxValue() + return self.maximun def GetMinValue(self): - return self.SliderData.GetMinValue() - - def GetSliderData(self): - """ - Returns the associated SliderData. - """ - return self.SliderData - - def SetColour(self, colour, transparency=None): - """ - Set colour of the slider, the colour must be in RGB format. - And values varying 0-255. - """ - if transparency is not None: - A = transparency - else: - A = self.transparency - (R,G,B) = colour - self.SliderData.SetColour((R,G,B,A)) - self.GradientPanel.Refresh() + return self.minimun def _GenerateEvent(self): - evt = SliderEvent(myEVT_THRESHOLD_CHANGE, self.GetId()) + evt = SliderEvent(myEVT_THRESHOLD_CHANGE, self.GetId(), self.min_range, + self.max_range, self.minimun, self.maximun) self.GetEventHandler().ProcessEvent(evt) - -class SliderEvent(wx.PyCommandEvent): - def __init__(self , evtType, id): - wx.PyCommandEvent.__init__(self, evtType, id) - -myEVT_SLIDER_CHANGE = wx.NewEventType() -# This event occurs when the user do slide, used only internaly -EVT_SLIDER_CHANGE = wx.PyEventBinder(myEVT_SLIDER_CHANGE, 1) - -myEVT_THRESHOLD_CHANGE = wx.NewEventType() -# This event occurs when the user change the threshold. -EVT_THRESHOLD_CHANGE = wx.PyEventBinder(myEVT_THRESHOLD_CHANGE, 1) -- libgit2 0.21.2