Patch attached. This is actually not rebased against the committing of the lines/etc patchset to HEAD. I expect it to apply fine regardless.
From 153e24849427e9a86c79a5d95c711961c08d50ac Mon Sep 17 00:00:00 2001 From: David Gowers <00a...@gmail.com> Date: Tue, 28 Feb 2012 17:41:49 +1030 Subject: [PATCH] Simplify curve related code and remove some cruft
--- gui/curve.py | 141 ++++++++++++++++++-------------------------------------- gui/toolbar.py | 25 +++------- 2 files changed, 51 insertions(+), 115 deletions(-) diff --git a/gui/curve.py b/gui/curve.py index 1b1699c..b2da577 100644 --- a/gui/curve.py +++ b/gui/curve.py @@ -15,11 +15,22 @@ class CurveWidget(gtk.DrawingArea): """Widget for modifying a (restricted) nonlinear curve. """ __gtype_name__ = 'CurveWidget' + snapto = (0.0, 0.25, 0.5, 0.75, 1.0) + ylock = {} - def __init__(self, changed_cb=None, magnetic=True): + def __init__(self, changed_cb=None, magnetic=True, npoints = None, ylockgroups = ()): gtk.DrawingArea.__init__(self) - self.points = [(0.0, 0.5), (1.0, 0.0)] # doesn't matter - self.maxpoints = 8 + self.points = [(0.0, 0.2), (.25, .5), (.75, .75), (1.0, 1.0)] # doesn't matter + self.npoints = npoints + if ylockgroups: + self.ylock = {} + for items in ylockgroups: + for thisitem in items: + others = list(items) + others.remove (thisitem) + self.ylock[thisitem] = tuple(others) + + self.maxpoints = 8 if not npoints else npoints self.grabbed = None if changed_cb is None: self.changed_cb = lambda *a: None @@ -54,6 +65,13 @@ class CurveWidget(gtk.DrawingArea): y = float(y) / height return (x, y) + def set_point (self, index, value): + y = value[1] + self.points[index] = value + if index in self.ylock: + for lockedto in self.ylock[index]: + self.points[lockedto] = (self.points[lockedto][0], y) + def button_press_cb(self, widget, event): if not event.button == 1: return x, y = self.eventpoint(event.x, event.y) @@ -64,7 +82,7 @@ class CurveWidget(gtk.DrawingArea): if nearest is None or dist < mindist: mindist = dist nearest = i - if mindist > 0.05 and len(self.points) < self.maxpoints: + if not self.npoints and mindist > 0.05 and len(self.points) < self.maxpoints: insertpos = 0 for i in range(len(self.points)): if self.points[i][0] < x: @@ -73,15 +91,17 @@ class CurveWidget(gtk.DrawingArea): if y > 1.0: y = 1.0 if y < 0.0: y = 0.0 self.points.insert(insertpos, (x, y)) + # XXX and update ylockgroups? + # nearest = insertpos self.queue_draw() - #if nearest == 0: + #if nearest == 0: # # first point cannot be grabbed # display = gtk.gdk.display_get_default() # display.beep() #else: - #assert self.grabbed is None # This did happen. I think it's save to ignore? + #assert self.grabbed is None # This did happen. I think it's save to ignore? # I guess it's because gtk can generate button press event without corresponding release. self.grabbed = nearest @@ -94,11 +114,21 @@ class CurveWidget(gtk.DrawingArea): self.grabbed = None # notify user of the widget self.changed_cb(self) - + def motion_notify_cb(self, widget, event): if self.grabbed is None: return x, y = self.eventpoint(event.x, event.y) i = self.grabbed + # XXX this may fail for non contiguous groups. + if i in self.ylock: + possiblei = None + if x > self.points[max(self.ylock[i])][0]: + possiblei = max ((i,) + self.ylock[i]) + elif x < self.points[min(self.ylock[i])][0]: + possiblei = min ((i,) + self.ylock[i]) + if (possiblei != None and + abs (self.points[i][0] - self.points[possiblei][0]) < 0.001): + i = possiblei out = False # by default, the point cannot be removed by drawing it out if i == len(self.points)-1: # last point stays right @@ -108,21 +138,24 @@ class CurveWidget(gtk.DrawingArea): leftbound = rightbound = 0.0 else: # other points can be dragged out - if y > 1.1 or y < -0.1: out = True + if not self.npoints and (y > 1.1 or y < -0.1): out = True leftbound = self.points[i-1][0] rightbound = self.points[i+1][0] - if x <= leftbound - 0.02 or x >= rightbound + 0.02: out = True + if not self.npoints and (x <= leftbound - 0.02 or x >= rightbound + 0.02): out = True if out: self.points[i] = None else: if y > 1.0: y = 1.0 if y < 0.0: y = 0.0 if self.magnetic: - if y > 0.48 and y < 0.52: y = 0.5 - if x > 0.48 and x < 0.52: x = 0.5 + xdiff = [abs(x - v) for v in self.snapto] + ydiff = [abs(y - v) for v in self.snapto] + if min (xdiff) < 0.015 and min (ydiff) < 0.015: + y = self.snapto[ydiff.index (min (ydiff))] + x = self.snapto[xdiff.index (min (xdiff))] if x < leftbound: x = leftbound if x > rightbound: x = rightbound - self.points[i] = (x, y) + self.set_point(i, (x, y)) self.queue_draw() def expose_cb(self, widget, event): @@ -167,90 +200,6 @@ class CurveWidget(gtk.DrawingArea): return True -class FixedCurveWidget(CurveWidget): - """CurveWidget subclass with fixed number of points, and support for locking together the Y values of - specific points. - """ - snapto = (0.0, 0.25, 0.5, 0.75, 1.0) - ylock = {} - def __init__(self, npoints=4, ylockgroups = (), changed_cb=None, magnetic=True): - CurveWidget.__init__ (self, changed_cb, magnetic) - self.points = [(0.0, 0.2), (.25, .5), (.75, .75), (1.0, 1.0)] # doesn't matter - self.npoints = npoints - if ylockgroups: - self.ylock = {} - for items in ylockgroups: - for thisitem in items: - others = list(items) - others.remove (thisitem) - self.ylock[thisitem] = tuple(others) - def set_point (self, index, value): - y = value[1] - self.points[index] = value - if index in self.ylock: - for lockedto in self.ylock[index]: - self.points[lockedto] = (self.points[lockedto][0], y) - def button_press_cb(self, widget, event): - if not event.button == 1: return - x, y = self.eventpoint(event.x, event.y) - nearest = None - for i in range(len(self.points)): - px, py = self.points[i] - dist = abs(px - x) + 0.5*abs(py - y) - if nearest is None or dist < mindist: - mindist = dist - nearest = i - self.grabbed = nearest - -# def button_release_cb(self, widget, event): -# if not event.button == 1: return -# if self.grabbed: -# i = self.grabbed -# # THE FOLLOWING MEANS WHAT? -# if self.points[i] is None: -# self.points.pop(i) -# self.grabbed = None -# # notify user of the widget -# self.changed_cb(self) - def motion_notify_cb(self, widget, event): - if self.grabbed is None: return - x, y = self.eventpoint(event.x, event.y) - i = self.grabbed - # XXX this may fail for non contiguous groups. - if i in self.ylock: - possiblei = None - if x > self.points[max(self.ylock[i])][0]: - possiblei = max ((i,) + self.ylock[i]) - elif x < self.points[min(self.ylock[i])][0]: - possiblei = min ((i,) + self.ylock[i]) - if (possiblei != None and - abs (self.points[i][0] - self.points[possiblei][0]) < 0.001): - i = possiblei - out = False # by default, the point cannot be removed by drawing it out - if i == len(self.points)-1: - # last point stays right - leftbound = rightbound = 1.0 - elif i == 0: - # first point stays left - leftbound = rightbound = 0.0 - else: - # other points can be dragged out - leftbound = self.points[i-1][0] - rightbound = self.points[i+1][0] - - if y > 1.0: y = 1.0 - if y < 0.0: y = 0.0 - if self.magnetic: - xdiff = [abs(x - v) for v in self.snapto] - ydiff = [abs(y - v) for v in self.snapto] - if min (xdiff) < 0.015 and min (ydiff) < 0.015: - y = self.snapto[ydiff.index (min (ydiff))] - x = self.snapto[xdiff.index (min (xdiff))] - if x < leftbound: x = leftbound - if x > rightbound: x = rightbound - self.set_point(i, (x, y)) - self.queue_draw() - if __name__ == '__main__': win = gtk.Window() diff --git a/gui/toolbar.py b/gui/toolbar.py index 32b4514..1bb78f7 100644 --- a/gui/toolbar.py +++ b/gui/toolbar.py @@ -146,8 +146,6 @@ class LineDropdownToolItem (gtk.ToolItem): 'exit_pressure': (3,1), 'line_head': (1,0), 'line_tail': (2,0), - #'line_head': (1,0), - #'line_tail': (2,0), } @@ -200,25 +198,17 @@ class LineDropdownToolItem (gtk.ToolItem): def settings_frame(): self.vbox.pack_start(frame, True, True) - from curve import FixedCurveWidget - curve = FixedCurveWidget(npoints = 4, - ylockgroups = ((1,2),), - changed_cb = self.curve_changed_cb) + from curve import CurveWidget + curve = CurveWidget(npoints = 4, + ylockgroups = ((1,2),), + changed_cb = self.curve_changed_cb) frame.add(curve) - curve.set_tooltip_text('Curve defining the amount of pressure applied at different points in the line.\n' - '\nX position = distance along the line;\n' - ' minimum X = start of line;\n' - ' maximum X = end of line\n' - ' (only the central two points can be adjusted in X axis)\n' - 'Y position = amount of pressure\n' - ' The Y position of the central two points is locked together.\n') - #vbox.pack_start(w, True, True) curve.show() curve.points = [(0.0,0.2), (0.33,.5),(0.66, .5), (1.0,.33)] for setting in (self.shape_settings): value = app.line_mode_adjustment[setting].get_value() index, subindex = self.settings_coordinate[setting] - if not setting.startswith ('line'):#if setting != 'line_head + if not setting.startswith ('line'): value = 1.0 - value coord = None if subindex == 0: @@ -228,7 +218,7 @@ class LineDropdownToolItem (gtk.ToolItem): curve.set_point(index, coord) self.curve_changed_cb (curve) - frame = widgets.section_frame(_("Line Shape")) + frame = widgets.section_frame(_("Line Pressure")) settings_frame() def curve_changed_cb(self, curve): @@ -239,9 +229,6 @@ class LineDropdownToolItem (gtk.ToolItem): if not setting.startswith('line'): value = 1.0 - value value = max(0.0001, value) - print ('setting %r (%s) to %f' % (coord, setting, value)) - #if setting.startswith('line_'): - # setting = {'line_tail':'line_head', 'line_head':'line_tail'}[setting] self.app.linemode.change_line_setting(setting, value) print (curve.points) -- 1.7.9.2
_______________________________________________ Mypaint-discuss mailing list Mypaint-discuss@gna.org https://mail.gna.org/listinfo/mypaint-discuss