Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x_colorsc.sobin620042 -> 620174 bytes
-rwxr-xr-xcolors.py126
-rw-r--r--src/canvas.h146
-rw-r--r--src/colorsc_wrap.cxx32
4 files changed, 185 insertions, 119 deletions
diff --git a/_colorsc.so b/_colorsc.so
index ed1e62a..38b30bb 100755
--- a/_colorsc.so
+++ b/_colorsc.so
Binary files differ
diff --git a/colors.py b/colors.py
index c262f55..7830151 100755
--- a/colors.py
+++ b/colors.py
@@ -115,7 +115,7 @@ class BrushControlsPanel(gtk.HBox):
self.sizebar.set_property("inverted", True)
self.sizebar.connect('value-changed', self.on_size_change)
sizebox.pack_end(self.sizebar)
- self.sizecheck = gtk.CheckButton(_('Pressure\nSensitive'))
+ self.sizecheck = gtk.CheckButton(_('Sensitive'))
self.sizecheck.connect('toggled', self.on_variable_size_toggle)
sizebox.pack_end(self.sizecheck, False)
self.pack_start(sizebox, False)
@@ -130,7 +130,7 @@ class BrushControlsPanel(gtk.HBox):
self.opacitybar.set_property("inverted", True)
self.opacitybar.connect('value-changed', self.on_opacity_change)
opacitybox.pack_end(self.opacitybar)
- self.opacitycheck = gtk.CheckButton(_('Pressure\nSensitive'))
+ self.opacitycheck = gtk.CheckButton(_('Sensitive'))
self.opacitycheck.connect('toggled', self.on_variable_opacity_toggle)
opacitybox.pack_end(self.opacitycheck, False)
self.pack_start(opacitybox, False)
@@ -423,7 +423,6 @@ class Colors(activity.Activity, ExportedGObject):
self.palettebtn = toggletoolbutton.ToggleToolButton('palette')
self.palettebtn.set_tooltip(_("Palette"))
self.palettebtn.connect('clicked', self.on_palette)
- self.palette_forced = False
# todo- Color picker button, similar semantics to palette button.
@@ -442,7 +441,6 @@ class Colors(activity.Activity, ExportedGObject):
self.showrefbtn = toggletoolbutton.ToggleToolButton('show-reference')
self.showrefbtn.set_tooltip(_("Show Reference Picture"))
self.showrefbtn.connect('clicked', self.on_show_reference)
- self.reference_forced = False
self.videopaintsep = gtk.SeparatorToolItem()
@@ -816,8 +814,8 @@ class Colors(activity.Activity, ExportedGObject):
# So each major key should appear at least once on each side of the keyboard.
button = 0
- # 'p' for Palette (todo- need something better!).
- if event.keyval == ord('p'):
+ # Space bar for Palette (todo- need something better!).
+ if event.keyval == ord(' '):
button = Colors.BUTTON_PALETTE
# 'r' for Reference (todo- need something better!).
@@ -833,7 +831,7 @@ class Colors(activity.Activity, ExportedGObject):
self.save_thumbnail(activity.get_bundle_path() + '/thumb.png')
# OLPC 'hand' buttons for scrolling.
- if event.keyval == 311 or event.keyval == 312 or event.keyval == ord('s'):
+ if event.keyval == ord('x') or event.keyval == 311 or event.keyval == 312 or event.keyval == ord('s'):
button = Colors.BUTTON_SCROLL
# OLPC 'size' buttons for intensity.
@@ -843,10 +841,10 @@ class Colors(activity.Activity, ExportedGObject):
#if event.keyval == 289: button = Colors.BUTTON_SIZE_3
# Arrow keys, gamepad 'face' buttons, or 'z' and 'x' for Zoom.
- if event.keyval == ord('z') or event.keyval == 264 or event.keyval == 265 or event.keyval == 273:
- button = Colors.BUTTON_ZOOM_IN
- if event.keyval == ord('x') or event.keyval == 258 or event.keyval == 259 or event.keyval == 274:
- button = Colors.BUTTON_ZOOM_OUT
+ #if event.keyval == ord('z') or event.keyval == 264 or event.keyval == 265 or event.keyval == 273:
+ # button = Colors.BUTTON_ZOOM_IN
+ #if event.keyval == ord('x') or event.keyval == 258 or event.keyval == 259 or event.keyval == 274:
+ # button = Colors.BUTTON_ZOOM_OUT
# Either Alt key for pick.
if event.keyval == 313 or event.keyval == 308:
@@ -921,15 +919,44 @@ class Colors(activity.Activity, ExportedGObject):
def on_press (self, button):
if button & Colors.BUTTON_ZOOM_IN:
self.zoom_in()
+ return
if button & Colors.BUTTON_ZOOM_OUT:
self.zoom_out()
+ return
if button & Colors.BUTTON_VIDEOPAINT:
self.videopaintbtn.set_active(not self.videopaint_enabled)
+ return
+
+ if self.mode == Colors.MODE_CANVAS:
+ if button & Colors.BUTTON_PALETTE:
+ self.set_mode(Colors.MODE_PALETTE)
+ return
+ if button & Colors.BUTTON_REFERENCE:
+ self.set_mode(Colors.MODE_REFERENCE)
+ return
+ if button & Colors.BUTTON_SCROLL:
+ log.debug("enter scroll")
+ self.set_mode(Colors.MODE_SCROLL)
+ return
+
+ if self.mode == Colors.MODE_PALETTE:
+ if button & Colors.BUTTON_PALETTE:
+ self.set_mode(Colors.MODE_CANVAS)
+ return
+
+ if self.mode == Colors.MODE_REFERENCE:
+ if button & Colors.BUTTON_REFERENCE:
+ self.set_mode(Colors.MODE_CANVAS)
+ return
def on_release (self, button):
- pass
+ if self.mode == Colors.MODE_SCROLL:
+ if button & Colors.BUTTON_SCROLL:
+ log.debug("leave scroll")
+ self.set_mode(Colors.MODE_SCROLL)
+ return
def on_hold (self, button):
pass
@@ -947,9 +974,11 @@ class Colors(activity.Activity, ExportedGObject):
self.scroll = pos
# Clamp scroll position to within absolute limits.
- scroll.x = min(max(scroll.x, -self.easel.width * 0.125), self.easel.width * 0.125)
- scroll.y = min(max(scroll.y, -self.easel.height * 0.125), self.easel.height * 0.125)
+ self.scroll.x = min(max(self.scroll.x, -self.easel.width * 0.125), self.easel.width * 0.125)
+ self.scroll.y = min(max(self.scroll.y, -self.easel.height * 0.125), self.easel.height * 0.125)
+ log.debug("scroll.x:%f scroll.y:%f" % (self.scroll.x, self.scroll.y))
+
def snap_scroll (self):
"""Animates the scroll position back towards reasonable bounds."""
if self.scroll.x < self.easel.width *-0.05: self.scroll.x = self.scroll.x * 0.9
@@ -1113,12 +1142,18 @@ class Colors(activity.Activity, ExportedGObject):
def flush_cursor (self):
"""Causes a redraw of the canvas area covered by the cursor."""
- r = int(self.easel.brush.size*2*self.pressure/256)
- x0 = min(self.lastmx-self.lastr/2, self.mx-r/2)
- y0 = min(self.lastmy-self.lastr/2, self.my-r/2)
- x1 = max(self.lastmx+self.lastr/2, self.mx+r/2)
- y1 = max(self.lastmy+self.lastr/2, self.my+r/2)
- self.easelarea.queue_draw_area(x0, y0, x1-x0+2, y1-y0+2)
+ try:
+ r = int(self.easel.brush.size*2*self.pressure/256)
+ x0 = min(self.lastmx-self.lastr/2, self.mx-r/2)
+ y0 = min(self.lastmy-self.lastr/2, self.my-r/2)
+ x1 = max(self.lastmx+self.lastr/2, self.mx+r/2)
+ y1 = max(self.lastmy+self.lastr/2, self.my+r/2)
+ self.easelarea.queue_draw_area(x0, y0, x1-x0+2, y1-y0+2)
+ except:
+ # WTB- Temporary workaround for invalid values!
+ self.lastmx = 0
+ self.lastmy = 0
+ self.lastr = 0
#-----------------------------------------------------------------------------------------------------------------
# Application states
@@ -1162,10 +1197,12 @@ class Colors(activity.Activity, ExportedGObject):
self.brush_controls.show_all()
self.flush_entire_canvas()
self.overlay_active = True
-
+ self.palettebtn.set_active(True)
+
if self.mode == Colors.MODE_REFERENCE:
self.easel.render_reference_overlay()
self.flush_entire_canvas()
+ self.showrefbtn.set_active(True)
def leave_mode (self):
if self.mode == Colors.MODE_INTRO:
@@ -1194,10 +1231,12 @@ class Colors(activity.Activity, ExportedGObject):
self.easelarea.set_double_buffered(False)
self.flush_entire_canvas()
self.overlay_active = False
+ self.palettebtn.set_active(False)
if self.mode == Colors.MODE_REFERENCE:
self.easel.clear_overlay()
self.flush_entire_canvas()
+ self.showrefbtn.set_active(False)
def update_mode (self):
if self.mode == None:
@@ -1240,18 +1279,6 @@ class Colors(activity.Activity, ExportedGObject):
elif self.easel.stroke:
self.end_draw()
self.flush_dirty_canvas()
- # Bring up palette if requested.
- if self.cur_buttons & Colors.BUTTON_PALETTE:
- self.set_mode(Colors.MODE_PALETTE)
- return
- # Bring up reference image if requested.
- if self.cur_buttons & Colors.BUTTON_REFERENCE:
- self.set_mode(Colors.MODE_REFERENCE)
- return
- # Start scrolling if requested.
- if self.cur_buttons & Colors.BUTTON_SCROLL:
- self.set_mode(Colors.MODE_SCROLL)
- return
if self.mode == Colors.MODE_SCROLL:
if self.cur_buttons & Colors.BUTTON_TOUCH:
@@ -1262,40 +1289,32 @@ class Colors(activity.Activity, ExportedGObject):
move = mpos - self.scrollref
if move.x != 0 or move.y != 0:
self.scroll_to(self.scroll - move)
- self.scrollref = mpos
+ #self.scrollref = mpos
else:
self.scrollref = None
# Smoothly pull back towards the image when out of reasonable bounds.
- self.snap_scroll()
+ #self.snap_scroll()
self.flush_entire_canvas()
- if not (self.cur_buttons & Colors.BUTTON_SCROLL):
- self.set_mode(Colors.MODE_CANVAS)
if self.mode == Colors.MODE_PALETTE:
- if not self.palette_forced:
- if not self.cur_buttons & Colors.BUTTON_PALETTE:
- self.set_mode(Colors.MODE_CANVAS)
- return
+ pass
if self.mode == Colors.MODE_REFERENCE:
- if not self.reference_forced:
- if not self.cur_buttons & Colors.BUTTON_REFERENCE:
- self.set_mode(Colors.MODE_CANVAS)
- return
+ pass
def set_mode (self, mode):
+ log.debug("set mode %d", mode)
if self.mode != None:
self.leave_mode()
self.mode = mode
self.enter_mode()
def update (self):
- if self.overlay_active:
- return
if self.easel == None:
return
self.update_input()
- self.update_mode()
+ if not self.overlay_active:
+ self.update_mode()
def tick (self):
# todo- Return False when nothing is going on (to idle the XO), then restart the idle event when something happens.
@@ -1337,6 +1356,7 @@ class Colors(activity.Activity, ExportedGObject):
self.easel.blit_2x(
self.easelimage,
int(event.area.x/2), int(event.area.y/2), int(event.area.width/2), int(event.area.height/2),
+ int(self.scroll.x), int(self.scroll.y),
self.overlay_active)
# Then draw the image to the screen.
@@ -1369,22 +1389,20 @@ class Colors(activity.Activity, ExportedGObject):
def on_palette (self, button):
if button.get_active():
- self.set_mode(Colors.MODE_PALETTE)
- self.palette_forced = True
+ if self.mode != Colors.MODE_PALETTE:
+ self.set_mode(Colors.MODE_PALETTE)
else:
self.set_mode(Colors.MODE_CANVAS)
- self.palette_forced = False
def on_take_reference (self, button):
self.take_reference = True
def on_show_reference (self, button):
if button.get_active():
- self.set_mode(Colors.MODE_REFERENCE)
- self.reference_forced = True
+ if self.mode != Colors.MODE_REFERENCE:
+ self.set_mode(Colors.MODE_REFERENCE)
else:
self.set_mode(Colors.MODE_CANVAS)
- self.reference_forced = False
def on_videopaint (self, button):
self.videopaint_enabled = button.get_active()
diff --git a/src/canvas.h b/src/canvas.h
index 8556d54..e221b39 100644
--- a/src/canvas.h
+++ b/src/canvas.h
@@ -426,10 +426,14 @@ public:
alpha = new unsigned char[width*height];
image_shared = new unsigned int[width*height];
+
image_reference = new unsigned short[REFERENCE_WIDTH*REFERENCE_HEIGHT];
+ memset(image_reference, 0, REFERENCE_WIDTH*REFERENCE_HEIGHT*sizeof(unsigned short));
image_video[0] = new unsigned int[VIDEO_WIDTH*VIDEO_HEIGHT];
image_video[1] = new unsigned int[VIDEO_WIDTH*VIDEO_HEIGHT];
+ memset(image_video[0], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned int));
+ memset(image_video[1], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned int));
video_idx = 0;
clear();
@@ -480,10 +484,10 @@ public:
clear_image();
}
- // Changes the size of the canvas.
- // Rather than trying to repaint everything from scratch, we simply quickly rescale it.
- void resize(int new_width, int new_height)
- {
+ // Changes the size of the canvas.
+ // Rather than trying to repaint everything from scratch, we simply quickly rescale it.
+ void resize(int new_width, int new_height)
+ {
unsigned int* new_image = new unsigned int[new_width*new_height];
unsigned int* new_image_backup = new unsigned int[new_width*new_height];
unsigned char* new_alpha = new unsigned char[new_width*new_height];
@@ -497,31 +501,31 @@ public:
int rx = 0;
for (int x = 0; x < new_width; x++)
{
- int sofs = (ry>>16)*width + (rx>>16);
- int dofs = y*new_width+x;
- new_image[dofs] = image[sofs];
- new_image_backup[dofs] = image_backup[sofs];
- new_alpha[dofs] = alpha[sofs];
- new_image_shared[dofs] = image_shared[sofs];
- rx += dx;
+ int sofs = (ry>>16)*width + (rx>>16);
+ int dofs = y*new_width+x;
+ new_image[dofs] = image[sofs];
+ new_image_backup[dofs] = image_backup[sofs];
+ new_alpha[dofs] = alpha[sofs];
+ new_image_shared[dofs] = image_shared[sofs];
+ rx += dx;
}
- ry += dy;
- }
-
- delete[] image;
- delete[] image_backup;
- delete[] alpha;
- delete[] image_shared;
-
- width = new_width;
- height = new_height;
-
- image = new_image;
- image_backup = new_image_backup;
- alpha = new_alpha;
- image_shared = new_image_shared;
+ ry += dy;
}
+
+ delete[] image;
+ delete[] image_backup;
+ delete[] alpha;
+ delete[] image_shared;
+
+ width = new_width;
+ height = new_height;
+ image = new_image;
+ image_backup = new_image_backup;
+ alpha = new_alpha;
+ image_shared = new_image_shared;
+ }
+
// Resets the brush to a random color and a default size and type.
void reset_brush()
{
@@ -578,10 +582,6 @@ public:
memset(image_shared, 0xff, width*height*sizeof(unsigned int));
- memset(image_reference, 0, REFERENCE_WIDTH*REFERENCE_HEIGHT*sizeof(unsigned short));
- memset(image_video[0], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned short));
- memset(image_video[1], 0, VIDEO_WIDTH*VIDEO_HEIGHT*sizeof(unsigned short));
-
dirtymin = Pos(0, 0);
dirtymax = Pos(width, height);
}
@@ -1026,42 +1026,68 @@ public:
// Blit
//
// Draws a region of the canvas into a GdkImage for display on the screen, with optional scaling
- // and darkening.
+ // and darkening.
- void blit_2x(GdkImage* img, int x, int y, int w, int h, bool overlay)
+ void blit_2x(GdkImage* img, int x, int y, int w, int h, int scroll_x, int scroll_y, bool overlay)
{
- if (overlay)
+ unsigned short* pixels = (unsigned short*)img->mem;
+ int pitch = img->bpl/sizeof(unsigned short);
+
+ // Translate origin to output location.
+ unsigned short* dest_pixels = pixels + y*pitch+x;
+
+ int src_x = (x - scroll_x)/2;
+ int src_y = (y - scroll_y)/2;
+
+ if (src_x < 0) src_x = 0;
+
+ while (src_y < 0)
{
- unsigned short* pixels = (unsigned short*)img->mem;
- int pitch = img->bpl/sizeof(unsigned short);
+ unsigned short* __restrict row0 = dest_pixels;
+ unsigned short* __restrict row1 = dest_pixels + pitch;
+ dest_pixels += pitch*2;
+ for (int cx = 0; cx < w; cx++)
+ {
+ unsigned int rgb = 0;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
+ }
+ src_y++;
+ h--;
+ }
- for (int cy = 0; cy < h; cy++)
+ unsigned int* src_pixels = &image[src_y*width+src_x];
+
+ for (int cy = 0; cy < h; cy++)
+ {
+ unsigned int* __restrict src = src_pixels;
+ unsigned short* __restrict row0 = dest_pixels;
+ unsigned short* __restrict row1 = dest_pixels + pitch;
+ src_pixels += width;
+ dest_pixels += pitch*2;
+ for (int cx = 0; cx < w; cx++)
{
- unsigned int* __restrict src = &image[(y+cy)*width+x];
- unsigned short* __restrict row0 = &pixels[((y+cy)*2+0)*pitch+x*2];
- unsigned short* __restrict row1 = &pixels[((y+cy)*2+1)*pitch+x*2];
- for (int cx = 0; cx < w; cx++)
- {
- unsigned int p = *src++;
- p &= ~0x03030303;
- p >>= 2;
- unsigned int r = (((p>>16)&0xff)>>3)<<11;
- unsigned int g = (((p>> 8)&0xff)>>2)<<5;
- unsigned int b = (((p>> 0)&0xff)>>3);
- unsigned int rgb = r|g|b;
- row0[0] = rgb;
- row0[1] = rgb;
- row1[0] = rgb;
- row1[1] = rgb;
- row0 += 2;
- row1 += 2;
- }
+ unsigned int p = *src++;
+ unsigned int r = (((p>>16)&0xff)>>3)<<11;
+ unsigned int g = (((p>> 8)&0xff)>>2)<<5;
+ unsigned int b = (((p>> 0)&0xff)>>3);
+ unsigned int rgb = r|g|b;
+ row0[0] = rgb;
+ row0[1] = rgb;
+ row1[0] = rgb;
+ row1[1] = rgb;
+ row0 += 2;
+ row1 += 2;
}
}
- else
+
+/*
+ if (overlay)
{
- unsigned short* pixels = (unsigned short*)img->mem;
- int pitch = img->bpl/sizeof(unsigned short);
for (int cy = 0; cy < h; cy++)
{
@@ -1071,6 +1097,8 @@ public:
for (int cx = 0; cx < w; cx++)
{
unsigned int p = *src++;
+ p &= ~0x03030303;
+ p >>= 2;
unsigned int r = (((p>>16)&0xff)>>3)<<11;
unsigned int g = (((p>> 8)&0xff)>>2)<<5;
unsigned int b = (((p>> 0)&0xff)>>3);
@@ -1084,6 +1112,8 @@ public:
}
}
}
+ else
+ */
}
//---------------------------------------------------------------------------------------------
diff --git a/src/colorsc_wrap.cxx b/src/colorsc_wrap.cxx
index daaefdb..6a3b4d2 100644
--- a/src/colorsc_wrap.cxx
+++ b/src/colorsc_wrap.cxx
@@ -9349,7 +9349,9 @@ SWIGINTERN PyObject *_wrap_Canvas_blit_2x(PyObject *SWIGUNUSEDPARM(self), PyObje
int arg4 ;
int arg5 ;
int arg6 ;
- bool arg7 ;
+ int arg7 ;
+ int arg8 ;
+ bool arg9 ;
void *argp1 = 0 ;
int res1 = 0 ;
int val3 ;
@@ -9360,8 +9362,12 @@ SWIGINTERN PyObject *_wrap_Canvas_blit_2x(PyObject *SWIGUNUSEDPARM(self), PyObje
int ecode5 = 0 ;
int val6 ;
int ecode6 = 0 ;
- bool val7 ;
+ int val7 ;
int ecode7 = 0 ;
+ int val8 ;
+ int ecode8 = 0 ;
+ bool val9 ;
+ int ecode9 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
@@ -9369,8 +9375,10 @@ SWIGINTERN PyObject *_wrap_Canvas_blit_2x(PyObject *SWIGUNUSEDPARM(self), PyObje
PyObject * obj4 = 0 ;
PyObject * obj5 = 0 ;
PyObject * obj6 = 0 ;
+ PyObject * obj7 = 0 ;
+ PyObject * obj8 = 0 ;
- if (!PyArg_ParseTuple(args,(char *)"OOOOOOO:Canvas_blit_2x",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6)) SWIG_fail;
+ if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOO:Canvas_blit_2x",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Canvas, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Canvas_blit_2x" "', argument " "1"" of type '" "Canvas *""'");
@@ -9402,12 +9410,22 @@ SWIGINTERN PyObject *_wrap_Canvas_blit_2x(PyObject *SWIGUNUSEDPARM(self), PyObje
SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "Canvas_blit_2x" "', argument " "6"" of type '" "int""'");
}
arg6 = static_cast< int >(val6);
- ecode7 = SWIG_AsVal_bool(obj6, &val7);
+ ecode7 = SWIG_AsVal_int(obj6, &val7);
if (!SWIG_IsOK(ecode7)) {
- SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "Canvas_blit_2x" "', argument " "7"" of type '" "bool""'");
+ SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "Canvas_blit_2x" "', argument " "7"" of type '" "int""'");
}
- arg7 = static_cast< bool >(val7);
- (arg1)->blit_2x(arg2,arg3,arg4,arg5,arg6,arg7);
+ arg7 = static_cast< int >(val7);
+ ecode8 = SWIG_AsVal_int(obj7, &val8);
+ if (!SWIG_IsOK(ecode8)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "Canvas_blit_2x" "', argument " "8"" of type '" "int""'");
+ }
+ arg8 = static_cast< int >(val8);
+ ecode9 = SWIG_AsVal_bool(obj8, &val9);
+ if (!SWIG_IsOK(ecode9)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "Canvas_blit_2x" "', argument " "9"" of type '" "bool""'");
+ }
+ arg9 = static_cast< bool >(val9);
+ (arg1)->blit_2x(arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
resultobj = SWIG_Py_Void();
return resultobj;
fail: