Tomas Bym wrote:
> Sorry for my bad explanation, AutoCad input line was just an example, my
> application has its own shell. The widget should work similar to "DOS
> commandline" like somebody has mentionned. The Greg proposal to use
> Fl_Text_Editor and handle all keyboard event could work, but would be litle
> bit tricky to make it run.
> Thank you very much for your help, Tomas
Here's a proof of concept of my suggestion to derive a class from
Fl_Text_Editor,
and trap the keystrokes to accumulate a command buffer.
I only tested it on Linux, not windows or mac.
The way it should work: you can add text to the widget with
MyTerminal::append(),
and your cursor should always be at the end.
When you type, text will be added to the editor AND accumulated in
MyTerminal::cmd,
such that when you hit 'Enter', the text you typed is printed to the
console eg:
EXECUTING: '<the text you typed>'
..and the internal buffer cleared, so that you can type a new command
and hit
"Enter". You would replace the fprintf(stderr, "EXECUTING..") line with
code
that runs the command typed.
It also handles backspace so that you can make corrections in the
command
you type, and when you hit 'Enter', you should get the expected results.
So this should allow you to have "prompts", and you can type "commands",
and make corrections with 'Backspace' without being able to backspace
beyond the command you typed (and thus avoiding ruining the "prompt").
The code is a proof of concept, which should point you in the right
direction. It handles the tricky GUI stuff I talked about; trapping
"special" keystrokes (up/down/left/right, etc). The only "special"
keys are allowed are backspace and enter.
Things this doesn't handle:
o Mouse oriented paste operations won't affect the command
buffer.
o Any kind of mouse operations are not supported here. For
instance
you can click the mouse around to set the cursor to places you
shouldn't be able to in a terminal type application.
The mouse stuff can be resolved, I just didn't want to get too carried
away.
#include <string.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Text_Editor.H>
//
// Simple terminal simulator (PROOF OF CONCEPT) -- 1.00 erco 07/30/2009
//
class MyTerminal : public Fl_Text_Editor {
Fl_Text_Buffer *buff;
int in, out;
char cmd[1024];
public:
MyTerminal(int X,int Y,int W,int H,const char* L=0) :
Fl_Text_Editor(X,Y,W,H,L) {
buff = new Fl_Text_Buffer();
buffer(buff);
textfont(FL_COURIER);
textsize(12);
in = out = 0;
cmd[0] = 0;
}
// Append to buffer, keep cursor at end
void append(const char*s) {
buff->append(s);
// Go to end of line
insert_position(buffer()->length());
scroll(count_lines(0, buffer()->length(), 1), 0);
}
int handle(int e) {
switch (e) {
case FL_KEYUP: {
int key = Fl::event_key();
if ( key == FL_Enter ) break;
if ( key != FL_BackSpace && (key < ' ' || key > 0x7f) )
return(0);
if ( key == FL_BackSpace && cmd[0] == 0 ) return(0);
break;
}
case FL_KEYDOWN: {
int key = Fl::event_key();
// Enter key? Execute the command, clear command buffer
if ( key == FL_Enter ) {
fprintf(stderr, "EXECUTING: '%s'\n", cmd); // <--
EXECUTE YOUR COMMANDS HERE
cmd[0] = 0;
break;
}
if ( key != FL_BackSpace && (key < ' ' || key > 0x7f ) )
return(0);
if ( key == FL_BackSpace ) {
// Remove a character from end of command buffer
if ( cmd[0] ) {
cmd[strlen(cmd)-1] = 0;
break;
} else {
return(0);
}
} else {
if ( strlen(cmd) > sizeof(cmd)-2 ) return(0);
// Append text to our 'command' buffer
int i = strlen(cmd);
cmd[i+0] = (char)key;
cmd[i+1] = 0;
}
break;
}
}
return(Fl_Text_Editor::handle(e));
}
};
int main() {
Fl_Double_Window win(620,520,"Terminal Test");
MyTerminal edit(10,10,win.w()-20,win.h()-20);
edit.append("Line one\nLine Two\nHere is your prompt: ");
win.resizable(win);
win.show();
return(Fl::run());
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk