如何在Vala中的Gtk3标签/条目小部件中为字体着色?

时间:2013-12-31 17:00:26

标签: gtk3 vala pango

我真的很高兴尝试使用Vala,并且设法解决了迄今为止遇到的大部分障碍。但是现在让我浪费时间的是Gtk3 Label和Entry小部件中字体的着色(和一般修改)。从理论上讲,有三种方法可以做到:

(1)使用PANGO标记。

(2)使用modify_base和modify_bg。

(3)使用CSS。

CSS路线似乎是Gtk3想要遵循的路线;从程序员的角度来看,它肯定是最具吸引力的。但似乎它还没有完全(甚至非常)在Vala中实现。我是对的吗?

所以现在可以接受modify_base和modify_bg;除了只有modify_bg似乎工作。在Vala中还没有实现modify_base吗?

PANGO是少数几个;但鉴于上述情况,我想知道它在Vala中的覆盖程度如何......

(下面的一些示例代码。)

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);
}

2 个答案:

答案 0 :(得分:1)

  

CSS路线似乎是Gtk3想要遵循的路线;从程序员的角度来看,它肯定是最具吸引力的。但似乎它还没有完全(甚至非常)在Vala中实现。我是对的吗?

没有。 Pala完全涵盖了CSS,Pango也是如此。 Vala GTK +绑定是从GTK +源代码生成的,非常完整。我不知道任何问题,但如果特定的东西丢失或损坏,请提交错误,我们会处理它。

至于如何实际操作,我不是GTK +的专家,但我相信你想要做的是使用Gtk.CssProvider加载你的CSS。然后将其应用于Gtk.StyleContext(您可以使用Gtk.Widget.get_style_context获得)。

在任何情况下,如果你能找到一个如何用另一种语言(最好是C)来做的例子,即使你不懂其他语言,通常也很容易将它翻译成Vala。

答案 1 :(得分:1)

yippee的!谢谢,nemequ:正如你所说,Gtk3 CSS样式在Vala中完全有效。你的保证让我回到了第一原则。在上面的示例中,我已将CssProvider附加到GUI顶部窗口的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);
}