HdyTab як альтернатива віджету вкладок GtkNotebook

Якщо ви тільки починаєте своє знайомство з фреймворком GTK, можливо, як і в мене, виникне схожа дилема з обмеженою функціональністю класичного віджету для створення вкладок GtkNotebook. В мережі віднайшов матеріал 2021 року "Reinventing tabs", в якому розглядається проблема стандартного віджету та пропонується альтернатива - HdyTab.

Переосмислення вкладок

В робочому столі GNOME 40, браузер Epiphany має нову панель вкладок. Це не просто переробка старої панелі, а повне її переписування з нуля:

Вигляд вкладок в Epiphany

Але для чого це було необхідно?

Статичні та динамічні вкладки

Додатки GNOME використовують вкладки різними способами, їх можна приблизно поділити на дві категорії.

Статичні вкладки

Вигляд статичних вкладок в різних діалогах

Вони є повністю незмінними, кожна вкладка містить заголовок і зазвичай не прокручуються. Зазвичай їх використовують у діалогових вікнах, але, наприклад, їх також можна використовувати в панелях інструментів. Сучасні додатки часто використовують GtkStackSwitcher або HdyViewSwitcher, але GtkNotebook все ще досить поширений.

Динамічні вкладки

Вигляд gedit, GNOME Terminal, Nautilus, GNOME Editor, Devhelp, Sysprof, Epiphany

Цей тип вкладок використовується в багатовіконних додатках, таких як веб-браузери, текстові редактори, файлові менеджери або емулятори терміналів. Вони відкриваються та закриваються користувачем, їх можна змінювати за порядком, перетягувати між вікнами або в нові вікна, скидаючи їх на робочий стіл. Вони часто реалізують прокрутку. Завжди мають заголовок і кнопку закриття, іноді іконку та/або індикатор завантаження. Вони ховаються, коли присутня лише одна вкладка. Їх можна закривати середнім кліком або через контекстне меню. Іноді, динамічні вкладки можна закріпити або додати іконку, наприклад, індикатор відтворення аудіо чи діалог підтвердження закриття.

Чому така різниця?

Хоча статичні вкладки в GNOME досить однорідні, динамічні вкладки в різних додатках виглядають і відчуваються дуже по-різному.

Наприклад:

GtkNotebook

Усі додатки вище використовують віджет під назвою GtkNotebook. Він реалізує загальний вигляд з вкладками та показує вкладки з одного боку, причому кожна вкладка має заголовок, який можна замінити на будь-який інший віджет.

За замовчуванням GtkNotebook не має засобів прокручування, має простий заголовок на кожній вкладці, не розширює вкладки та не дозволяє жодного виду перетягування.

Іншими словами, він орієнтований виключно на статичні вкладки. Це не означає, що його неможливо використовувати для динамічних вкладок, але вам доведеться вручну реалізувати наступне:

Ці вимоги підкреслюють, що хоча GtkNotebook може бути використаний для динамічних вкладок, його базова реалізація не підтримує багато функцій, які користувачі очікують від сучасних динамічних вкладок, і вимагає значних зусиль для налаштування.

Звісно, кожен додаток реалізує ці функції трохи по-різному. А ще є проблеми, які не можна повністю вирішити з боку додатка, наприклад, відсутня функціональність закріплених вкладок або інтерфейс загалом не дуже відшліфований - не має анімації при відкритті або закритті вкладок.

Також, прокручування вкладок є дискретним, це виглядає заплутано і викликає інші проблеми:

Ці проблеми підкреслюють, що, хоча додатки можуть намагатись реалізувати динамічні вкладки засобами статичного віджета GtkNotebook, існують обмеження, які ускладнюють створення зручного та інтуїтивно зрозумілого досвіду для користувачів.

Деякі з таких проблем можна замаскувати:

Вигляд компактно закріплених вкладок
Вигляд закріплених вкладок при зміні ширини вікна

Крім того, GtkNotebook містить як вміст, так і вкладки, і вони є невід'ємними, тому неможливо мати вкладки у повноекранному режимі, автоматично приховуючи їх з заголовної панелі, або розміщувати їх у панелі заголовку, відокремлено від вмісту.

Нарешті, GtkNotebook не є адаптивним, і Epiphany наразі має вбудовану реалізацію мобільного перемикача вкладок, яку кожен додаток, що прагне адаптивного інтерфейсу з вкладками - повинен буде копіювати.

Ці обмеження підкреслюють, що GtkNotebook не забезпечує гнучкості, необхідної для сучасних інтерфейсів, які можуть адаптуватися до різних розмірів екранів і режимів використання. Відсутність можливості розміщення вкладок окремо від вмісту обмежує можливості дизайну, а необхідність копіювати реалізацію мобільного перемикача вкладок може призвести до дублювання зусиль і несумісності між додатками.

HdyTab як рішення

Як виглядають вкладки HdyTab

Отже, з урахуванням усіх цих обмежень, я вважаю, що найчистішим шляхом вперед є створення абсолютно нового віджета, який реалізує специфічно динамічні вкладки. Таким чином, також зможемо відокремити перегляд вкладок і панель вкладок в окремі віджети, так само як GtkStack і GtkStackSwitcher - є окремими.

Реалізацію цього віджета було розпочато незадовго до GUADEC 2020 року, і до кінця вересня, на момент долучення до Purism (https://puri.sm) - її було майже завершено. У січні ми з Адрієном нарешті знайшли час, щоб закінчити, переглянути та впровадити його.

Результатом цього стали два віджети під назвою HdyTabView і HdyTabBar, доступні в бібліотеці libhandy, починаючи з версії 1.2:

HdyTabView містить GtkStack і надає API, більш придатний для динамічних вкладок: наприклад, сторінки відтепер строго впорядковані, є API для перестановки вкладок тощо. Крім того, кожна сторінка має велику кількість метаданих, вона використовує об'єкти сторінок, схожі на GTK 4 (HdyTabPage), навіть у GTK 3, замість властивостей дочірніх елементів, які було б досить незручно використовувати без прив'язок властивостей.

HdyTabBar є панеллю вкладок, яка підключається до HdyTabView і відображає його сторінки, реалізуючи цей дизайн:

Вигляд різних реалізацій вкладок

Що він забезпечує

Вигляд непрочитаних вкладок
Вигляд індикаторів вкладок

Коли вкладка закріплена, індикатор відображається замість іконки, а не поруч з нею, як це було раніше в Epiphany. Щоб забезпечити легкий вибір вкладки, вона є клікабельною лише тоді, коли вкладка вже вибрана, тому перший клік вибирає вкладку, а другий клік - активує індикатор.

- Ctrl+Tab і Shift+Ctrl+Tab - перемикання між вкладками з обгортанням

- Ctrl+PageUp/PageDown/Home/End - те ж саме, але без обгортання

- Ctrl+Shift+PageUp/PageDown/Home/End - перестановка вкладок

- Alt+[1–9] - перемикання на одну з перших 9 вкладок

Той факт, що вони є окремими, дозволяє Epiphany зберігати свою панель вкладок у повноекранному режимі в 40 версії:

Вигляд вкладок у повноекранному режимі Epiphany

Чого він не забезпечує

Оскільки Epiphany також використовується в Elementary OS, HdyTabBar надає API для вимкнення автоматичного приховування та розширення вкладок, а також для зміни місцями кнопки закриття та індикатора. Усі ці параметри все ще працюють так, як і раніше.

Вигляд Epiphany в "елементарному режимі"

Адаптивність

HdyTabBar поки що не є адаптивним. Epiphany все ще постачає той самий мобільний інтерфейс у версії 40. Однак це значно полегшує реалізацію альтернативних комутаторів, наприклад, нижній аркуш на основі HdyFlap:

Вигляд перемикача вкладок для мобільних пристроїв у стадії розробки

Однак це дуже базово. Мобільні перемикачі вкладок часто є дуже складними, наприклад, використовують 3D-стеки карток, сітки, каруселі або списки з попередніми переглядами. На жаль, усе це недоступно в GTK 3. Однак у GTK 4 це можливо, і ми можемо робити такі речі:

Вигляд вкладок у режимі каруселі
Вигляд вкладок у режимі сітки

Маючи належний огляд, можна буде нарешті видалити спливаюче вікно вкладок з Epiphany, яке все ще є в 40 версії, але показується лише тоді, коли панель вкладок починає прокручуватися.

Порт HdyTabView і HdyTabBar на GTK 4 завершено і повністю працює, і йому просто потрібен код-рев'ю, хоча огляд ще не є повторно використовуваним віджетом.

Джерело

Reinventing tabs, Alice Mikhaylenko's GNOME blog