System: Linux, Language: C, Toolkit: GTK
I am working to create an emulator for an embedded machine's display. The display is a smart 800x400 pixel RGB display. The machine sends commands to control the display over a serial port in binary.
The first command sent will be to create the area for the text to be displayed:
createLabel LabelID X Y Width Height Rot Vjst Hjst Font R G B
Example commands from the embedded system:
CreateLabel 1 325 0 150 40 0 2 2 1 214 215 216
CreateLabel 2 565 0 220 40 0 2 1 1 214 215 216
CreateLabel 3 15 0 300 40 0 2 0 1 214 215 216
The numbers may look a little strange, but this is typical of what the embedded system transmits.
Label #3 is on the left side of the screen, with the horizontal justification set to left (
Hjst=0) and vertical justification set to the middle (Vjst=2) within the 40 pixel 'box' of the label.Label #2 is on the right side of the screen, with horizontal justification set to right (
Hjst=1) and vertically centered in the middle of the 40 pixel box (Vjst=2).Label #1 is centered on the screen around pixel 400 (
Hjst=2, calculated as325+(150/2)), and is also vertically centered in the 40 pixel box (Vjst=2).
I have tried gtk_label_set_max_width_chars() and gtk_widget_set_halign(), but neither seem to have any effect.
I can also set the font and color using gtk_label_set_markup(). The color seems to stick when I replace the text using gtk_label_set_text(), but the font reverts to the default when I use gtk_label_set_text() later on.
I also tried to draw a rectangle but could not get this to work. The code draws a png file to create the rectangle.
It seems like I am fighting the GTK libraries rather than working with them. To decode the color request from the embedded controller in binary to integer variables to convert them to hex encoding in a string to pass to the libraries seems a little obfuscated.
What I need to do is emulate the display not re-imagine it. This emulator will be used to create screen shots, otherwise I would use a tool like glade to create a new interface from scratch.
#include <gtk-3.0/gtk/gtk.h>
#include <gtk-3.0/gtk/gtkimage.h>
#define GTT_MAX_X 800
#define GTT_MAX_Y 480
#define FHIGHT 14 /* height of font */
#define VJST ((40-FHIGHT)/2)
#define APPLICATION_ID "org.gtk.example"
GtkWidget *label1;
GtkWidget *label2;
GtkWidget *label3;
GtkWidget *labelxx;
static void
print_new (GtkWidget *widget, gpointer data)
{
static int index;
static char *message[] = {"New text from embedded machine","more text","less","stuff"};
g_print ("Print_new() text from machine %d\n", index);
gtk_label_set_text (GTK_LABEL(labelxx), message[index]);
index = (++index) & 0x3;
}
static void
activate (GtkApplication *app, gpointer user_data)
{
GtkWidget *button_box;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *Rectangle;
GtkWidget *label;
GtkWidget *window;
GtkFixed *fixed;
GtkWidget *image;
// create the base window
window = gtk_application_window_new (app);
gtk_window_set_title(GTK_WINDOW (window), "Machine99"); // name of machine were attached to
gtk_window_set_default_size (GTK_WINDOW (window), GTT_MAX_X, GTT_MAX_Y); // size of GTT display
gtk_window_set_resizable(GTK_WINDOW(window), FALSE); // don't let it resize
fixed = (GtkFixed *)gtk_fixed_new();
/*
* load the background image
* code from machine: LoadBitmap 1 Images/en/Screens/39.bmp
* DisplayBitmap 1 0 0
*/
image = gtk_image_new_from_file ("data/Screens/39.bmp");
gtk_fixed_put(fixed, image, 0, 0);
/*
* code from machine: FillRectangle 700 85 140 45
* gtk_draw_rectangle(GdkDrawable *drawable, GdkGC *gc, gint filled, gint x, gint y, gint width, gint height);
*/
Rectangle = gtk_image_new_from_file ("data/Screens/textbox1.png");
gtk_fixed_put(fixed, Rectangle, 90, 85);
/*
* code from machine: CreateLabel 1 15 0 300 40 0 2 0 1 214 215 216
* CreateLabel 2 325 0 150 40 0 2 2 1 214 215 216
* CreateLabel 3 565 0 220 40 0 2 1 1 214 215 216
*/
label1 = gtk_label_new("Inital Text1");
gtk_label_set_markup(GTK_LABEL(label1),
"<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Left Text</b></span>");
gtk_label_set_max_width_chars((GtkLabel *)label1, 10);
g_print("label1 width = %d\n", gtk_label_get_max_width_chars((GtkLabel*)label1));
gtk_fixed_put(fixed, label1, 15,0+VJST);
label2 = gtk_label_new("Inital Text2");
gtk_label_set_markup(GTK_LABEL(label2),
"<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Center</b></span>");
gtk_label_set_max_width_chars((GtkLabel *)label2, 10);
g_print("label2 width = %d\n", gtk_label_get_max_width_chars((GtkLabel*)label2));
gtk_widget_set_halign (label2, GTK_ALIGN_CENTER);
gtk_fixed_put(fixed, label2, 325,0+VJST);
label3 = gtk_label_new("Inital Text3");
gtk_label_set_markup(GTK_LABEL(label3),
"<span font='Oxygen Mono' foreground='#D6D7D8' size='large'><b>Right Text</b></span>");
gtk_widget_set_halign (label3, GTK_ALIGN_END);
gtk_fixed_put(fixed, label3, 565,0+VJST);
labelxx = gtk_label_new("This is an example Label");
gtk_fixed_put(fixed, labelxx, 90+10,85+VJST);
gtk_label_set_markup(GTK_LABEL(labelxx),
"<span font='FONT NAME' foreground='#000000' size='large'>Text From Remote Here</span>");
gtk_container_add (GTK_CONTAINER (window), (GtkWidget *)fixed);
// need to add a task bar below the 'screen' with open connection quit any other controlls
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_fixed_put(fixed, button_box, 0, 483);
button1 = gtk_button_new_with_label ("Quit");
g_signal_connect_swapped(button1, "clicked", G_CALLBACK (gtk_widget_destroy), window);
button2 = gtk_button_new_with_label ("New Text");
g_signal_connect (button2, "clicked", G_CALLBACK (print_new), NULL);
gtk_container_add (GTK_CONTAINER (button_box), button2);
gtk_container_add (GTK_CONTAINER (button_box), button1);
gtk_widget_show_all (window);
}
int
main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new (APPLICATION_ID, G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
Here is the screen created by the code as posted.
The second image shows what happens when more text than will fit. it causes the entire screen to resize.
set_markup()with the embedded cairo markup wanted for the font, etc. to keep the font modifications.