Как я могу настроить завершение GtkComboBoxText
как с "статическим" аспектом, так и с "динамическим"? Статический аспект заключается в том, что некоторые записи известны и добавляются в текст со списком во время построения с gtk_combo_box_text_append_text
. Динамический аспект заключается в том, что мне также необходимо выполнить некоторые функции обратного вызова (-ов), которые должны выполняться динамически - после создания виджета GtkComboBoxText
- после ввода нескольких символов.
Мое приложение использует Boehm GC (за исключением GTK-объектов, конечно), таких как Guile или SCM или Bigloo. Его можно рассматривать как экспериментальную персистентную динамически типизированную реализацию языка программирования с интегрированным редактором, закодированным на и для Debian/Linux/x86-64 с помощью библиотеки GTK3.21, он закодирован на C99 (некоторые из которых сгенерированы) и скомпилирован с GCC6.
(меня не интересуют системы, отличные от Linux, библиотеки GTK3 старше GTK3.20, компилятор GCC старше GCC6)
вопрос вопросов
Я ввожу (вводя в GtkComboBoxText
) либо имя, либо идентификатор объекта.
-
Имя является C-идентификатором, но начинается с буквы и не может заканчиваться символом подчеркивания. Например,
comment
,if
,the_GUI
,the_system
,payload_json
илиx1
являются допустимыми именами (но_a0bcd
foobar_
gtk_combo_box_append_text
для каждого имени). -
Идентификатор объекта начинается с символа подчеркивания, за которым следует цифра, и имеет ровно 18 буквенно-цифровых (произвольных) символов. Например,
_5Hf0fFKvRVa71ZPM0
,_8261sbF1f9ohzu2Iu
,_0BV96V94PJIn9si1K
являются объектами-объектами. На самом деле это 96 почти случайных бит (возможно, возможно только 2 94). Идентификатор объекта играет роль UUID (в том смысле, что он считается уникальным для всего мира для разных объектов), но имеет C дружественный синтаксис. В настоящее время у меня есть несколько десятков объектов-идентификаторов, но у меня может быть несколько сотен тысяч (или, может быть, миллионов) из них. Но, учитывая префикс из четырех символов, таких как_6S3
или_22z
, я предполагаю, что в моем приложении с этим префиксом существует только разумное число (вероятно, не более тысячи и, конечно, не более тысячи) объектов-идентификаторов. Конечно, было бы необоснованным регистрировать (статически) априори все идентификаторы объектов (завершение должно происходить после ввода четырех символов и должно происходить динамически).
Итак, я хочу, чтобы завершение, которое работает как над именами (например, для ввода одной буквы, за которой следует другой символ алфавита, должно быть достаточно, чтобы предлагать не более ста выборов), так и на объектных идентификаторах (набрав четыре символа, например _826
должно быть достаточно, чтобы вызвать завершение, вероятно, не более нескольких десятков вариантов, возможно, тысячи, если не повезет).
Следовательно, набрав три клавиши p a tab, вы получите завершение с несколькими именами, такими как payload_json
или payload_vectval
и т.д.... и набрав пять клавиш _ 5 H f tab предложит завершение с очень небольшим количеством объектов-идентификаторов, особенно _5Hf0fFKvRVa71ZPM0
образец неполного кода
До сих пор я кодировал следующее:
static GtkWidget *
mom_objectentry (void)
{
GtkWidget *obent = gtk_combo_box_text_new_with_entry ();
gtk_widget_set_size_request (obent, 30, 10);
mo_value_t namsetv = mo_named_objects_set ();
У меня есть значения, полученные от Boehm-garbage, а mo_value_t
- указатель на любой из них. Значения могут быть помечены целыми числами, указателями на строки, объекты или кортежи или наборы объектов. Итак, namesetv
теперь содержит множество именованных объектов (возможно, менее нескольких тысяч названных объектов).
int nbnam = mo_set_size (namsetv);
MOM_ASSERTPRINTF (nbnam > 0, "bad nbnam");
mo_value_t *namarr = mom_gc_alloc (nbnam * sizeof (mo_value_t));
int cntnam = 0;
for (int ix = 0; ix < nbnam; ix++)
{
mo_objref_t curobr = mo_set_nth (namsetv, ix);
mo_value_t curnamv = mo_objref_namev (curobr);
if (mo_dyncast_string (curnamv))
namarr[cntnam++] = curnamv;
}
qsort (namarr, cntnam, sizeof (mo_value_t), mom_obname_cmp);
for (int ix = 0; ix < cntnam; ix++)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (obent),
mo_string_cstr (namarr[ix]));
в этот момент я отсортировал все имена (несколько тысяч) и добавил "статически" их с помощью gtk_combo_box_text_append_text
.
GtkWidget *combtextent = gtk_bin_get_child (GTK_BIN (obent));
MOM_ASSERTPRINTF (GTK_IS_ENTRY (combtextent), "bad combtextent");
MOM_ASSERTPRINTF (gtk_entry_get_completion (GTK_ENTRY (combtextent)) ==
NULL, "got completion in combtextent");
Я с удивлением заметил, что gtk_entry_get_completion (GTK_ENTRY (combtextent))
имеет значение null.
Но я застрял здесь. Я думаю:
-
Наличие некоторого
mom_set_complete_objectid(const char*prefix)
, который далprefix
как"_47n"
не менее четырех символов, возвратил собранный мусоромmo_value_t
, представляющий набор объектов с этим префиксом. Это очень легко кодировать для меня, и это почти сделано. -
Создайте собственный локальный
GtkEntryCompletion* mycompl =
..., который будет завершен, как я хочу. Затем я поместил бы его в текстовую записьcombtextent
моего gtk-combo-box-text, используяgtk_entry_set_completion(GTK_ENTRY(combtextent), mycompl);
Должны ли они использовать записи, добавленные с помощью gtk_combo_box_text_append_text
для роли статического имени? Как я должен динамически завершить использование значения динамического набора, возвращаемого с моего mom_set_complete_objectid
; учитывая некоторый объект-указатель obr
и некоторый char bufid[20];
, я легко и быстро могу заполнить его объектным идентификатором этого объекта obr
с помощью mo_cstring_from_hi_lo_ids(bufid, obr->mo_ob_hid, obr->mo_ob_loid)
..
Я не знаю, как закодировать выше. Для справки, теперь я просто возвращаю combo-box-текст:
// if the entered text starts with a letter, I want it to be
// completed with the appended text above if the entered text starts
// with an undersore, then a digit, then two alphanum (like _0BV or
// _6S3 for example), I want to call a completion function.
#warning objectentry: what should I code here?
return obent;
} /* end mom_objectentry */
Мой подход правильный?
Функция mom_objectentry
выше используется для заполнения модальных диалогов с коротким временем жизни.
Я предпочитаю простой код по эффективности. На самом деле мой код временный (я надеялся загрузить мой язык и сгенерировать все его C-код!), И на практике у меня, вероятно, будет всего несколько сотен имен и самое большее несколько десятков тысяч объектов-идентификаторов. Таким образом, производительность не очень важна, но более важна простота кодирования (какой-то концептуально "выброшенный" код).
Я не хочу (если возможно) добавлять свои собственные классы GTK. Я предпочитаю использовать существующие классы и виджеты GTK, настраивая их с помощью сигналов GTK и обратных вызовов.
Контекст
Мое приложение представляет собой экспериментальный постоянный язык программирования и реализацию с близким Scheme или Python (или JavaScript, игнорируя прототип,...) семантика, но с совершенно другим (еще не реализованным в сентябре 7 th 2016) синтаксисом (который будет показан и введен в виджеты GTK), используя сборщик мусора Boehm для значения (включая объекты, наборы, кортежи, строки...)... Значения (включая объекты), как правило, постоянны (за исключением связанных с GTK данных: приложение начинается с почти пустого окна). Вся языковая куча сохраняется в JSON-подобном синтаксисе в некоторой базе данных Sqlite (сгенерированной при выходе приложения), сбрасываемой в _momstate.sql
, которая повторяется - загружается при запуске приложения. Идентификаторы объектов полезны для отображения ссылок объектов на пользователя в виджетах GTK, настойчивости и для генерации C-кода, связанного с объектами (например, объект id _76f7e2VcL8IJC1hq6
может быть связан с идентификатором mo_76f7e2VcL8IJC1hq6
в некотором сгенерированном C код, отчасти потому, что у меня есть свой формат идентификатора объекта вместо использования UUID).
PS. Мой код C - бесплатное программное обеспечение GPLv3 и доступно на github. Это монитор MELT, ветвь expjs, commit e2b3b99ef66394...
NB: Объекты, упомянутые здесь, неявно являются моими языковыми объектами, а не объектами GTK. У всех есть уникальный идентификатор объекта, а некоторые, но не большинство из них, называются.