offset_x, offset_y, scale, scale,
gtk.gdk.INTERP_BILINEAR)
+# What do the points[] mean?
+# Points = [x1, y1, x2, y2, x3, y3, x4, y4]
+# with x_scale = max(x_i) and y_scale = max(y_i)
class Setting:
"a specific setting for a specific brush"
def __init__(self, setting, parent_brush):
def set_base_value(self, value):
self.base_value = value
self.brush.set_base_value(self.setting.index, value)
+ def has_only_base_value(self):
+ for i in brushsettings.inputs:
+ if self.has_input(i):
+ return False
+ return True
+ def has_input(self, input):
+ points = self.points[input.index]
+ if points is None:
+ return False
+ #print points
+ return True
+ def has_input_nonlinear(self, input):
+ points = self.points[input.index]
+ if points is None:
+ return False
+ # also if it is linear but the x-axis was changed
+ if points[0] != 1.0: return True
+ # having one additional point is sufficient
+ if points[2] == 0.0 and points[3] == 0.0: return False
+ return True
+
def set_points(self, input, points):
if points is None:
self.points[input.index] = None
self.preview_mtime = None
def get_fileprefix(self, saving=False):
+ prefix = 'b'
+ if os.path.samefile(self.app.user_brushpath, self.app.stock_brushpath):
+ # working directly on brush collection, use different prefix
+ prefix = 's'
+
if not self.name:
i = 0
while 1:
- self.name = 'b%03d' % i
+ self.name = '%s%03d' % (prefix, i)
a = self.app.user_brushpath + self.name + '.myb'
b = self.app.stock_brushpath + self.name + '.myb'
if not os.path.isfile(a) and not os.path.isfile(b):
--- /dev/null
+# mypaint brush file
+color 90 68 16
+opaque 1.0 | stroke 0.62962962963 0.0 1.0 -1.0 0.0 0.0 0.0 0.0
+opaque_multiply 0.0 | pressure 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0
+radius_logarithmic 1.59 | stroke 0.598765432099 -1.4175 0.725308641975 -0.3290625 0.885802469136 -0.9871875 1.0 -2.43
+hardness 0.8
+dabs_per_basic_radius 0.0
+dabs_per_actual_radius 2.0
+dabs_per_second 0.0
+radius_by_random 0.0
+speed1_slowness 0.04
+speed2_slowness 0.8
+offset_by_random 0.0
+offset_by_speed 0.0
+offset_by_speed_slowness 1.0
+saturation_slowdown 0.0
+slow_tracking 0.0
+slow_tracking_per_dab 0.0
+color_value 0.39 | pressure 1.0 -1.14 0.0 0.0 0.0 0.0 0.0 0.0 | random 1.0 0.71 0.0 0.0 0.0 0.0 0.0 0.0 | stroke 0.0802469135802 -0.30125 0.614197530864 0.30125 0.753086419753 0.702916666667 1.0 0.953958333333
+color_saturation 0.0 | stroke 1.0 3.38 0.0 0.0 0.0 0.0 0.0 0.0
+color_hue 0.0 | speed 1.0 -1.37 0.0 0.0 0.0 0.0 0.0 0.0 | stroke 0.651234567901 -0.044375 0.706790123457 0.650833333333 0.891975308642 0.569479166667 1.0 -0.0
+adapt_color_from_image 0.0
+change_radius 0.0
+stroke_treshold 0.0
+stroke_duration_logarithmic 3.73 | pressure 0.496913580247 -0.190625 0.70987654321 -0.83875 1.0 -1.22 0.0 0.0 | speed2 0.231481481481 -1.91125 1.0 2.78 0.0 0.0 0.0 0.0
+stroke_holdtime 10.0
--- /dev/null
+# mypaint brush file
+color 90 68 16
+opaque 1.0 | stroke 0.62962962963 0.0 1.0 -1.0 0.0 0.0 0.0 0.0
+opaque_multiply 0.0 | pressure 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0
+radius_logarithmic 1.29 | stroke 0.598765432099 -1.4175 0.70987654321 0.2278125 0.898148148148 -0.2278125 1.0 -2.43
+hardness 0.8
+dabs_per_basic_radius 0.0
+dabs_per_actual_radius 2.0
+dabs_per_second 0.0
+radius_by_random 0.0
+speed1_slowness 0.04
+speed2_slowness 0.8
+offset_by_random 0.0
+offset_by_speed 0.0
+offset_by_speed_slowness 1.0
+saturation_slowdown 0.0
+slow_tracking 0.0
+slow_tracking_per_dab 0.0
+color_value 0.39 | pressure 1.0 -1.14 0.0 0.0 0.0 0.0 0.0 0.0 | random 1.0 0.71 0.0 0.0 0.0 0.0 0.0 0.0 | stroke 0.0802469135802 -0.30125 0.614197530864 0.30125 0.753086419753 0.702916666667 1.0 0.953958333333
+color_saturation 0.0 | stroke 1.0 3.38 0.0 0.0 0.0 0.0 0.0 0.0
+color_hue 0.0 | speed 1.0 -1.37 0.0 0.0 0.0 0.0 0.0 0.0 | stroke 0.651234567901 -0.044375 0.706790123457 0.650833333333 0.891975308642 0.569479166667 1.0 -0.0
+adapt_color_from_image 0.0
+change_radius 0.0
+stroke_treshold 0.0
+stroke_duration_logarithmic 2.76
+stroke_holdtime 10.0
# this file saves brushorder
# the first one (upper left) will be selected at startup
+s000
o043
ink
pencil
o033
o015
o501
+o665
+o519
o512
o945
o029
+old_b001
old_b008
o005
o007
old_b000
o036
o028
-old_b001
o017
o001
o018
except:
pass
+order = open('order.conf').read()
existing = [name[:-4] for name in os.listdir('.') if name.endswith('.myb')]
for name in existing:
if not name.startswith('b') or name[1] not in '0123456789': continue
print oldname, '==>', name
rename(oldname + '.myb', name + '.myb')
rename(oldname + '_prev.png', name + '_prev.png')
-
+ order = order.replace(oldname, name)
+
+open('order.conf', 'w').write(order)
if s.constant:
b2 = gtk.Label("=")
b2.set_alignment(0.5, 0.5)
+ adj.three_dots_button = None
else:
b2 = gtk.Button("...") # TODO: in red if some details are set
b2.connect('clicked', self.details_clicked_cb, adj, s)
+ adj.three_dots_button = b2
table.attach(eb, 0, 1, s.index, s.index+1, gtk.FILL, gtk.FILL, 5, 0)
table.attach(h, 1, 2, s.index, s.index+1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL)
def brush_selected_cb(self, brush_selected):
for s in brushsettings.settings:
- self.adj[s.index].set_value(self.app.brush.settings[s.index].base_value)
+ adj = self.adj[s.index]
+ s = self.app.brush.settings[s.index]
+ adj.set_value(s.base_value)
+ if adj.three_dots_button:
+ def set_label(s):
+ if adj.three_dots_button.get_label() == s: return
+ adj.three_dots_button.set_label(s)
+ if s.has_only_base_value():
+ set_label("...")
+ else:
+ set_label("X")
t.attach(l5, 1, 2, 3, 4, gtk.EXPAND, 0, 5, 0)
t.attach(l6, 2, 3, 3, 4, 0, 0, 5, 0)
- expander = gtk.Expander(label='Details')
+ expander = self.expander = gtk.Expander(label='Details')
expander.add(t)
expander.set_expanded(False)
brush_points = None
self.app.brush.settings[self.setting.index].set_points(self.input, brush_points)
+ def reconsider_details(self):
+ s = self.app.brush.settings[self.setting.index]
+ if s.has_input_nonlinear(self.input):
+ self.expander.set_expanded(True)
+ else:
+ self.expander.set_expanded(False)
+
def reread(self):
brush_points = self.app.brush.settings[self.setting.index].points[self.input.index]
curve_points = []
self.scale_x_adj.set_value(scale_x)
self.scale_y_adj.set_value(scale_y)
+ self.reconsider_details()
+
RADIUS = 4
class CurveWidget(gtk.DrawingArea):
"modify a (restricted) nonlinear curve"
for (i=0; i<BRUSH_SETTINGS_COUNT; i++) {
settings[i] = b->settings[i].base_value;
- // FIXME: each setting might depend on any input however, some
- // inputs need the value of a setting to be updated. Using the old
- // value here, this results in a small lag that would be avoidable
- // in most cases. -- however if one of the inputs jumps between
- // two strokes (speed for example) this might be fatal.
-
- // ==> the inputs should be updated above, and the settings needed
- // to do so should have been cached from the last step...
-
for (j=0; j<INPUT_COUNT; j++) {
Mapping * m = b->settings[i].mapping[j];
// OPTIMIZE?