Первый раз постер; давний поклонник стека переполнения ангелов.
У меня проблема с цветами в тексте span, которые контролируются Pango.
Длинная версия:
Я обновляю старую программу с пользовательским интерфейсом, в которой есть C ++, GTK, XML (написанный Glade) и RC-таблица стилей, обрабатывающая графику. Часть нашего цветного текста разметки жестко запрограммирована в XML. Некоторые из них динамически устанавливаются в коде C ++.
Проблема в том, что когда программа запускается на наших старых системах, цвет, на который ссылается текст span как «зеленый», отображается как # 00FF00. На наших более новых системах «зеленый» отображается как # 008000.
Пример печати кода на виджет этикетки:
gtk_label_set_markup((GtkLabel *) TitleBarLabel, "<span color='green'>Orbital Cannon Positioning</span>");
Я вполне уверен, что Pango контролирует разметку span-текста. Я обнаружил, что разница между зелеными цветами точно равна разнице между списками цветов X11 и W3C (https://en.wikipedia.org/wiki/X11_color_names#Clashes_between_web_and_X11_colors).
Кажется, что наши старые системы используют X11, а наши новые используют W3C, что имеет смысл.
Я мог бы просто заменить все экземпляры ‘green’ на ‘# 00FF00’, но если бы мы хотели изменить цвета в будущем, нам пришлось бы снова пройти через все это. Я бы предпочел, чтобы цвета менялись через таблицу стилей, а не вставлялись в код.
Код C ++:
GtkWidget * TitleBarLabel;
TitleBarLabel = GTK_WIDGET (get_builder_object (builder, "TitleBarLabel"));
gtk_label_set_markup((GtkLabel *) TitleBarLabel, "<span color='#00FF00'>Death Ray Power Status</span>");
Я могу создать GdkColor во время выполнения и gdk_color_parse со значениями из файла конфигурации, а затем использовать gtk_widget_modify_text (), чтобы применить цвет к виджетам надписей. Но тогда это не работает для всех жестко закодированных текстов в XML. Кроме того, у нас есть множество этикеток с кусочками текста, окрашенными по-разному внутри одной и той же строки.
Код C ++:
GdkColor pass_color;
gdk_color_parse("#00FF00", &pass_color);
gtk_widget_modify_text(TitleBarLabel, GTK_STATE_NORMAL, &pass_color);
Я могу создать стиль в своем RC-файле для каждого цвета и связать каждую метку, которая будет использовать этот цвет во время выполнения. Но нам пришлось бы удалить все цвета разметки и добавить много кода для захвата виджетов, с которым мы никогда не сталкивались раньше, и код для установки имен виджетов вместо того, чтобы просто печатать на них с новым текстом span. Это дает желаемый результат изменения цвета в таблице стилей, но это сложное мероприятие, и оно не интуитивно понятно для наших опытных инженеров, которые привыкли использовать атрибуты цвета.
RC файл:
style "pass_color"{
fg[NORMAL] = #00FF00
}
widget "*TitleBarLabel_Pass" style "pass_color"
Код C ++:
gtk_widget_set_name(TitleBarLabel, "TitleBarLabel_Pass");
Укороченная версия:
В идеале я хотел бы иметь возможность создавать новый цвет во время выполнения, чтобы мы могли связать его с таким текстом:
<span color='MyNewColor'>Weather Manipulation Settings</span>
Или, может быть, даже создать новый тег, который применяет определенные атрибуты, например:
<span><MyNewColor>Shark Tank pH Balance</MyNewColor></span>
Но я сомневаюсь, что это возможно.
Я пытался поиграться с pango_attr_type_register (), pango_attr_foreground_new () и друзьями, но я не мог понять, как работают атрибуты, если они могут даже делать то, что я думал, что они сделали. После долгих исследований, похоже, что «атрибут» — это единовременная настройка для одной строки текста. И не новое значение, которое можно вызвать в соответствии с текстом span, как я и надеялся.
Возможно ли что-нибудь подобное дистанционно, без перестройки всего Панго?
Есть ли какая-то другая работа, которая заставила бы меня создать таблицу стилей наподобие установки?
На данный момент я открыт для предложений.
Версия Характеристики:
Компьютеры, показывающие зеленый цвет как # 00FF00
ОС: Linux Slackware 13.37 и ниже
GTK: 2.24.4
Панго: 1.28.4
Компьютеры, показывающие зеленый цвет как # 008000
ОС: Linux Slackware 14.1
GTK: 2.24.20
Панго: 1.34.1
Если вы можете использовать GTK 3.x, я бы посоветовал сделать это там, где это гораздо проще сделать с помощью CSS. Есть даже способ использовать несколько стилей CSS для разных регионов в одной и той же метке, хотя это неудобно.
В GTK 2, как вы заметили, вы можете ссылаться на виджеты по их name
Свойство в вашем файле RC:
widget "shark-tank-ph-label" style "green-text"style "green-text" {
text[NORMAL] = #008000
}
Я бы порекомендовал использовать этот подход, даже если это не то, к чему вы привыкли. Повторный рефакторинг для удаления жестко закодированных цветов с ваших ярлыков значительно облегчит следующий раз, когда вам придется что-то менять, а также приблизит ваш код к тому, как все будет работать в GTK 3.x, если вы решите сделать порт в будущем.
Других решений пока нет …