I'm really enjoying experimenting with Vala, and have managed to solve most of the snags I've encountered so far. But the one that's causing me a bit of time-wasting right now is the colouring (and general modification) of fonts in Gtk3 Label and Entry widgets. In theory there are three ways of doing it:
(1) Using PANGO mark-up.
(2) Using modify_base and modify_bg.
(3) Using CSS.
The CSS route seems to be the one that Gtk3 is wanting to follow; and it's certainly the most appealing from a programmer's point of view. But it seems that it's not yet fully (or even very much) implemented in Vala. Am I right about this?
So modify_base and modify_bg are acceptable for now; except that only modify_bg seems to work. Is modify_base not yet implemented in Vala?
PANGO is a more of a handful; but in view of the above, I'd like to know how well covered it is in Vala...
(Some sample code below.)
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);
}
Yippee! Thanks, nemequ: as you say, Gtk3 CSS styling works fully in Vala. Your assurance drove me back to first principles. In the example above, I had attached the CssProvider to the StyleContext of the top window in the GUI, whereas it should have been attached to the Gdk Screen object. Amended (and stripped-down) code follows.