00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023
00024 #include <context.h>
00025 #include <layer.h>
00026 #include <jutils.h>
00027
00028 #include <slang_console_ctrl.h>
00029 #include <console_calls_ctrl.h>
00030 #include <console_readline_ctrl.h>
00031
00032 #include <keycodes.h>
00033
00034
00035
00036
00037 SlwReadline::SlwReadline()
00038 : SLangWidget() {
00039
00040 movestep=2;
00041 parser = DEFAULT;
00042 commandline = false;
00043 memset(command, EOL, MAX_CMDLINE);
00044
00045 }
00046
00047 SlwReadline::~SlwReadline() {
00048
00049 Entry *e;
00050 e = history.begin();
00051 while(e) {
00052 free(e->data);
00053 e->rem();
00054 delete(e);
00055 e = history.begin();
00056 }
00057
00058 }
00059
00060 bool SlwReadline::init() {
00061 initialized = true;
00062 return(true);
00063 }
00064
00065 bool SlwReadline::feed(int key) {
00066 bool res = false;
00067
00068 switch(parser) {
00069 case COMMANDLINE:
00070
00071 res = parser_commandline(key);
00072 break;
00073
00074 case MOVELAYER:
00075
00076 res = parser_movelayer(key);
00077 break;
00078
00079 case DEFAULT:
00080 res = parser_default(key);
00081 break;
00082
00083 }
00084
00085
00086 return(res);
00087 }
00088
00089 bool SlwReadline::refresh() {
00090 switch(parser) {
00091 case DEFAULT:
00092 case MOVELAYER:
00093 color = TITLE_COLOR+20;
00094 putnch((char*)
00095 " use arrows to move selection, press ctrl-h for help with hotkeys"
00096 ,0,0,0);
00097 break;
00098
00099 case COMMANDLINE:
00100 blank_row(0);
00101 color = PLAIN_COLOR;
00102 putnch((char*)": ", 0, 0, 2);
00103 if(command[0]!=EOL)
00104 putnch(command, 2, 0, 0);
00105 else
00106 cursor = 0;
00107 gotoxy(cursor+2, 0);
00108 break;
00109
00110 default: break;
00111 }
00112 return(true);
00113 }
00114
00115
00116 void SlwReadline::set_parser(parser_t pars) {
00117 switch(pars) {
00118
00119 case DEFAULT:
00120 parser = DEFAULT;
00121 SLtt_set_cursor_visibility(0);
00122 break;
00123
00124 case COMMANDLINE:
00125 parser = COMMANDLINE;
00126 SLtt_set_cursor_visibility(1);
00127 break;
00128
00129 case MOVELAYER:
00130 ::notice("move layer with arrows, press enter when done");
00131 ::act("use arrow keys to move, or keypad numbers");
00132 ::act("+ and - zoom, < and > rotate");
00133 ::act(", stop rotation . stop zoom and <space> to center");
00134 ::act("press <enter> when you are done");
00135 parser = MOVELAYER;
00136 SLtt_set_cursor_visibility(0);
00137 break;
00138
00139 default:
00140 error("unknown parser for readline");
00141 break;
00142 }
00143
00144 }
00145
00146
00147
00148
00149
00150 int SlwReadline::readline(const char *msg,cmd_process_t *proc,cmd_complete_t *comp) {
00151 ::notice(msg);
00152
00153 color = PLAIN_COLOR;
00154
00155 blank();
00156
00157
00158
00159
00160
00161
00162
00163 memset(command,EOL,MAX_CMDLINE);
00164
00165 cmd_process = proc;
00166 cmd_complete = comp;
00167
00168 commandline = true;
00169 set_parser(COMMANDLINE);
00170
00171 if(cmd_complete)
00172 (*cmd_complete)(env, command);
00173
00174 cursor = strlen(command);
00175 return 1;
00176 }
00177
00178
00180
00182
00183
00184 bool SlwReadline::parser_default(int key) {
00185 Entry *le, *fe;
00186 bool res = true;
00187
00188 commandline = false;
00189
00190
00191
00192 if(env->screens.selected()->layers.len() > 0) {
00193
00194
00195 le = env->screens.selected()->layers.selected();
00196 if(!le) {
00197 env->screens.selected()->layers.begin();
00198 le->sel(true);
00199 }
00200
00201 fe = ((Layer*)le)->filters.selected();
00202
00203
00204 switch(key) {
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 case KEY_CTRL_E:
00222 readline("add new Effect - press TAB for completion:",
00223 &console_filter_selection, &console_filter_completion);
00224 break;
00225
00226 case KEY_CTRL_P:
00227 readline("set parameter - press TAB for completion:",
00228 &console_param_selection, &console_param_completion);
00229 break;
00230
00231 case KEY_CTRL_B:
00232 readline("select Blit mode for the selected Layer - press TAB for completion:",
00233 &console_blit_selection, &console_blit_completion);
00234 break;
00235 case KEY_CTRL_V:
00236 readline("select Blit parameter value - press TAB for completion:",
00237 &console_blit_param_selection, &console_blit_param_completion);
00238 break;
00239
00240 #if defined WITH_TEXTLAYER
00241 case KEY_CTRL_Y:
00242 if(((Layer*)le)->type == Layer::TEXT)
00243 readline("print a new word in Text Layer, type your words:",
00244 &console_print_text_layer,NULL);
00245 break;
00246 #endif
00247
00248 case KEY_CTRL_A:
00249 set_parser(MOVELAYER);
00250 break;
00251
00252
00253
00254
00255
00256
00257 default:
00258
00259 break;
00260
00261 }
00262 }
00263
00264 switch(key) {
00265 case KEY_CTRL_H:
00266 case KEY_CTRL_H_APPLE:
00267 case '?':
00268 notice("Below are listed the Hotkeys available in FreeJ console");
00269
00270 act("pressing [Tab] in most situations lists choices and completes commands");
00271 act("Arrow keys browse across Layers and Filters");
00272 act("Space de/activates Layers and Filters selected");
00273 act("+ and - move Layers and Effects up and down the chains");
00274 act(" @ = Switch on/off screen cleanup (blank frame at every tick)");
00275
00276 act("ctrl+o = Open a File (will prompt for path to file)");
00277 act("ctrl+g = Create a Generator (tab to list available)");
00278 act("ctrl+t = Add a Text layer (will prompt for text)");
00279
00280 act("ctrl+a = Move Rotate and Zoom a Layer");
00281 act("ctrl+e = Add a Filter to a Layer");
00282 act("ctrl+p = Set Parameters for a Layer or Filter");
00283 act("ctrl+b = Select the Blit for a Layer (tab completed)");
00284 act("ctrl+v = Set Parameters for of a Layer's Blit");
00285
00286 act("ctrl+x = Execute a javascript command");
00287 act("ctrl+j = Load and execute a javascript file");
00288 act("ctrl+f = Switch Fullscreen on/off");
00289
00290 act("ctrl+c = Quit FreeJ");
00291 break;
00292
00293
00294
00295
00296
00297
00298 case '@':
00299 env->clear_all = !env->clear_all;
00300 break;
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 case KEY_CTRL_F:
00319 env->screens.selected()->fullscreen();
00320 break;
00321
00322 case KEY_CTRL_X:
00323 readline("execute javascript command:",
00324 &console_exec_script_command,NULL);
00325 break;
00326
00327 case KEY_CTRL_J:
00328 readline("load and execute a javascript file:",
00329 &console_exec_script, &console_filebrowse_completion);
00330 break;
00331
00332
00333 case KEY_CTRL_O:
00334 readline("open a file in a new Layer:",
00335 &console_open_layer,&console_filebrowse_completion);
00336 break;
00337
00338
00339 case KEY_CTRL_G:
00340 readline("create a generator in a new Layer:",
00341 &console_generator_selection, &console_generator_completion);
00342 break;
00343
00344
00345 #if defined WITH_TEXTLAYER
00346 case KEY_CTRL_T:
00347 readline("create a new Text Layer, type your words:",
00348 &console_open_text_layer,NULL);
00349 break;
00350 #endif
00351
00352 default:
00353 res = false;
00354 break;
00355
00356 }
00357 return(res);
00358 }
00359
00360 bool SlwReadline::parser_movelayer(int key) {
00361 bool res = true;
00362
00363 commandline = false;
00364
00365
00366 Layer *layer = (Layer*)env->screens.selected()->layers.selected();
00367 if(!layer) {
00368 env->screens.selected()->layers.begin();
00369 layer->sel(true);
00370 }
00371
00372 switch(key) {
00373
00374
00375
00376
00377
00378 case KEY_PLUS: layer->set_zoom( layer->zoom_x + 0.01,
00379 layer->zoom_y + 0.01); break;
00380 case KEY_MINUS: layer->set_zoom( layer->zoom_x - 0.01,
00381 layer->zoom_y - 0.01); break;
00382 case '.': layer->set_zoom(1,1); break;
00383
00384
00385 case '<': layer->set_rotate( layer->rotate + 0.5 ); break;
00386 case '>': layer->set_rotate( layer->rotate - 0.5 ); break;
00387 case ',': layer->set_rotate(0); break;
00388 case 'z': layer->antialias =
00389 !layer->antialias; break;
00390
00391
00392 case '8':
00393 case 'k':
00394 case SL_KEY_UP:
00395 layer->set_position(layer->geo.x,layer->geo.y-movestep);
00396 break;
00397 case '2':
00398 case 'j':
00399 case SL_KEY_DOWN:
00400 layer->set_position(layer->geo.x,layer->geo.y+movestep);
00401 break;
00402 case '4':
00403 case 'h':
00404 case SL_KEY_LEFT:
00405 layer->set_position(layer->geo.x-movestep,layer->geo.y);
00406 break;
00407 case '6':
00408 case 'l':
00409 case SL_KEY_RIGHT:
00410 layer->set_position(layer->geo.x+movestep,layer->geo.y);
00411 break;
00412 case '7':
00413 case 'y':
00414 layer->set_position(layer->geo.x-movestep,layer->geo.y-movestep);
00415 break;
00416 case '9':
00417 case 'u':
00418 layer->set_position(layer->geo.x+movestep,layer->geo.y-movestep);
00419 break;
00420 case '1':
00421 case 'b':
00422 layer->set_position(layer->geo.x-movestep,layer->geo.y+movestep);
00423 break;
00424 case '3':
00425 case 'n':
00426 layer->set_position(layer->geo.x+movestep,layer->geo.y+movestep);
00427 break;
00428
00429 case '5':
00430 case KEY_SPACE:
00431
00432 layer->set_position
00433 ( (env->screens.selected()->geo.w - layer->geo.w)/2,
00434 (env->screens.selected()->geo.h - layer->geo.h)/2 );
00435 break;
00436
00437 case SL_KEY_ENTER:
00438 case KEY_ENTER:
00439 case KEY_CTRL_I:
00440 ::act("layer repositioned");
00441 set_parser(DEFAULT);
00442 break;
00443
00444 default:
00445 res = false;
00446 break;
00447 }
00448 return(res);
00449 }
00450
00451
00452
00453
00454 bool SlwReadline::parser_commandline(int key) {
00455 int res, c;
00456 bool parsres = true;
00457 Entry *entr = NULL;
00458
00459 commandline = true;
00460
00461
00462 if(cursor>MAX_CMDLINE) {
00463 error("command too long, can't type more.");
00464 return(parsres);
00465 }
00466
00467
00468 color = PLAIN_COLOR;
00469
00470 switch(key) {
00471
00472 case SL_KEY_ENTER:
00473 case KEY_ENTER:
00474
00475 if(command[0]==EOL || command[0]==EOT) {
00476 set_parser(DEFAULT);
00477 break;
00478 }
00479
00480 res = (*cmd_process)(env,command);
00481 if(res<0) break;
00482
00483 set_parser(DEFAULT);
00484
00485 entr = new Entry();
00486 entr->data = strdup(command);
00487 history.append( entr );
00488 if(history.len()>32)
00489 delete history.begin();
00490
00491 memset(command, EOL, MAX_CMDLINE);
00492 break;
00493
00494 case SL_KEY_UP:
00495
00496 entr = history.selected();
00497 if(!entr) {
00498 entr = history.end();
00499 if(entr) entr->sel(true);
00500 } else {
00501 entr = entr->prev;
00502 if(entr) {
00503 history.sel(0);
00504 entr->sel(true);
00505 }
00506 }
00507 if(!entr) break;
00508 strncpy(command,(char*)entr->data,MAX_CMDLINE);
00509
00510 cursor = strlen(command);
00511
00512 break;
00513
00514 case SL_KEY_DOWN:
00515
00516 if(!entr) break;
00517 if(!entr->next) break;
00518 entr = entr->next;
00519 strncpy(command,(char*)entr->data,MAX_CMDLINE);
00520
00521 cursor = strlen(command);
00522
00523
00524 break;
00525
00526 case KEY_CTRL_G:
00527 set_parser(DEFAULT);
00528
00529 memset(command, EOL, MAX_CMDLINE);
00530 break;
00531
00532 case KEY_TAB:
00533 if(!cmd_complete) break;
00534 if(command[0]=='\n') command[0]=0x0;
00535 res = (*cmd_complete)(env,command);
00536 if(!res) break;
00537
00538
00539
00540
00541
00542
00543 cursor = strlen(command);
00544
00545 break;
00546
00547
00548 case KEY_BACKSPACE:
00549 case KEY_BACKSPACE_APPLE:
00550 case KEY_BACKSPACE_SOMETIMES:
00551 if(!cursor) break;
00552
00553 for(c=cursor;c<MAX_CMDLINE;c++) {
00554 command[c-1] = command[c];
00555 if(command[c]==EOL) break;
00556 }
00557 cursor--;
00558
00559
00560 break;
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 case SL_KEY_LEFT:
00571 if(cursor) cursor--;
00572
00573 break;
00574 case SL_KEY_RIGHT:
00575 if(command[cursor]) cursor++;
00576
00577 break;
00578
00579 case KEY_CTRL_D:
00580 for(c=cursor;command[c]!=EOL;c++)
00581 command[c] = command[c+1];
00582
00583
00584
00585
00586
00587
00588 break;
00589
00590 case KEY_CTRL_A:
00591 case KEY_HOME:
00592 cursor=0;
00593
00594 break;
00595
00596 case KEY_CTRL_E:
00597 while(command[cursor]!=EOL) cursor++;
00598
00599 break;
00600
00601 case KEY_CTRL_K:
00602 for(c=cursor;command[c]!=EOL;c++)
00603 command[c] = EOL;
00604
00605
00606 break;
00607
00608 case KEY_CTRL_U:
00609 for(c=0;command[cursor+c]!=EOL;c++)
00610 command[c] = command[cursor+c];
00611 for(;command[c]!=EOL;c++)
00612 command[c] = EOL;
00613 cursor=0;
00614
00615
00616 break;
00617
00618 default:
00619 parsres = false;
00620 break;
00621
00622 }
00623
00624
00625
00626
00627 if( key >= 32 && key < 127) {
00628 for(c=cursor;command[c]!=EOL;c++);
00629
00630 command[c+1] = EOL;
00631
00632 for(;c>cursor;c--)
00633 command[c] = command[c-1];
00634
00635 command[cursor] = key;
00636
00637 cursor++;
00638 parsres = true;
00639 }
00640
00641 return(parsres);
00642 }
00643