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

Reply via email to