X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=ui.c;h=70a7cfee38a88b38918464d22882b96555f2189c;hb=966b2d03909c03910a1d0494b1a289f44dc8a9cd;hp=bb30df7b2b98797516c10147f949eb2efb1e7dc9;hpb=8bd00384b1f1e9ac7d4a888d53aab0bfce6bd5f8;p=speedometer diff --git a/ui.c b/ui.c index bb30df7..70a7cfe 100644 --- a/ui.c +++ b/ui.c @@ -17,13 +17,39 @@ ****/ #include +#include +#include +#include +#include #include "ui.h" #include "callbacks.h" +#define GCONF_KEY "/apps/Maemo/speedometer/disclaimer" + +/* This is used when converting to other units + * number represents a multiplier which is used + * when converting the base unit to other units. + * Base unit is m/s thus the first multiplier is + * one. Units are in following order: + * + * m/s, km/h, mph, f/s, knot + */ +gdouble conversion[] = { 1, 3.6, 2.237, 3.281, 1.944 }; +guint unit = 1; +#define UNIT_COUNT 4 +// TODO: wrap this mess up somewhere +// TODO: knot graphics are missing + +static GdkPixbuf* big_graphics[14]; +static GdkPixbuf* small_graphics[14]; +static GtkWidget* digits[5]; +static GtkWidget* unit_graphic; + #define IMAGE_PATH "/usr/share/speedometer/%d.png" static void set_widget_bg_black(GtkWidget* widget) { + g_assert(widget); GdkColor black; black.red = 0x0000; black.blue = 0x0000; @@ -31,54 +57,90 @@ static void set_widget_bg_black(GtkWidget* widget) { gtk_widget_modify_bg(GTK_WIDGET(widget), GTK_STATE_NORMAL, &black); } -void load_images(AppData *appdata) { - g_print("Loading images\n"); - int i = 0; - while(i < 10) { - char* path = malloc(30); + +/* Loads all the graphics from the disk and + * scales the images down to be used in several + * places. Might block for few seconds depending + * on the load. + */ +void load_graphics() { + g_print("Loading and scaling images\n"); + guint i = 0; + + /* This loop will load all the images from the disk + * and store the pixbufs to the array. Pixbufs are + * correct size to be used in the big digits. + */ + while(i < 14) { + char* path = g_malloc(30); g_sprintf(path, IMAGE_PATH, i); - appdata->image_array[i] = gtk_image_new_from_file(path); g_print(path); g_print("\n"); - free(path); + GError* error = NULL; + big_graphics[i] = gdk_pixbuf_new_from_file(path, &error); + if(error) { + g_print("Error loading graphics: %s\n", error->message); + g_error_free(error); + error = NULL; + } + g_free(path); + + small_graphics[i] = gdk_pixbuf_scale_simple( + big_graphics[i], + 150, + 150, + GDK_INTERP_BILINEAR); + i++; } + g_print("Done\n"); } -void reset_speed(AppData* appdata) { - - GdkPixbuf* zero = gtk_image_get_pixbuf(appdata->image_array[0]); - - appdata->speed_array[0] = gtk_image_new_from_pixbuf(zero); - appdata->speed_array[1] = gtk_image_new_from_pixbuf(zero); - appdata->speed_array[2] = gtk_image_new_from_pixbuf(zero); +void set_digits_to_zero() { + digits[0] = gtk_image_new_from_pixbuf(big_graphics[0]); + digits[1] = gtk_image_new_from_pixbuf(big_graphics[0]); + digits[2] = gtk_image_new_from_pixbuf(big_graphics[0]); + digits[3] = gtk_image_new_from_pixbuf(small_graphics[0]); + digits[4] = gtk_image_new_from_pixbuf(small_graphics[0]); + // TODO: load this from GConf + unit_graphic = gtk_image_new_from_pixbuf(small_graphics[11]); } -guint randomize(AppData* appdata) { +static void set_nth_digit(guint n, guint value) { + g_assert(value < 10); + g_assert(n < 5); - gint32 n = g_random_int_range(0, 3); - GtkImage* image = appdata->speed_array[n]; - - gint32 m = g_random_int_range(0, 10); - GdkPixbuf* buf = gtk_image_get_pixbuf(appdata->image_array[m]); - - g_print("Setting number %d to %d.. ", n+1, m); - - gtk_image_set_from_pixbuf(image, buf); - gtk_widget_queue_draw(appdata->speed_array[n]); + if(n < 3) { + GtkWidget* image = digits[n]; + GdkPixbuf* buf = big_graphics[value]; + gtk_image_set_from_pixbuf(GTK_IMAGE(image), buf); + } + else { + GtkWidget* image = digits[n]; + GdkPixbuf* buf = small_graphics[value]; + gtk_image_set_from_pixbuf(GTK_IMAGE(image), buf); + } +} - return TRUE; +static void repaint_all_digits() { + gtk_widget_queue_draw(GTK_WIDGET(digits[0])); + gtk_widget_queue_draw(GTK_WIDGET(digits[1])); + gtk_widget_queue_draw(GTK_WIDGET(digits[2])); } void create_ui(AppData* appdata) { + g_assert(appdata); GtkWidget *hbox; + GtkWidget *bhbox; GtkWidget *vbox; vbox = gtk_vbox_new(FALSE, 0); hbox = gtk_hbox_new(TRUE, 0); + bhbox = gtk_hbox_new(TRUE, 0); GtkWidget* top_e = gtk_event_box_new(); + GtkWidget* middle_e = gtk_event_box_new(); GtkWidget* bottom_e = gtk_event_box_new(); g_signal_connect(G_OBJECT(top_e), @@ -86,6 +148,11 @@ void create_ui(AppData* appdata) { G_CALLBACK(top_event_box_button_press), appdata); + g_signal_connect(G_OBJECT(middle_e), + "button_press_event", + G_CALLBACK(middle_event_box_button_press), + appdata); + g_signal_connect(G_OBJECT(bottom_e), "button_press_event", G_CALLBACK(bottom_event_box_button_press), @@ -96,27 +163,124 @@ void create_ui(AppData* appdata) { G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(G_OBJECT(appdata->window), - "key_press_event", - G_CALLBACK(key_press_cb), - appdata->window); - - // add three digits to the hbox - gtk_box_pack_start(hbox, appdata->speed_array[0], FALSE, FALSE, 0); - gtk_box_pack_start(hbox, appdata->speed_array[1], FALSE, FALSE, 0); - gtk_box_pack_start(hbox, appdata->speed_array[2], FALSE, FALSE, 0); - - gtk_box_pack_start_defaults(vbox, top_e); // add event box on top - gtk_box_pack_start_defaults(vbox, hbox); // numbers to the middle - gtk_box_pack_start_defaults(vbox, bottom_e); // add event box on bottom - + g_signal_connect(G_OBJECT(appdata->window), + "key_press_event", + G_CALLBACK(key_press_cb), + appdata->window); + + // add three big digits to the hbox + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(digits[0]), FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(digits[1]), FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(digits[2]), FALSE, FALSE, 0); + + // add small digits to another hbox + gtk_box_pack_start(GTK_BOX(bhbox), GTK_WIDGET(unit_graphic), FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(bhbox), GTK_WIDGET(digits[3]), FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(bhbox), GTK_WIDGET(digits[4]), FALSE, FALSE, 0); + + // add hboxes to the event boxes + gtk_container_add(GTK_CONTAINER(middle_e), hbox); + gtk_container_add(GTK_CONTAINER(bottom_e), bhbox); + + // add event boxes to the vbox + gtk_box_pack_start_defaults(GTK_BOX(vbox), top_e); + gtk_box_pack_start_defaults(GTK_BOX(vbox), middle_e); + gtk_box_pack_start_defaults(GTK_BOX(vbox), bottom_e); + + // finally add the vertical box with all the children to the window gtk_container_add(GTK_CONTAINER(appdata->window), GTK_WIDGET(vbox)); - // set backgrounds black - set_widget_bg_black(appdata->window); + set_widget_bg_black(GTK_WIDGET(appdata->window)); set_widget_bg_black(bottom_e); set_widget_bg_black(top_e); + set_widget_bg_black(middle_e); + + gtk_window_fullscreen(GTK_WINDOW(appdata->window)); + gtk_widget_show_all(GTK_WIDGET(appdata->window)); +} + +void change_unit() { + unit++; + + if(unit >= UNIT_COUNT) { + unit = 0; + } + g_print("Unit used in conversion: %f\n", conversion[unit]); + + GdkPixbuf* buf = small_graphics[10 + unit]; + gtk_image_set_from_pixbuf(GTK_IMAGE(unit_graphic), buf); +} + +void interpret_and_set_speed(gdouble speed) { + g_assert(!isnan(speed)); + + /* speed is in m/s so let's convert + * it to the unit that we are using + */ + speed *= conversion[unit]; + + /* Convert float to a 6 digits (including dot) wide + * string with leading zeros. After conversion + * the speed looks like: + * + * 009.20 (9,20 km/h) or + * 010.90 (10,90 km/h) or + * 120.10 (120,10 km/h) + * + * Now, regardless of speed we know the position + * of the digits and can access the array directly. + */ + gchar* charspeed = g_malloc(10); // alloc + g_sprintf(charspeed, "%0*.2f", 6, speed); + + g_print("Speed is %s km/h\n", charspeed); + + // these three lines will set the big digits + set_nth_digit(0, g_ascii_digit_value(charspeed[0])); + set_nth_digit(1, g_ascii_digit_value(charspeed[1])); + set_nth_digit(2, g_ascii_digit_value(charspeed[2])); + + // these two lines will set the small digits + set_nth_digit(3, g_ascii_digit_value(charspeed[4])); + set_nth_digit(4, g_ascii_digit_value(charspeed[5])); + + repaint_all_digits(); + + g_free(charspeed); +} + +static void show_dialog() { + GtkWidget *dialog = gtk_message_dialog_new( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "This program is licensed under GNU General Public License, " + "which means (among other things) that you don't have to pay " + "a dime for it. " + "If you think, however, that this software is worth it, you " + "can always drop me a postcard.\n\n" + "Wellu Mäkinen\n" + "PO BOX\n" + "33580 Tampere\n" + "FINLAND"); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +void show_cardware_dialog() { + GConfClient* client = gconf_client_get_default(); + g_assert(GCONF_IS_CLIENT(client)); + GConfValue* gcvalue = NULL; + gcvalue = gconf_client_get_without_default(client, GCONF_KEY, NULL); + + if(gcvalue == NULL) { + g_print("GConf key not found so show dialog.\n"); + show_dialog(); + gconf_client_set_bool(client, GCONF_KEY, TRUE, NULL); + } + g_object_unref(client); }