1
0
Fork 0
forked from len0rd/rockbox

rockpaint: change the way to handle tools to improve readability.

make ROCKPAINT_QUIT cancel drawing if it is in progress.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28607 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Teruaki Kawashima 2010-11-16 12:55:20 +00:00
parent e464656b88
commit 36f623d2ca

View file

@ -33,6 +33,8 @@
#include "lib/rgb_hsv.h"
#include "lib/playback_control.h"
#include "pluginbitmaps/rockpaint.h"
#include "pluginbitmaps/rockpaint_hsvrgb.h"
/***********************************************************************
@ -265,9 +267,6 @@
#define COLOR_BROWN LCD_RGBPACK(128,64,0)
#define COLOR_LIGHTBROWN LCD_RGBPACK(255,128,64)
#define SPLASH_SCREEN PLUGIN_APPS_DIR "/rockpaint/splash.bmp"
#define ROCKPAINT_TITLE_FONT 2
/***********************************************************************
* Program Colors
***********************************************************************/
@ -340,14 +339,15 @@
static void draw_pixel(int x,int y);
static void draw_line( int x1, int y1, int x2, int y2 );
static void draw_rect( int x1, int y1, int x2, int y2 );
static void draw_rect_full( int x1, int y1, int x2, int y2 );
static void draw_toolbars(bool update);
static void inv_cursor(bool update);
static void restore_screen(void);
static void clear_drawing(void);
static void reset_tool(void);
static void goto_menu(void);
static int load_bitmap( const char *filename );
static int save_bitmap( char *filename );
static void draw_rect_full( int x1, int y1, int x2, int y2 );
/***********************************************************************
* Global variables
@ -366,7 +366,6 @@ static int x=0, y=0; /* cursor position */
static int prev_x=-1, prev_y=-1; /* previous saved cursor position */
static int prev_x2=-1, prev_y2=-1;
static int prev_x3=-1, prev_y3=-1;
static int tool_mode=-1;
static int bsize=1; /* brush size */
@ -388,7 +387,14 @@ enum Tools { Brush = 0, /* Regular brush */
RadialGradient = 13
};
enum States { State0 = 0, /* initial state */
State1,
State2,
State3,
};
enum Tools tool = Brush;
enum States state = State0;
static bool quit=false;
static int gridsize=0;
@ -404,8 +410,10 @@ static fb_data rp_colors[18] =
static fb_data save_buffer[ ROWS*COLS ];
extern fb_data rockpaint[];
extern fb_data rockpaint_hsvrgb[];
struct tool_func {
void (*state_func)(void);
void (*preview_func)(void);
};
struct incdec_ctx {
int max;
@ -975,6 +983,7 @@ static bool browse_fonts( char *dst, int dst_size )
break;
case ROCKPAINT_LEFT:
case ROCKPAINT_QUIT:
return false;
case ROCKPAINT_RIGHT:
@ -1206,7 +1215,7 @@ static void color_picker( int x, int y )
if( y >= ROWS - PSIZE ) y -= PSIZE + 2;
rb->lcd_drawrect( x + 2, y + 2, PSIZE - 2, PSIZE - 2 );
rb->lcd_set_drawmode(DRMODE_SOLID);
rb->lcd_drawrect( x + 3, y + 3, PSIZE - 4, PSIZE - 4 );
rb->lcd_fillrect( x + 3, y + 3, PSIZE - 4, PSIZE - 4 );
#undef PSIZE
rb->lcd_set_foreground( rp_colors[ drawcolor ] );
}
@ -1414,10 +1423,10 @@ static void draw_rot_90_deg( int x1, int y1, int x2, int y2, int direction )
}
static void draw_paste_rectangle( int src_x1, int src_y1, int src_x2,
int src_y2, int x1, int y1, int mode )
int src_y2, int x1, int y1, int cut )
{
int i, width, height;
if( mode == SELECT_MENU_CUT )
if( cut )
{
i = drawcolor;
drawcolor = bgdrawcolor;
@ -1907,6 +1916,8 @@ static void draw_fill( int x0, int y0 )
short y = y0;
unsigned int prev_color = save_buffer[ x0+y0*COLS ];
if( preview )
return;
if( prev_color == rp_colors[ drawcolor ] ) return;
PUSH( x, y );
@ -2063,6 +2074,7 @@ static void linear_gradient( int x1, int y1, int x2, int y2 )
if( preview )
{
line_gradient( x1, y1, x2, y2 );
return;
}
if( rp_colors[ drawcolor ] == rp_colors[ bgdrawcolor ] )
{
@ -2162,6 +2174,7 @@ static void radial_gradient( int x1, int y1, int x2, int y2 )
if( preview )
{
line_gradient( x1, y1, x2, y2 );
return;
}
if( rp_colors[ drawcolor ] == rp_colors[ bgdrawcolor ] )
{
@ -2351,13 +2364,7 @@ static void toolbar( void )
i = ( x - TB_TL_LEFT )/(TB_TL_SIZE+TB_TL_SPACING);
j = ( y - (TOP+TB_TL_TOP) )/(TB_TL_SIZE+TB_TL_SPACING);
tool = i*2+j;
prev_x = -1;
prev_y = -1;
prev_x2 = -1;
prev_y2 = -1;
prev_x3 = -1;
prev_y3 = -1;
preview = false;
reset_tool();
}
else if( x >= TB_MENU_LEFT && y >= TOP+TB_MENU_TOP-2)
{
@ -2550,83 +2557,58 @@ static void reset_tool( void )
prev_y2 = -1;
prev_x3 = -1;
prev_y3 = -1;
tool_mode = -1;
preview = false;
/* reset state */
state = State0;
/* always preview color picker */
preview = (tool == ColorPicker);
}
static bool rockpaint_loop( void )
/* brush tool */
static void state_func_brush(void)
{
int button=0,i,j;
bool bigstep;
if( state == State0 )
{
state = State1;
}
else
{
state = State0;
}
}
x = 10;
toolbar();
x = 0; y = 0;
/* fill tool */
static void state_func_fill(void)
{
draw_fill( x, y );
restore_screen();
inv_cursor(true);
}
while (!quit) {
button = rb->button_get(true);
bigstep = (button & BUTTON_REPEAT) && !(tool == Brush && prev_x != -1);
switch(button)
/* select rectangle tool */
static void state_func_select(void)
{
case ROCKPAINT_QUIT:
rb->lcd_set_drawmode(DRMODE_SOLID);
return PLUGIN_OK;
case ROCKPAINT_MENU:
inv_cursor(false);
goto_menu();
restore_screen();
inv_cursor(true);
break;
case ROCKPAINT_DRAW:
inv_cursor(false);
switch( tool )
{
case Brush:
if( prev_x == -1 ) prev_x = 1;
else prev_x = -1;
break;
case SelectRectangle:
case Line:
case Curve:
case Rectangle:
case RectangleFull:
case Oval:
case OvalFull:
case LinearGradient:
case RadialGradient:
/* Curve uses 4 points, others use 2 */
if( prev_x == -1 || prev_y == -1 )
int mode;
if( state == State0 )
{
prev_x = x;
prev_y = y;
preview = true;
state = State1;
}
else if( tool == Curve
&& ( prev_x2 == -1 || prev_y2 == -1 ) )
else if( state == State1 )
{
prev_x2 = x;
prev_y2 = y;
}
else if( tool == SelectRectangle
&& ( prev_x2 == -1 || prev_y2 == -1 ) )
{
tool_mode = rb->do_menu( &select_menu,
NULL, NULL, false );
switch( tool_mode )
mode = rb->do_menu( &select_menu, NULL, NULL, false );
switch( mode )
{
case SELECT_MENU_CUT:
case SELECT_MENU_COPY:
prev_x2 = x;
prev_y2 = y;
copy_to_clipboard();
if( prev_x < x ) x = prev_x;
if( prev_y < y ) y = prev_y;
prev_x3 = abs(prev_x2 - prev_x);
prev_y3 = abs(prev_y2 - prev_y);
copy_to_clipboard();
state = (mode == SELECT_MENU_CUT? State2: State3);
break;
case SELECT_MENU_INVERT:
@ -2669,31 +2651,125 @@ static bool rockpaint_loop( void )
}
restore_screen();
}
else if( tool == Curve
&& ( prev_x3 == -1 || prev_y3 == -1 ) )
else
{
preview = false;
draw_paste_rectangle( prev_x, prev_y, prev_x2, prev_y2,
x, y, state == State2 );
reset_tool();
restore_screen();
}
}
static void preview_select(void)
{
if( state == State1 )
{
/* we are defining the selection */
draw_select_rectangle( prev_x, prev_y, x, y );
}
else
{
/* we are pasting the selected data */
draw_paste_rectangle( prev_x, prev_y, prev_x2, prev_y2,
x, y, state == State2 );
draw_select_rectangle( x, y, x+prev_x3, y+prev_y3 );
}
}
/* color picker tool */
static void state_func_picker(void)
{
preview = false;
color_picker( x, y );
reset_tool();
}
static void preview_picker(void)
{
color_picker( x, y );
}
/* curve tool */
static void state_func_curve(void)
{
if( state == State0 )
{
prev_x = x;
prev_y = y;
preview = true;
state = State1;
}
else if( state == State1 )
{
prev_x2 = x;
prev_y2 = y;
state = State2;
}
else if( state == State2 )
{
prev_x3 = x;
prev_y3 = y;
state = State3;
}
else
{
preview = false;
draw_curve( prev_x, prev_y, prev_x2, prev_y2,
prev_x3, prev_y3, x, y );
reset_tool();
restore_screen();
}
}
static void preview_curve(void)
{
if( state == State1 )
{
draw_line( prev_x, prev_y, x, y );
}
else
{
draw_curve( prev_x, prev_y, prev_x2, prev_y2,
prev_x3, prev_y3, x, y );
}
}
/* text tool */
static void state_func_text(void)
{
draw_text( x, y );
}
/* tools which take 2 point */
static void preview_2point(void);
static void state_func_2point(void)
{
if( state == State0 )
{
prev_x = x;
prev_y = y;
state = State1;
preview = true;
}
else
{
preview = false;
preview_2point();
reset_tool();
restore_screen();
}
}
static void preview_2point(void)
{
if( state == State1 )
{
switch( tool )
{
case SelectRectangle:
draw_paste_rectangle( prev_x, prev_y,
prev_x2, prev_y2,
x, y, tool_mode );
break;
case Line:
draw_line( prev_x, prev_y, x, y );
break;
case Curve:
draw_curve( prev_x, prev_y,
prev_x2, prev_y2,
prev_x3, prev_y3,
x, y );
break;
case Rectangle:
draw_rect( prev_x, prev_y, x, y );
break;
@ -2715,39 +2791,84 @@ static bool rockpaint_loop( void )
default:
break;
}
if( !preview )
{
reset_tool();
restore_screen();
}
break;
case Fill:
draw_fill( x, y );
restore_screen();
break;
case ColorPicker:
color_picker( x, y );
break;
case Text:
draw_text( x, y );
break;
default:
break;
}
}
static const struct tool_func tools[14] = {
[Brush] = { state_func_brush, NULL },
[Fill] = { state_func_fill, NULL },
[SelectRectangle] = { state_func_select, preview_select },
[ColorPicker] = { state_func_picker, preview_picker },
[Line] = { state_func_2point, preview_2point },
[Unused] = { NULL, NULL },
[Curve] = { state_func_curve, preview_curve },
[Text] = { state_func_text, NULL },
[Rectangle] = { state_func_2point, preview_2point },
[RectangleFull] = { state_func_2point, preview_2point },
[Oval] = { state_func_2point, preview_2point },
[OvalFull] = { state_func_2point, preview_2point },
[LinearGradient] = { state_func_2point, preview_2point },
[RadialGradient] = { state_func_2point, preview_2point },
};
static bool rockpaint_loop( void )
{
int button = 0, i, j;
bool bigstep;
x = 10;
toolbar();
x = 0; y = 0;
restore_screen();
inv_cursor(true);
while (!quit) {
button = rb->button_get(true);
bigstep = (button & BUTTON_REPEAT) && !(tool == Brush && state == State1);
switch(button)
{
case ROCKPAINT_QUIT:
if (state != State0)
{
reset_tool();
restore_screen();
inv_cursor(true);
}
else
{
rb->lcd_set_drawmode(DRMODE_SOLID);
return PLUGIN_OK;
}
break;
case ROCKPAINT_MENU:
goto_menu();
restore_screen();
inv_cursor(true);
break;
case ROCKPAINT_DRAW:
if( tools[tool].state_func )
{
inv_cursor(false);
tools[tool].state_func();
inv_cursor(true);
}
break;
case ROCKPAINT_DRAW|BUTTON_REPEAT:
if( tool == Curve )
if( tool == Curve && state != State0 )
{
/* 3 point bezier curve */
preview = false;
draw_curve( prev_x, prev_y,
prev_x2, prev_y2,
-1, -1,
x, y );
draw_curve( prev_x, prev_y, prev_x2, prev_y2,
-1, -1, x, y );
reset_tool();
restore_screen();
inv_cursor( true );
@ -2755,17 +2876,9 @@ static bool rockpaint_loop( void )
break;
case ROCKPAINT_TOOLBAR:
i = x; j = y;
x = 10;
toolbar();
x = i; y = j;
restore_screen();
inv_cursor(true);
break;
case ROCKPAINT_TOOLBAR2:
i = x; j = y;
x = 110;
x = (button == ROCKPAINT_TOOLBAR2) ? 110: 10;
toolbar();
x = i; y = j;
restore_screen();
@ -2802,97 +2915,16 @@ static bool rockpaint_loop( void )
return PLUGIN_USB_CONNECTED;
break;
}
if( tool == Brush && prev_x == 1 )
if( tool == Brush && state == State1 )
{
inv_cursor(false);
draw_brush( x, y );
inv_cursor(true);
}
if( preview || tool == ColorPicker )
/* always preview color picker */
if( preview && tools[tool].preview_func )
{
restore_screen();
switch( tool )
{
case SelectRectangle:
if( prev_x2 == -1 || prev_y2 == -1 )
{
/* we are defining the selection */
draw_select_rectangle( prev_x, prev_y, x, y );
}
else
{
/* we are pasting the selected data */
draw_paste_rectangle( prev_x, prev_y, prev_x2,
prev_y2, x, y, tool_mode );
prev_x3 = prev_x2-prev_x;
if( prev_x3 < 0 ) prev_x3 *= -1;
prev_y3 = prev_y2-prev_y;
if( prev_y3 < 0 ) prev_y3 *= -1;
draw_select_rectangle( x, y, x+prev_x3, y+prev_y3 );
prev_x3 = -1;
prev_y3 = -1;
}
break;
case Brush:
break;
case Line:
draw_line( prev_x, prev_y, x, y );
break;
case Curve:
if( prev_x2 == -1 || prev_y2 == -1 )
{
draw_line( prev_x, prev_y, x, y );
}
else
{
draw_curve( prev_x, prev_y,
prev_x2, prev_y2,
prev_x3, prev_y3,
x, y );
}
break;
case Rectangle:
draw_rect( prev_x, prev_y, x, y );
break;
case RectangleFull:
draw_rect_full( prev_x, prev_y, x, y );
break;
case Oval:
draw_oval_empty( prev_x, prev_y, x, y );
break;
case OvalFull:
draw_oval_full( prev_x, prev_y, x, y );
break;
case Fill:
break;
case ColorPicker:
preview = true;
color_picker( x, y );
preview = false;
break;
case LinearGradient:
line_gradient( prev_x, prev_y, x, y );
break;
case RadialGradient:
line_gradient( prev_x, prev_y, x, y );
break;
case Text:
default:
break;
}
tools[tool].preview_func();
inv_cursor( true );
}
if( gridsize > 0 )