Как раскрасить шрифты в виджетах ярлыков/вводов Gtk3 в Vala?

Мне очень нравится экспериментировать с Vala, и мне удалось решить большинство проблем, с которыми я сталкивался до сих пор. Но то, что заставляет меня тратить немного времени прямо сейчас, — это раскрашивание (и общая модификация) шрифтов в виджетах Gtk3 Label и Entry. Теоретически есть три способа сделать это:

(1) Использование разметки PANGO.

(2) Использование modify_base и modify_bg.

(3) Использование CSS.

Маршрут CSS кажется тем, которому хочет следовать Gtk3; и это, безусловно, самое привлекательное с точки зрения программиста. Но похоже, что в Вале это еще не полностью (или даже не очень) реализовано. Я прав в этом?

Так что на данный момент mod_base и modify_bg приемлемы; за исключением того, что, похоже, работает только modify_bg. Modify_base еще не реализована в Vala?

PANGO немногочисленнее; но в связи с вышеизложенным, хотелось бы знать, насколько хорошо он прикрыт в Вале...

(Пример кода ниже.)

using Gtk;
using Posix;

public class CSStestWindow: ApplicationWindow {

    private string APPNAME = "CSStest";
    private int PAGENO;
    private Gdk.Color LIGHTGREY;
    private Gdk.Color PALEGREEN;
    private Gdk.Color PINK;
    private Gdk.Color PURPLE;
    private Button bQuit = new Button.from_stock(Stock.QUIT);
    private Button bColour = new Button.from_stock(Stock.ADD);
    private Entry eAtitle = new Entry();
    private Entry eBtitle = new Entry();
    private Entry eCtitle = new Entry();
    private Entry eDtitle = new Entry();
    private Label lAtitle = new Label("AAA");
    private Label lBtitle = new Label("BBB");
    private Label lCtitle = new Label("CCC");
    private Label lDtitle = new Label("DDD");
    private Label lTab0 = new Label("First");
    private Label lTab1 = new Label("Second");
    private Label lTab2 = new Label("<span foreground='red'>Third</span>");
    private Label lTab3 = new Label("Fourth");
    private Notebook nbMain = new Notebook();

    internal CSStestWindow(CSStest app) {
        Object(application:app,title:"CSStest");
        Gdk.Color.parse("lightgrey",out LIGHTGREY);
        Gdk.Color.parse("palegreen",out PALEGREEN);
        Gdk.Color.parse("pink",out PINK);
        Gdk.Color.parse("purple",out PURPLE);
        string style = """
            @define-color bg beige;
            @define-color fg blue;
            * {engine:none; font-weight:bold;}
            .window {background-color:@bg;}
        /* those above seem to work, those below don't */
            .redongreen {background-color:green; color:red;}
            .switch {font-style:italic;}
            .entry {background-color:yellow;}
            .entry:selected {font-style:italic;}
            GtkButton {color:#ff00ea; font:Serif 12;}
            GtkButton:hover {background-color:#3085a9;}
            GtkLabel {background-color:#898989;}
            GtkNotebook {background-color:#a939f0;}
            GtkNotebook > GtkEntry {color:@fg; background-color:#1209a2;}
            GtkNotebook tab GtkLabel:focused {font:Serif 12;}
            #lDtitle {background-color:lightblue;}
            #eDtitle {font:Times;}
            :insensitive {background-color:#320a91;}
        """;
        CssProvider provider = new CssProvider();
        try {
            provider.load_from_data(style,-1);
        } catch (GLib.Error e) {
            warning(e.message);
        }
        this.get_style_context().add_provider
            (provider,STYLE_PROVIDER_PRIORITY_THEME);
        this.get_style_context().add_class("window");
        this.window_position = WindowPosition.CENTER;
        this.set_default_size(480,320);
// ---- Set up Notebook -----------------------------------------------
        nbMain.switch_page.connect((p,pn)=>{switchPage(pn);});
        nbMain.set_show_border(true);
// ---- Notebook Tab 0 ------------------------------------------------
        Grid gTab0 = new Grid();
        gTab0.attach(lAtitle,0,0,1,1);
        changeColour(eAtitle,PALEGREEN);
        gTab0.attach(eAtitle,1,0,1,1);
        bQuit.clicked.connect(onQuit);
        gTab0.attach(bQuit,2,0,1,1);
        nbMain.append_page(gTab0,lTab0);
// ---- Notebook Tab 1 ------------------------------------------------
        Grid gTab1 = new Grid();
        gTab1.attach(lBtitle,0,0,1,1);
        changeColour(eBtitle,PINK);
        gTab1.attach(eBtitle,1,0,1,1);
        nbMain.append_page(gTab1,lTab1);
// ---- Notebook Tab 2 ------------------------------------------------
        lTab2.set_use_markup(true);
        Grid gTab2 = new Grid();
        gTab2.attach(lCtitle,0,0,1,1);
        lCtitle.get_style_context().add_class("redongreen");
        gTab2.attach(eCtitle,1,0,1,1);
        bColour.clicked.connect(()=>{changeColour(eCtitle,LIGHTGREY);});
        gTab2.attach(bColour,2,0,1,1);
        nbMain.append_page(gTab2,lTab2);
// ---- Notebook Tab 3 ----------------------------------------------------
        Grid gTab3 = new Grid();
        gTab3.attach(lDtitle,0,0,1,1);
        gTab3.attach(eDtitle,1,0,1,1);
        PAGENO = nbMain.append_page(gTab3,lTab3);
        Widget pw = nbMain.get_nth_page(PAGENO);
        pw.get_style_context().add_class("redongreen");
// ---- Pack Notebook into vBox on main window ------------------------
        Box vbMain = new Box(Orientation.VERTICAL,0);
        vbMain.pack_start(nbMain,true,true,0);
        this.add(vbMain);
        this.show_all();
        showDialog("Started");
    }
// ==== changeColour ==================================================
    private void changeColour(Entry entry,Gdk.Color colour) {
        entry.modify_bg(StateType.NORMAL,colour);
        entry.modify_base(StateType.NORMAL,PURPLE);
    }
// ==== onQuit ========================================================
    private void onQuit() {
        showDialog("Ending");
        exit(-1);
    }
// ==== showDialog ====================================================
    private void showDialog(string message) {
        Dialog dialog = new Dialog.with_buttons
            (APPNAME,this,DialogFlags.MODAL,
            Stock.OK,ResponseType.OK,null);
        var content = dialog.get_content_area();
// DURING COMPILATION:
// warning: assignment from incompatible pointer type
// [enabled by default]
        Label label = new Label(message);
        label.set_line_wrap(true);
        content.add(label);
        content.show_all();
        dialog.response.connect((id)=>{dialog.destroy();});
        dialog.run();
    }
// ==== switchPage ====================================================
    private void switchPage(uint pn) {
        switch (pn) {
        case 0:
            break;
        case 1:
            break;
        case 2:
            break;
        case 3:
            break;
        }
nbMain.get_tab_label(nbMain.get_nth_page(nbMain.get_current_page())).get_style_context().add_class("switch");
    }

}

public class CSStest: Gtk.Application {
    internal CSStest() {
        Object(application_id: "org.test.CSStest");
    }
    protected override void activate() {
        new CSStestWindow(this).show();
    }
}

extern void exit(int exit_code);

public int main(string[] args) {
    return new CSStest().run(args);
}

person b j norse    schedule 31.12.2013    source источник


Ответы (2)


Маршрут CSS кажется тем, которому хочет следовать Gtk3; и это, безусловно, самое привлекательное с точки зрения программиста. Но похоже, что в Вале это еще не полностью (или даже не очень) реализовано. Я прав в этом?

Нет. CSS полностью реализован в Vala, как и в Pango. Привязки Vala GTK+ генерируются из исходного кода GTK+ и являются достаточно полными. Я не знаю о каких-либо проблемах, но если определенные вещи отсутствуют или сломаны, сообщите об ошибке, и мы позаботимся об этом.

Что касается того, как это сделать, я не совсем эксперт в GTK+, но я считаю, что вы хотите использовать Gtk.CssProvider для загрузки вашего CSS. Затем примените его к элементу Gtk.StyleContext (который можно получить с помощью Gtk.Widget.get_style_context).

В любом случае, если вы можете найти пример того, как это сделать на другом языке (желательно C), обычно довольно легко перевести это на Vala, даже если вы не знаете другого языка.

person nemequ    schedule 31.12.2013

Ура! Спасибо, nemequ: как вы говорите, стили Gtk3 CSS полностью работают в Vala. Ваша уверенность заставила меня вернуться к первым принципам. В приведенном выше примере я прикрепил CssProvider к StyleContext верхнего окна в графическом интерфейсе, тогда как он должен был быть присоединен к объекту Gdk Screen. Далее следует измененный (и урезанный) код.

using Gtk;
using Posix;

public class CSStestWindow: ApplicationWindow {

    internal CSStestWindow(CSStest app) {
        Object(application:app,title:"CSStest");
        this.window_position = WindowPosition.CENTER;
        this.set_default_size(480,320);
        string style = """
            GtkButton {color:#ff00ea; font:Serif 12;}
            GtkButton:hover {background-color:#3085a9;}
            GtkLabel {background-color:#898989;}
            GtkEntry {background-color:green; color:red;}
        """;
        CssProvider provider = new CssProvider();
        try {
            provider.load_from_data(style,-1);
        } catch (GLib.Error e) {
            warning(e.message);
        }
        StyleContext context = new StyleContext();
        var screen = Gdk.Screen.get_default();
        context.add_provider_for_screen
            (screen,provider,STYLE_PROVIDER_PRIORITY_USER);
        Box vbMain = new Box(Orientation.VERTICAL,0);
        bTop.clicked.connect(onQuit);
        Button bTop = new Button.from_stock(Stock.QUIT);
        vbMain.pack_start(bTop,false,false,0);
        Label lTop = new Label("Here we are again");
        vbMain.pack_start(lTop,false,false,0);
        Entry eTop = new Entry();
        vbMain.pack_start(eTop,false,false,0);
        this.add(vbMain);
        this.show_all();
    }
// ==== onQuit ============================================================
    private void onQuit() {
        exit(-1);
    }

}

public class CSStest: Gtk.Application {
    internal CSStest() {
        Object(application_id: "org.test.CSStest");
    }
    protected override void activate() {
        new CSStestWindow(this).show();
    }
}

extern void exit(int exit_code);

public int main(string[] args) {
    return new CSStest().run(args);
}
person b j norse    schedule 01.01.2014