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:
parent
e464656b88
commit
36f623d2ca
1 changed files with 306 additions and 274 deletions
|
|
@ -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 )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue