Question

I am using Gtkmm 3+ and What I am trying to do is have the text buffer have the constant string "> " even if the user tries to delete it. In addition when the user pressed return it will automatically be there again. Basically have a constant string like a terminal does.

The only way I can think about about accomplishing this would be to connect to the delete and backspace signals so the user cannot delete the string. But, is there a better way?

so far this is the only way I can think of:

//in constructor
txt_view_i_.signal_event().connect(sigc::mem_fun(*this, &MainWindow::inputEvent));

//function
bool MainWindow::inputEvent(GdkEvent* event)
{
    if((event->key.keyval == GDK_KEY_BackSpace || event->key.keyval == GDK_KEY_Delete) && buffer_input_->get_char_count() < 3)
        return true;

    return false;
}

But doesn't work perfectly, because if you type in more then 3 characters then go to the beginning of the line you can delete the constant string.

Another way I just thought about was to add a label to the TextView widget. I did that but, the user could still delete it. Here is the code for that:

Gtk::TextBuffer::iterator it = buffer_input_->get_iter_at_line(1);
Glib::RefPtr<Gtk::TextChildAnchor> refAnchor = buffer_input_->create_child_anchor(it);
Gtk::Label* lbl = Gtk::manage(new Gtk::Label("> "));
txt_view_i_.add_child_at_anchor(*lbl, refAnchor);
Was it helpful?

Solution

This is very similar, but not quite identical, to the question I answered here: You can create a GtkTextTag that makes its contents uneditable, and apply it from the beginning of the buffer up to and including the "> " prompt.

Then when you receive input, append your output to the buffer and then append a new prompt on the next line, and re-apply the tag to make the whole thing uneditable.

The links in the linked answer show some C code where this is done, even including a prompt. It's not Gtkmm or C++, but it should serve as an illustration.

OTHER TIPS

Here is the code I used to solve it:

Glib::RefPtr<Gtk::TextBuffer::Tag> tag = Gtk::TextBuffer::Tag::create();
tag->property_editable() = false;
Glib::RefPtr<Gtk::TextBuffer::TagTable> tag_table =  Gtk::TextBuffer::TagTable::create();
tag_table->add(tag);
buffer_input_ = Gtk::TextBuffer::create(tag_table);
txt_view_i_.set_buffer(buffer_input_);
scroll_win_i_.add(txt_view_i_);

Gtk::TextBuffer::iterator buffer_it_ = buffer_input_->begin();
buffer_input_->insert_with_tag(buffer_it_, "> ", tag);

Here is how I made it so that the user cannot edit before the constant string:

//connect to the mark set signal
buffer_input_->signal_mark_set().connect(sigc::mem_fun(*this, &MainWindow::setMark));

//make the box uneditable
void MainWindow::setMark(const Gtk::TextBuffer::iterator& it, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark)
{
    if(it.get_offset() < 2)
        txt_view_i_.set_editable(false);
    else
        txt_view_i_.set_editable(true);
}

Hopefully someone will find this useful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top