Here's a version rebased against latest master.
From 617ec7ee1881c89063d9f63208a49e9312ccd5c5 Mon Sep 17 00:00:00 2001
From: David Gowers <[email protected]>
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 | 24 +++-------
2 files changed, 51 insertions(+), 114 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 1678965..2b1de36 100644
--- a/gui/toolbar.py
+++ b/gui/toolbar.py
@@ -198,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:
@@ -226,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):
@@ -237,11 +229,7 @@ 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)
class ColorDropdownToolItem (gtk.ToolItem):
--
1.7.9.2
_______________________________________________
Mypaint-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/mypaint-discuss