Drawing with Cairo in GTK3 and CSS (Part 2)Attachment:
cairo2.gif [ 10.33 KiB | Viewed 5496 times ]
This is an extension of the first Cairo drawing example. Here I've made the drawing area scrollable; added two buttons and made the scrollbar wider. Wider scroll bars can be useful for users with vision disabilities or when creating a user interface for a computer with a small touchscreen such as a A13-OLinuXino or IGEP. (See references at bottom) I've used internal CSS for this example to keep it easier to follow. I've coloured the different areas brightly so you can tell what CSS goes with what area. I've also listed all the pointers to the widgets individually in a hierarchy to help you better understand the packing arrangement.
CODE NOTES:Everything in the window gets packed into a
GtkGrid which is one column wide by 2 rows tall. You should avoid using
GtkTable. It's been phased out since version 3.4 and shouldn't used in newly-written code.
http://developer.gnome.org/gtk3/stable/GtkTable.htmlThere's official GTK documentation to help you make the switch from other container widgets to
GtkGrid.
http://developer.gnome.org/gtk3/stable/gtk-migrating-GtkGrid.htmlThe upper row in the grid contains the
GtkDrawingArea which is packed into a
GtkViewPort. The
GtkViewPort is packed into a
GtkScrolledWindow. Then the
GtkScrolledWindow is packed into the upper row (row 0) of the
GtkGrid.
The bottom row of the grid contains the two buttons. The buttons are first packed into a
GtkButtonBox using
gtk_button_box_new with it's orientation set to
GTK_ORIENTATION_HORIZONTAL.
gtk_hbutton_box_new along with
gtk_vbutton_box_new have been phased out since gtk version 3.2 and should not be used in newly-written code.
http://developer.gnome.org/gtk3/stable/GtkHButtonBox.htmlThe
GtkButtonBox is packed into the bottom row (row 1) of the
GtkGrid. Added space above and below the
GtkButtonBox is provided by the following functions:
gtk_widget_set_margin_bottom() gtk_widget_set_margin_top()Quote:
GtkGrid doesn't have any custom child properties to specify per-child padding; instead you can use the "margin" property. You can also set different padding on each side with the "margin-left", "margin-right", "margin-top" and "margin-bottom" properties.
http://developer.gnome.org/gtk3/stable/ch28s03.htmlFinally the
GtkGrid with all of the other widgets inside it, is packed into the
GtkWindow.
Code:
/* COMPILE USING: gcc -Wextra -o cairo2 `pkg-config --cflags --libs gtk+-3.0` cairo2.c
*/
#include <gtk/gtk.h>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 480
static gboolean
draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data)
{
cr = gdk_cairo_create ( gtk_widget_get_window (widget));
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
/* draw rectangle */
cairo_set_source_rgb (cr, 0.42, 0.65, 0.80);
cairo_set_line_width (cr,6);
cairo_rectangle (cr, 3, 3, 100, 100);
cairo_stroke (cr);
/* draw circle */
cairo_set_source_rgb (cr, 0.17, 0.63, 0.12);
cairo_set_line_width (cr,2);
cairo_arc (cr, 150, 210, 20, 0, 2*G_PI);
cairo_stroke (cr);
/* draw horizontal line */
cairo_set_source_rgb (cr, 0.77, 0.16, 0.13);
cairo_set_line_width (cr, 6);
cairo_move_to (cr, 80,160);
cairo_line_to (cr, 200, 160);
cairo_stroke (cr);
cairo_destroy (cr);
return TRUE;
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *grid;
GtkWidget *scrollwin;
GtkWidget *view;
GtkWidget *da;
GtkWidget *hbtnbox;
GtkWidget *btn_back;
GtkWidget *btn_home;
/*-- CSS ------------------*/
GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
/*---------------------------*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window),"cairo2");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit),
NULL);
gtk_widget_set_size_request (window,
WINDOW_WIDTH,
WINDOW_HEIGHT);
gtk_window_set_has_resize_grip (GTK_WINDOW(window), FALSE);
da = gtk_drawing_area_new();
gtk_widget_set_size_request (da, 1000, 400);
g_signal_connect (da,
"draw",
G_CALLBACK(draw_cb),
NULL);
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_hexpand (GTK_WIDGET(scrollwin), TRUE);
gtk_widget_set_vexpand (GTK_WIDGET(scrollwin), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrollwin),
GTK_POLICY_ALWAYS,
GTK_POLICY_NEVER);
view = gtk_viewport_new (NULL,NULL);
hbtnbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout ( GTK_BUTTON_BOX(hbtnbox), GTK_BUTTONBOX_CENTER );
gtk_box_set_spacing (GTK_BOX(hbtnbox),60);
gtk_widget_set_margin_bottom (GTK_WIDGET(hbtnbox), 20);
gtk_widget_set_margin_top (GTK_WIDGET(hbtnbox), 20);
btn_back = gtk_button_new_with_label ("Back");
btn_home = gtk_button_new_with_label ("Home");
gtk_widget_set_size_request (GTK_WIDGET(btn_back), 100, 45);
gtk_widget_set_size_request (GTK_WIDGET(btn_home), 100, 45);
gtk_box_pack_start (GTK_BOX(hbtnbox), btn_back, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX(hbtnbox), btn_home, FALSE, FALSE, 0);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrollwin), da);
grid = gtk_grid_new ();
gtk_grid_attach (GTK_GRID(grid),
GTK_WIDGET(scrollwin),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID(grid),
GTK_WIDGET(hbtnbox),
0, 1, 1, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
/*------------- CSS --------------------------------------------------------------------------------------------------*/
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen,
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider),
" GtkWindow {\n"
" background-color: black;\n"
"}\n"
" GtkRange {\n"
" -GtkRange-arrow-displacement-x: 8;\n"
" -GtkRange-arrow-displacement-y: 2;\n"
" -GtkRange-arrow-scaling: 1.0;\n"
" -GtkRange-slider-width: 40;\n"
" -GtkRange-stepper-size: 40;\n"
" -GtkRange-stepper-spacing: 0;\n"
" -GtkRange-trough-border: 1;\n"
" -GtkRange-trough-under-steppers: 0;\n"
"}\n"
" GtkRange.slider {\n"
" background-color: blue;\n"
"}\n"
" GtkRange.button {\n"
" background-color: green;\n"
" color: red;\n"
"}\n"
" GtkRange.trough {\n"
" background-color: burlywood;\n"
"}\n"
" GtkButton {\n"
" -GtkWidget-focus-line-width: 0;\n"
" color: black;\n"
" border-radius: 10;\n"
" border-width: 1;\n"
" background-color: dodgerblue;\n"
" font-size: 18;\n"
"}\n", -1, NULL);
g_object_unref (provider);
/*----------------------------------------------------------------------------------------------------------------------*/
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
References:ARM CORTEX-A8, 1GHZ microcontroller board:
https://www.olimex.com/Products/OLinuXino/A13/ A13-OLinuXino: 512 MB RAM, 45 euros and 55 euros for WIFI model. "$58 and $72"
A13-OLinuXino-MICRO: 256 MB RAM, 35 euros "$46"
7'' (480x800) resistive touchscreen with backlight, (Innolux AT070TN9X) 55 euros available at the link above.
USA sellers:
http://www.mouser.com/ProductDetail/Olimex-Ltd/A13-OLINUXINO-WIFI/?qs=sGAEpiMZZMtfUM4gNaCsXt/8G7WT37Q7http://www.digikey.com/product-detail/en/A13-OLINUXINO-WIFI/1188-1090-ND/3601083http://microcontrollershop.com/product_info.php?cPath=154_170_556&products_id=5314--------------------------------------------------------------------------------------------------------------
IGEP COM ELECTRON microcontroller board:
ARM CORTEX A8, 720Mhz or 1 Ghz
79.00 euros
Features:
Industrial grade (-40 ... +85C Deg)Size: 18 x 68,5 mm
Integrated antenna and connector for external antenna
1 x USB 2.0 OTG (USB 2.0)
MicroSD card reader
Expansion: USB, DDS, Camera signals, I/O, uart, SPI, McBSP, I2C, keypad ...
Expansion: GPMC lines.
2 x 70 pin Expansion Connectors
2 x 27 pin Expansion Connectors
USB Powered, standalone mode
http://shop.isee.biz/buy-online/processor-boards/igeptm-com-electron.htmlIGEP NEW YORK expansion module:
29.00 euros
Features:
Industrial grade (-40 ... +85C Deg)Size: 68 x 26 mm
Power your module from +5Vdc source
3 Axis Accelerometer
Up to 44 GPIO signals
1 x SPI
2 x UART
1 x I2C
4 PWM
DSS Video interface
Fully Software supported in the processor BSP
http://shop.isee.biz/igeptm-new-york.html7 inch touch screen for IGEP COM ELECTRON (110 euros)
http://shop.isee.biz/buy-online/accesories/tft-24-bits-seiko-7.html10-inch, 1024 x 600, capacitive
http://www.chalk-elec.com/?page_id=1280#ecwid:category=0&mode=product&product=7703686