LINUX.ORG.RU
ФорумTalks

GTK facepalm

 ,


0

2

Добры молодцы из команды GTK навертали чертову уйму классов для отделения логики от интерфейса. Все эти GtkAction, GtkUiManager, GtkActivatable и прочие упоительные названия.

У GtkAction есть имя, иконка, тултип, состояния sensetive и visible. На их основе генерируется внешний вид и состояния менюшечек и тулбаров. Короче, всё как у взрослых.

Почти. Если не считать того досадного факта, что тултип абсолютно бесполезен, т.к. не используется при создании меню.

Ладно. Решаю по-быстрому накалякать пару костылей — у нас же ООП, реюз кода во все поля и всё такое прочее. Мы можем переопределять поведение объектов и разводить руками тучи.

GtkImageMenuItem реализует интерфейс GtkActivatable и через него получает апдейты состояния. Ок, унаследуем свой класс от GtkImageMenuItem и допишем нужный код по установке тултипа.

GtkAction рожает из себя менюшки на основе класса, указанного в одном из полей своего класса. Ок, унаследуем свой класс от GtkAction и переопределим поле, засунув туда собственный класс менюитема.

Всё красиво, всё поООПшному, архитектурные космонавты в восторге.

Стоп. Про что-то мы забыли. А кто создаёт GtkAction-ы? GtkAction-ы создаёт GtkActionGroup. Открываем код. Смотрим. Еще раз смотрим. Хлопаем глазами и не верим в то, что видим:

void
gtk_action_group_add_actions_full (GtkActionGroup       *action_group,
				   const GtkActionEntry *entries,
				   guint                 n_entries,
				   gpointer              user_data,
				   GDestroyNotify        destroy)
{

  /* Keep this in sync with the other 
   * gtk_action_group_add_..._actions_full() functions.
   */
  guint i;
  SharedData *shared_data;

  g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));

  shared_data = g_slice_new0 (SharedData);
  shared_data->ref_count = 1;
  shared_data->data = user_data;
  shared_data->destroy = destroy;

  for (i = 0; i < n_entries; i++)
    {
      GtkAction *action;
      const gchar *label;
      const gchar *tooltip;

      if (!check_unique_action (action_group, entries[i].name))
        continue;

      label = gtk_action_group_translate_string (action_group, entries[i].label);
      tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);

      action = gtk_action_new (entries[i].name,
			       label,
			       tooltip,
			       NULL);

Даааа, дааа, да! Развесистое дерево наследований. Абстрактные интерфейсы. Переменные класса. Фантастика на грани техники. Чертова уйма overengineered кода, который абсолютно бесполезен, потому что в итоге всё равно вся эта развесистая космическая архитектура запинается о вовремя подставленный gtk_action_new(), падает и разбивается к едреней фене. И хоронит под собой все ваши иллюзии, будто ООП волшебным образом превращает всех плохих программистов в хороших. Enjoy your code reuse.

А, да: баг репортить не буду. Если кому надо, репортите сами. Я ж обещал, что к разработке стека гномобиблиотек и пальцем не притронусь, даже на уровне отсылки багов. Лучше пойду придумаю обычный костыль с ручным назначением тултипов, без всей этой архитектурной космонавтики.

Ответ на: комментарий от stevejobs

(c), кажется, Матвей Кожев

опять ты пьяный неправильно копипастишь

amorpher ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.