Commit 1cdd42c8634bfcf077812256651e2569e4836c31
1 parent
ee693621
Exists in
master
Using wx.GraphicsContext in GradientCtrl
Showing
1 changed file
with
59 additions
and
30 deletions
Show diff stats
invesalius/gui/widgets/gradient.py
... | ... | @@ -26,7 +26,12 @@ from wx.lib import intctrl |
26 | 26 | |
27 | 27 | from invesalius.gui.widgets.inv_spinctrl import InvSpinCtrl |
28 | 28 | |
29 | -PUSH_WIDTH = 7 | |
29 | +dc = wx.MemoryDC() | |
30 | +font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) | |
31 | +dc.SetFont(font) | |
32 | +PUSH_WIDTH = dc.GetTextExtent("M")[0] // 2 + 1 | |
33 | +del dc | |
34 | +del font | |
30 | 35 | |
31 | 36 | myEVT_SLIDER_CHANGED = wx.NewEventType() |
32 | 37 | EVT_SLIDER_CHANGED = wx.PyEventBinder(myEVT_SLIDER_CHANGED, 1) |
... | ... | @@ -70,6 +75,8 @@ class GradientSlider(wx.Panel): |
70 | 75 | self.colour = colour |
71 | 76 | self.selected = 0 |
72 | 77 | |
78 | + self._gradient_colours = None | |
79 | + | |
73 | 80 | self.CalculateControlPositions() |
74 | 81 | |
75 | 82 | def _bind_events_wx(self): |
... | ... | @@ -131,27 +138,43 @@ class GradientSlider(wx.Panel): |
131 | 138 | |
132 | 139 | width_transparency = self.max_position - self.min_position |
133 | 140 | |
134 | - # Drawing the left blank area. | |
135 | - pen = wx.Pen((0, 0, 0)) | |
136 | - brush = wx.Brush((0, 0, 0)) | |
137 | - dc.SetPen(pen) | |
138 | - dc.SetBrush(brush) | |
139 | - dc.DrawRectangle(0, 0, PUSH_WIDTH, h) | |
140 | - | |
141 | - # Drawing the right blank area. | |
142 | - pen = wx.Pen((255, 255, 255)) | |
143 | - brush = wx.Brush((255, 255, 255)) | |
144 | - dc.SetPen(pen) | |
145 | - dc.SetBrush(brush) | |
146 | - dc.DrawRectangle(x_init_gradient + width_gradient, 0, PUSH_WIDTH, h) | |
147 | - | |
148 | - # Drawing the gradient. | |
149 | - dc.GradientFillLinear( | |
150 | - (x_init_gradient, y_init_gradient, width_gradient, height_gradient), | |
151 | - (0, 0, 0), | |
152 | - (255, 255, 255), | |
153 | - ) | |
154 | - | |
141 | + gc = wx.GraphicsContext.Create(dc) | |
142 | + | |
143 | + points = ((0, PUSH_WIDTH, (0, 0, 0), (0, 0, 0)), | |
144 | + (PUSH_WIDTH, w - PUSH_WIDTH, (0, 0, 0), (255, 255, 255)), | |
145 | + (w - PUSH_WIDTH, w, (255, 255, 255), (255, 255, 255))) | |
146 | + | |
147 | + # Drawing the gradient background | |
148 | + for p1, p2, c1, c2 in points: | |
149 | + brush = gc.CreateLinearGradientBrush(p1, 0, p2, h, c1, c2) | |
150 | + gc.SetBrush(brush) | |
151 | + path = gc.CreatePath() | |
152 | + path.AddRectangle(p1, 0, p2 - p1, h) | |
153 | + gc.StrokePath(path) | |
154 | + gc.FillPath(path) | |
155 | + | |
156 | + # Drawing the transparent coloured overlay | |
157 | + if self._gradient_colours is None: | |
158 | + brush = wx.Brush(wx.Colour(*self.colour)) | |
159 | + pen = wx.Pen(wx.Colour(*self.colour)) | |
160 | + gc.SetBrush(brush) | |
161 | + gc.SetPen(pen) | |
162 | + path = gc.CreatePath() | |
163 | + path.AddRectangle(self.min_position, 0, width_transparency, h) | |
164 | + gc.FillPath(path) | |
165 | + gc.StrokePath(path) | |
166 | + else: | |
167 | + for i, (c1, c2) in enumerate(zip(self._gradient_colours, self._gradient_colours[1:])): | |
168 | + p1 = self.min_position + i * width_transparency / len(self._gradient_colours) | |
169 | + p2 = self.min_position + (i + 1) * width_transparency / len(self._gradient_colours) | |
170 | + brush = gc.CreateLinearGradientBrush(p1, 0, p2, h, c1, c2) | |
171 | + gc.SetBrush(brush) | |
172 | + path = gc.CreatePath() | |
173 | + path.AddRectangle(p1, 0, p2 - p1, h) | |
174 | + gc.StrokePath(path) | |
175 | + gc.FillPath(path) | |
176 | + | |
177 | + # Drawing the pushes | |
155 | 178 | try: |
156 | 179 | n = wx.RendererNative.Get() |
157 | 180 | except AttributeError: |
... | ... | @@ -161,14 +184,14 @@ class GradientSlider(wx.Panel): |
161 | 184 | n.DrawPushButton(self, dc, (x_init_push1, 0, PUSH_WIDTH, h)) |
162 | 185 | n.DrawPushButton(self, dc, (x_init_push2, 0, PUSH_WIDTH, h)) |
163 | 186 | |
164 | - # Drawing the transparent slider. | |
165 | - bytes = numpy.array(self.colour * width_transparency * h, "B") | |
166 | - try: | |
167 | - slider = wx.Bitmap.FromBufferRGBA(width_transparency, h, bytes) | |
168 | - except: | |
169 | - pass | |
170 | - else: | |
171 | - dc.DrawBitmap(slider, self.min_position, 0, True) | |
187 | + # # Drawing the transparent slider. | |
188 | + # bytes = numpy.array(self.colour * width_transparency * h, "B") | |
189 | + # try: | |
190 | + # slider = wx.Bitmap.FromBufferRGBA(width_transparency, h, bytes) | |
191 | + # except: | |
192 | + # pass | |
193 | + # else: | |
194 | + # dc.DrawBitmap(slider, self.min_position, 0, True) | |
172 | 195 | |
173 | 196 | def OnEraseBackGround(self, evt): |
174 | 197 | # Only to avoid this widget to flick. |
... | ... | @@ -316,6 +339,9 @@ class GradientSlider(wx.Panel): |
316 | 339 | def SetColour(self, colour): |
317 | 340 | self.colour = colour |
318 | 341 | |
342 | + def SetGradientColours(self, colors): | |
343 | + self._gradient_colours = colors | |
344 | + | |
319 | 345 | def SetMinRange(self, min_range): |
320 | 346 | self.min_range = min_range |
321 | 347 | self.CalculateControlPositions() |
... | ... | @@ -485,6 +511,9 @@ class GradientCtrl(wx.Panel): |
485 | 511 | self.gradient_slider.SetColour(colour) |
486 | 512 | self.gradient_slider.Refresh() |
487 | 513 | |
514 | + def SetGradientColours(self, colors): | |
515 | + self.gradient_slider.SetGradientColours(colors) | |
516 | + | |
488 | 517 | def SetMaxRange(self, value): |
489 | 518 | self.spin_min.SetMax(value) |
490 | 519 | self.spin_max.SetMax(value) | ... | ... |