c - gtk+ 文本编辑器 vim 类型模式(插入/命令)

标签 c gtk keypress gtksourceview

我正在尝试将类似于 vim 的功能合并到我在 gtk+ 2.0 和 gtksourceview 2.0 中创建的文本编辑器中。我让它工作,除了当我按“i”进入插入模式时,它正确进入此模式,但随后它在文本缓冲区中键入“i”。这是我的按键函数,设置为在按下 esc 键时进入命令模式(离开插入模式),正如我之前所说,按下 i 键时进入插入模式:

gboolean on_key_press_win_main (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{

  switch (event->keyval)
  {

    case GDK_i:
      if (event->state & GDK_CONTROL_MASK)
      {
        printf("key pressed: %s\n", "ctrl + i");
      }
      else
      {
        GtkTextBuffer *tbuffer;
                GtkTextView *text_view;
                int page = 0;
        gchar *msg;
        gint row, col;
        GtkTextIter iter;

              page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
                text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
                tbuffer = gtk_text_view_get_buffer (text_view);

        if (insert_mode == 0)
        {
            insert_mode = 1;
            command_mode = 0;

            /* update statusbar */
            gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0); 

            gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));

            row = gtk_text_iter_get_line(&iter);
            col = gtk_text_iter_get_line_offset(&iter);

            msg = g_strdup_printf("INSERT\t\t Col %d Ln %d", col+1, row+1);
            gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);

            gtk_text_view_set_editable (text_view, TRUE);

        }

      }

      break;

        /* esc key */
        case 65307:
    {
        GtkTextBuffer *tbuffer;
          GtkTextView *text_view;
          int page = 0;
      gchar *msg;
      gint row, col;
      GtkTextIter iter;

        page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
          text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
          tbuffer = gtk_text_view_get_buffer (text_view);

      insert_mode = 0;
      command_mode = 1;
      gtk_text_view_set_editable (text_view, FALSE);

      /* update statusbar */
      gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0); 

      gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));

      row = gtk_text_iter_get_line(&iter);
      col = gtk_text_iter_get_line_offset(&iter);

      msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);
      gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);

    }

    break;

    default:
      return FALSE; 
  }

  return FALSE; 
}

如您所见,gtk_text_view_set_editable (text_view, FALSE) 在进入命令模式时设置,gtk_text_view_set_editable (text_view, TRUE) 在进入插入模式时设置。但是,当进入插入模式时,在按键注册到缓冲区之前,text_view 被设置为可编辑,即使它是按键情况下的最后一个命令。进入插入模式时如何防止 i 被放置在文本缓冲区中?

最佳答案

从事件处理程序返回 TRUE 而不是 FALSE 以阻止对该事件的任何进一步处理。事件处理程序的工作方式类似于过滤器,您可以过滤掉不想传递到 TextView 的击键。

PS。不要使用像 65307 这样的常量,使用 GDK_KEY_Escape 或其他任何东西。

关于c - gtk+ 文本编辑器 vim 类型模式(插入/命令),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10908679/

相关文章:

c - 是一个==*一个??关于指针的查询

c - 文件处理时我的二进制搜索树代码中的段错误

c - 从无符号int提取位的函数

c++ - 如何去除 "default button"边框?

javascript - 带按键代码参数的模拟按键功能 Jquery

wpf - 如何在 WPF 中使用按键中断 while 循环?

能否将多维数组作为指针传递给 C 函数,然后在函数内部将它们转换回数组?

c - 从C中的GTK3 ComboBox中获取选定的文本

c - 【C初学】GTK+及初学题

c++ - Qt keyPressEvent 错误