From b60bfd619cebda212385c397e9aad00e382a6a27 Mon Sep 17 00:00:00 2001 From: Wade Brainerd Date: Mon, 19 May 2008 02:18:50 +0000 Subject: WIP on scrolling. Don't get! --- 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: -- cgit v0.9.1