[cairo-commit] roadster/src glyph.c, 1.8, 1.9 glyph.h, 1.5, 1.6 gui.c, 1.12, 1.13 locationset.c, 1.15, 1.16 locationset.h, 1.9, 1.10 main.c, 1.26, 1.27 mainwindow.c, 1.43, 1.44 mainwindow.h, 1.11, 1.12 map.c, 1.47, 1.48 map.h, 1.23, 1.24 map_draw_cairo.c, 1.23, 1.24 map_draw_gdk.c, 1.20, 1.21 map_style.c, 1.2, 1.3 map_style.h, 1.2, 1.3 road.h, 1.3, 1.4 searchwindow.c, 1.24, 1.25 util.c, 1.12, 1.13 util.h, 1.12, 1.13

Ian McIntosh commit at pdx.freedesktop.org
Thu Sep 29 22:09:53 PDT 2005


Committed by: ian

Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv14881/src

Modified Files:
	glyph.c glyph.h gui.c locationset.c locationset.h main.c 
	mainwindow.c mainwindow.h map.c map.h map_draw_cairo.c 
	map_draw_gdk.c map_style.c map_style.h road.h searchwindow.c 
	util.c util.h 
Log Message:
	* src/map_style.c: Removed "constants"-- found out that XML already has this feature!
	* src/glyph.c: Don't load the same image twice.  Allow loading at image's native resolution.
	* src/map_draw_gdk.c: Can now fill polygons with a tiled image.  Beginning support for moving POI to the layers.XML file.
	* src/util.c: Add code for GtkEntry "hints".  These are messages shown when there is nothing in the entry.  May be used for search box.


Index: glyph.c
===================================================================
RCS file: /cvs/cairo/roadster/src/glyph.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- glyph.c	26 Sep 2005 13:57:13 -0000	1.8
+++ glyph.c	30 Sep 2005 05:09:51 -0000	1.9
@@ -28,10 +28,12 @@
 
 struct {
 	GPtrArray* pGlyphArray;	// to store all glyphs we hand out
-} g_Glyph;
+	GtkWidget* pTargetWidget;
+} g_Glyph = {0};
 
-void glyph_init(void)
+void glyph_init(GtkWidget* pTargetWidget)
 {
+	g_Glyph.pTargetWidget = pTargetWidget;
 	g_Glyph.pGlyphArray = g_ptr_array_new();
 }
 
@@ -75,6 +77,21 @@
 	return TRUE;
 }
 
+gboolean glyph_find_by_attributes(const gchar* pszName, gint nMaxWidth, gint nMaxHeight, glyph_t** ppReturnGlyph)
+{
+	gint i;
+	for(i=0 ; i<g_Glyph.pGlyphArray->len ; i++) {
+		glyph_t* pGlyph = g_ptr_array_index(g_Glyph.pGlyphArray, i);
+		if(pGlyph->nMaxWidth == nMaxWidth && pGlyph->nMaxHeight == nMaxHeight && strcmp(pGlyph->pszName, pszName) == 0) {
+			if(ppReturnGlyph) {
+				*ppReturnGlyph = pGlyph;
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
 void _glyph_load_at_size_into_struct(glyph_t* pNewGlyph, const gchar* pszName, gint nMaxWidth, gint nMaxHeight)
 {
 	// pszName is an icon name without extension or path
@@ -88,15 +105,30 @@
 	gint iExtension;
 	for(iExtension = 0 ; iExtension < G_N_ELEMENTS(apszExtensions) ; iExtension++) {
 		gchar* pszFilePath = g_strdup_printf("%s%s.%s", pszPath, pszName, apszExtensions[iExtension]);
-		pNewPixbuf = gdk_pixbuf_new_from_file_at_scale(pszFilePath, nMaxWidth, nMaxHeight, TRUE, NULL);	// NOTE: scales image to fit in this size
+		if(nMaxWidth == -1) {
+			pNewPixbuf = gdk_pixbuf_new_from_file(pszFilePath, NULL);
+		}
+		else {
+			pNewPixbuf = gdk_pixbuf_new_from_file_at_scale(pszFilePath, nMaxWidth, nMaxHeight, TRUE, NULL);	// NOTE: scales image to fit in this size
+		}
 		g_free(pszFilePath);
 
-		if(pNewPixbuf != NULL) break;	// got it!
+		if(pNewPixbuf != NULL) {
+			g_print("loaded image '%s' as %s with size (%d,%d)\n", pszName, apszExtensions[iExtension], gdk_pixbuf_get_width(pNewPixbuf), gdk_pixbuf_get_height(pNewPixbuf));
+			break;	// got it!
+		}
 	}
 
 	// Create a fake pixbuf if not found
 	if(pNewPixbuf == NULL) {
-		pNewPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nMaxWidth, nMaxHeight);
+		g_print("unabled to load image '%s'\n", pszName);
+
+		if(nMaxWidth == -1) {
+			pNewPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 16, 16);
+		}
+		else {
+			pNewPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nMaxWidth, nMaxHeight);
+		}
 		gdk_pixbuf_fill(pNewPixbuf, 0xFF000080);
 	}
 	pNewGlyph->pPixbuf = pNewPixbuf;
@@ -104,12 +136,52 @@
 	pNewGlyph->nHeight = gdk_pixbuf_get_height(pNewPixbuf);
 }
 
+// Load at image's default size
+glyph_t* glyph_load(const gchar* pszName)
+{
+	g_assert(g_Glyph.pTargetWidget != NULL);
+	g_assert(g_Glyph.pGlyphArray != NULL);
+	g_assert(pszName != NULL);
+
+	glyph_t* pExistingGlyph = NULL;
+	if(glyph_find_by_attributes(pszName, -1, -1, &pExistingGlyph)) {
+		g_print("Found in cache '%s'\n", pszName);
+		pExistingGlyph->nReferenceCount++;
+		return pExistingGlyph;
+	}
+
+	// NOTE: We always return something!
+	glyph_t* pNewGlyph = g_new0(glyph_t, 1);
+	pNewGlyph->nReferenceCount = 1;
+
+	pNewGlyph->pszName = g_strdup(pszName);
+	pNewGlyph->nMaxWidth = -1;
+	pNewGlyph->nMaxHeight = -1;
+
+	// call internal function to fill the struct
+	_glyph_load_at_size_into_struct(pNewGlyph, pszName, -1, -1);
+
+	g_ptr_array_add(g_Glyph.pGlyphArray, pNewGlyph);
+
+	return pNewGlyph;
+}
+
 glyph_t* glyph_load_at_size(const gchar* pszName, gint nMaxWidth, gint nMaxHeight)
 {
-	g_print("glyph.c: loading %s\n", pszName);
+	g_assert(g_Glyph.pTargetWidget != NULL);
+	g_assert(g_Glyph.pGlyphArray != NULL);
+	g_assert(pszName != NULL);
+
+	glyph_t* pExistingGlyph = NULL;
+	if(glyph_find_by_attributes(pszName, nMaxWidth, nMaxHeight, &pExistingGlyph)) {
+		g_print("Found in cache '%s'\n", pszName);
+		pExistingGlyph->nReferenceCount++;
+		return pExistingGlyph;
+	}
 
 	// NOTE: We always return something!
 	glyph_t* pNewGlyph = g_new0(glyph_t, 1);
+	pNewGlyph->nReferenceCount = 1;
 
 	pNewGlyph->pszName = g_strdup(pszName);
 	pNewGlyph->nMaxWidth = nMaxWidth;
@@ -123,6 +195,9 @@
 	return pNewGlyph;
 }
 
+//
+//
+//
 GdkPixbuf* glyph_get_pixbuf(const glyph_t* pGlyph)
 {
 	g_assert(pGlyph != NULL);
@@ -131,13 +206,28 @@
 	return pGlyph->pPixbuf;
 }
 
+GdkPixmap* glyph_get_pixmap(glyph_t* pGlyph)
+{
+	g_assert(pGlyph != NULL);
+	
+	if(pGlyph->pPixmap == NULL) {
+		GdkGC* pGC = g_Glyph.pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(g_Glyph.pTargetWidget)];
+        pGlyph->pPixmap = gdk_pixmap_new(g_Glyph.pTargetWidget->window, pGlyph->nWidth, pGlyph->nHeight, -1);	// -1 is bpp
+		gdk_draw_pixbuf(pGlyph->pPixmap, pGC, pGlyph->pPixbuf,0,0,0,0,-1,-1,
+						GDK_RGB_DITHER_NONE,0,0);           // no dithering
+	}
+	g_assert(pGlyph->pPixmap != NULL);
+
+	return pGlyph->pPixmap;
+}
+
 void glyph_draw_centered(glyph_t* pGlyph, GdkDrawable* pTargetDrawable, GdkGC* pGC, gdouble fX, gdouble fY)
 {
 	gdk_draw_pixbuf(pTargetDrawable,
 					pGC,
 					pGlyph->pPixbuf,
-					0,0,                        		// src
-					(gint)(fX - (pGlyph->nWidth/2)), (gint)(fY - (pGlyph->nHeight/2)),                 // x/y to draw to
+					0,0, // src
+					(gint)(fX - ((gdouble)(pGlyph->nWidth)/2.0)), (gint)(fY - ((gdouble)(pGlyph->nHeight)/2.0)),                 // x/y to draw to
 					pGlyph->nWidth, pGlyph->nHeight,    // width/height
 					GDK_RGB_DITHER_NONE,0,0);   		// no dithering
 }

Index: glyph.h
===================================================================
RCS file: /cvs/cairo/roadster/src/glyph.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- glyph.h	26 Sep 2005 13:57:13 -0000	1.5
+++ glyph.h	30 Sep 2005 05:09:51 -0000	1.6
@@ -28,17 +28,20 @@
 #include <cairo.h>
 
 typedef struct {
-	GdkPixbuf* pPixbuf;
+	GdkPixbuf* pPixbuf;		// pixbuf is just a decoded image
+	GdkPixmap* pPixmap;		// pixmap is converted to screen color depth, etc.
 	gint nWidth;
 	gint nHeight;
 	gint nMaxWidth;
 	gint nMaxHeight;
 	gchar* pszName;
+	gint nReferenceCount;
 } glyph_t;
 
-void glyph_init(void);
+void glyph_init(GtkWidget* pTargetWidget);
 glyph_t* glyph_load_at_size(const gchar* pszName, gint nMaxWidth, gint nMaxHeight);
 GdkPixbuf* glyph_get_pixbuf(const glyph_t* pGlyph);
+GdkPixmap* glyph_get_pixmap(glyph_t* pGlyph);
 //void glyph_draw_centered(cairo_t* pCairo, gint nGlyphHandle, gdouble fX, gdouble fY);
 void glyph_draw_centered(glyph_t* pGlyph, GdkDrawable* pTargetDrawable, GdkGC* pGC, gdouble fX, gdouble fY);
 void glyph_deinit(void);

Index: gui.c
===================================================================
RCS file: /cvs/cairo/roadster/src/gui.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- gui.c	24 Sep 2005 05:25:25 -0000	1.12
+++ gui.c	30 Sep 2005 05:09:51 -0000	1.13
@@ -44,12 +44,18 @@
 	glade_xml_signal_autoconnect(pGladeXML);
 
 	// init all windows/dialogs
-	mainwindow_init(pGladeXML);	
+	g_print("- initializing mainwindow\n");
+	mainwindow_init(pGladeXML);
+	g_print("- initializing searchwindow\n");
 	searchwindow_init(pGladeXML);
+	g_print("- initializing gotowindow\n");
 	gotowindow_init(pGladeXML);
+	g_print("- initializing importwindow\n");
 	importwindow_init(pGladeXML);
 	//datasetwindow_init(pGladeXML);
+	g_print("- initializing welcomewindow\n");
 	welcomewindow_init(pGladeXML);
+	g_print("- initializing locationeditwindow\n");
 	locationeditwindow_init(pGladeXML);
 }
 

Index: locationset.c
===================================================================
RCS file: /cvs/cairo/roadster/src/locationset.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- locationset.c	26 Sep 2005 13:57:13 -0000	1.15
+++ locationset.c	30 Sep 2005 05:09:51 -0000	1.16
@@ -106,7 +106,8 @@
 			pNewLocationSet->pszName = g_strdup(aRow[1]);
 			pNewLocationSet->pszIconName = g_strdup(aRow[2]);
 			pNewLocationSet->pGlyph = glyph_load_at_size(pNewLocationSet->pszIconName, SEARCHWINDOW_SEARCH_RESULT_GLYPH_WIDTH, SEARCHWINDOW_SEARCH_RESULT_GLYPH_HEIGHT);
-			pNewLocationSet->pMapGlyph = glyph_load_at_size(pNewLocationSet->pszIconName, 16, 16);
+			pNewLocationSet->pMapGlyph = glyph_load_at_size(pNewLocationSet->pszIconName, 24, 24);
+			pNewLocationSet->pMapGlyphSmall = glyph_load_at_size(pNewLocationSet->pszIconName, 6, 6);
 			pNewLocationSet->nLocationCount = atoi(aRow[3]);
 
 			// Add the new set to both data structures

Index: locationset.h
===================================================================
RCS file: /cvs/cairo/roadster/src/locationset.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- locationset.h	26 Sep 2005 13:57:13 -0000	1.9
+++ locationset.h	30 Sep 2005 05:09:51 -0000	1.10
@@ -45,6 +45,8 @@
 //	locationsetstyle_t Style;
 	glyph_t* pGlyph;
 	glyph_t* pMapGlyph;
+	glyph_t* pMapGlyphSmall;
+
 } locationset_t;
 
 void locationset_init(void);

Index: main.c
===================================================================
RCS file: /cvs/cairo/roadster/src/main.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- main.c	26 Sep 2005 13:57:13 -0000	1.26
+++ main.c	30 Sep 2005 05:09:51 -0000	1.27
@@ -95,8 +95,8 @@
 
 	// New POI
 	mappoint_t pt;
-	pt.fLatitude = 42.37382;
-	pt.fLongitude = -71.10054;
+	pt.fLatitude = 42.37391;
+	pt.fLongitude = -71.10045;
 	nNewLocationID = 0;
 	location_insert(nNewLocationSetID, &pt, &nNewLocationID);
 	location_insert_attribute(nNewLocationID, LOCATION_ATTRIBUTE_ID_NAME, "1369 Coffee House", NULL);
@@ -104,8 +104,8 @@
 	location_insert_attribute(nNewLocationID, nAttributeIDReview, "1369 Coffee House (specifically, the one on Mass Ave) has a special place in my heart; it's sort of my office away from the office, or my vacation home away from my tiny Central Square rented home. It's cozy. It's hip.", NULL);
 
 	// New POI
-	pt.fLatitude = 42.36650;
-	pt.fLongitude = -71.10554;
+	pt.fLatitude = 42.36654;
+	pt.fLongitude = -71.10541;
 	nNewLocationID = 0;
 	location_insert(nNewLocationSetID, &pt, &nNewLocationID);
 	location_insert_attribute(nNewLocationID, LOCATION_ATTRIBUTE_ID_NAME, "1369 Coffee House", NULL);
@@ -151,20 +151,21 @@
 	track_init();
 	g_print("initializing map styles\n");
 	map_style_init();
-	g_print("initializing glyphs\n");
-	glyph_init();
 	g_print("initializing map\n");
 	map_init();
 
-	g_print("initializing search\n");
-	search_init();
-
 	g_print("initializing scenemanager\n");
 	scenemanager_init();
 
 	g_print("initializing gpsclient\n");
 	gpsclient_init();
 
+	g_print("initializing animator\n");
+	animator_init();
+
+	//
+	// Database
+	//
 	g_print("initializing db\n");
 	db_init();
 
@@ -174,23 +175,25 @@
 	g_print("creating database tables\n");
 	db_create_tables();
 
-	g_print("initializing locationsets\n");
-	locationset_init();
-
-	g_print("initializing locations\n");
-	location_init();
-
-	g_print("initializing animator\n");
-	animator_init();
-
 	main_debug_insert_test_data();
 
+	//
 	// Load location sets from DB.  This is "coffee shops", "ATMs", etc.
-	locationset_load_locationsets();
+	//
+	g_print("initializing locationsets\n");
+	locationset_init();
 
 	g_print("initializing gui\n");
 	gui_init();
 
+	locationset_load_locationsets();	// needs glyph
+
+	g_print("initializing search\n");
+	search_init();
+
+	g_print("initializing locations\n");
+	location_init();
+
 	g_print("initialization complete\n");
 
 	return TRUE;

Index: mainwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/mainwindow.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- mainwindow.c	26 Sep 2005 13:57:13 -0000	1.43
+++ mainwindow.c	30 Sep 2005 05:09:51 -0000	1.44
@@ -106,8 +106,6 @@
 
 #define MAX_DISTANCE_FOR_AUTO_SLIDE_IN_PIXELS	(3500.0)	// when selecting search results, we slide to them instead of jumping if they are within this distance
 
-#define LOCATIONSET_LIST_MIN_NAME_WIDTH_IN_CHARS (17)	// also forces minimum sidebar width
-
 // Types
 typedef struct {
 	GdkCursorType CursorType;
@@ -240,6 +238,7 @@
 	GtkMenuItem* pWebMapsMenuItem;
 } g_MainWindow = {0};
 
+// XXX: Use GDK_HAND1 for the map
 
 // Data
 toolsettings_t g_Tools[] = {
@@ -402,24 +401,17 @@
 	g_MainWindow.pTooltip 		= tooltip_new();
 
 	// Drawing area
-	g_MainWindow.pDrawingArea = GTK_DRAWING_AREA(gtk_drawing_area_new());
+	g_MainWindow.pDrawingArea = GTK_DRAWING_AREA(gtk_drawing_area_new());	
+	g_print("initializing glyphs\n");
+	glyph_init(g_MainWindow.pDrawingArea);
 	gtk_widget_show(GTK_WIDGET(g_MainWindow.pDrawingArea));
 
 	// create map and load style
 	map_new(&g_MainWindow.pMap, GTK_WIDGET(g_MainWindow.pDrawingArea));
 	map_style_load(g_MainWindow.pMap, MAP_STYLE_FILENAME);
-
-	// Signal handlers for drawing area
-	gtk_widget_add_events(GTK_WIDGET(g_MainWindow.pDrawingArea), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "expose_event", G_CALLBACK(mainwindow_on_expose_event), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "configure_event", G_CALLBACK(mainwindow_on_configure_event), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "button_press_event", G_CALLBACK(mainwindow_on_mouse_button_click), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "button_release_event", G_CALLBACK(mainwindow_on_mouse_button_click), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "motion_notify_event", G_CALLBACK(mainwindow_on_mouse_motion), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "scroll_event", G_CALLBACK(mainwindow_on_mouse_scroll), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "enter_notify_event", G_CALLBACK(mainwindow_on_enter_notify), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "leave_notify_event", G_CALLBACK(mainwindow_on_leave_notify), NULL);
-	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "key_press_event", G_CALLBACK(mainwindow_on_key_press), NULL);
+	
+	g_assert(g_MainWindow.pContentBox);
+	g_assert(g_MainWindow.pDrawingArea);
 
 	// Pack drawing area into application window
 	gtk_box_pack_end(GTK_BOX(g_MainWindow.pContentBox), GTK_WIDGET(g_MainWindow.pDrawingArea),
@@ -433,17 +425,29 @@
 	mainwindow_refresh_locationset_list();
 
 	mainwindow_statusbar_update_zoomscale();
-	mainwindow_statusbar_update_position();	
+	mainwindow_statusbar_update_position();
 
 	// Slide timeout
 	g_timeout_add(SLIDE_TIMEOUT_MS, (GSourceFunc)mainwindow_on_slide_timeout, (gpointer)NULL);
 
 	// GPS check timeout
 	g_timeout_add(TIMER_GPS_REDRAW_INTERVAL_MS, (GSourceFunc)mainwindow_on_gps_redraw_timeout, (gpointer)NULL);
-	mainwindow_on_gps_redraw_timeout(NULL);		// give it a call to set all labels, etc.
+	mainwindow_on_gps_redraw_timeout(NULL);     // give it a call to set all labels, etc.
 
 	// When main window closes, quit.
 	g_signal_connect(G_OBJECT(g_MainWindow.pWindow), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
+
+	// Signal handlers for drawing area
+	gtk_widget_add_events(GTK_WIDGET(g_MainWindow.pDrawingArea), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "expose_event", G_CALLBACK(mainwindow_on_expose_event), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "configure_event", G_CALLBACK(mainwindow_on_configure_event), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "button_press_event", G_CALLBACK(mainwindow_on_mouse_button_click), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "button_release_event", G_CALLBACK(mainwindow_on_mouse_button_click), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "motion_notify_event", G_CALLBACK(mainwindow_on_mouse_motion), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "scroll_event", G_CALLBACK(mainwindow_on_mouse_scroll), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "enter_notify_event", G_CALLBACK(mainwindow_on_enter_notify), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "leave_notify_event", G_CALLBACK(mainwindow_on_leave_notify), NULL);
+	g_signal_connect(G_OBJECT(g_MainWindow.pDrawingArea), "key_press_event", G_CALLBACK(mainwindow_on_key_press), NULL);
 }
 
 gboolean mainwindow_locationset_list_is_separator_callback(GtkTreeModel *_unused, GtkTreeIter *pIter, gpointer __unused)
@@ -483,7 +487,6 @@
 		// NEW COLUMN: "Name" column
 		pCellRenderer = gtk_cell_renderer_text_new();
 			g_object_set(G_OBJECT(pCellRenderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-			//g_object_set(G_OBJECT(pCellRenderer), "width-chars", LOCATIONSET_LIST_MIN_NAME_WIDTH_IN_CHARS, NULL);
 		pColumn = gtk_tree_view_column_new_with_attributes("Name", pCellRenderer, "markup", LOCATIONSETLIST_COLUMN_NAME, NULL);
 			gtk_tree_view_column_set_expand(pColumn, TRUE);
 		gtk_tree_view_append_column(g_MainWindow.pLocationSetsTreeView, pColumn);

Index: mainwindow.h
===================================================================
RCS file: /cvs/cairo/roadster/src/mainwindow.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- mainwindow.h	24 Sep 2005 05:25:25 -0000	1.11
+++ mainwindow.h	30 Sep 2005 05:09:51 -0000	1.12
@@ -81,8 +81,8 @@
 void mainwindow_scroll_direction(EDirection eScrollDirection, gint nPixels);
 
 #define SIDEBAR_TAB_LOCATIONSETS	0
-#define SIDEBAR_TAB_TRACKS			1
-#define SIDEBAR_TAB_SEARCH_RESULTS	2
+//#define SIDEBAR_TAB_TRACKS			1
+#define SIDEBAR_TAB_SEARCH_RESULTS	1
 
 void mainwindow_sidebar_set_tab(gint nTab);
 

Index: map.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- map.c	26 Sep 2005 13:57:13 -0000	1.47
+++ map.c	30 Sep 2005 05:09:51 -0000	1.48
@@ -1257,7 +1257,7 @@
 
 gboolean map_layer_render_type_atoi(const gchar* pszName, gint* pnReturnRenderTypeID)
 {
-	gchar* g_apszMapRenderTypeNames[] = {"lines", "polygons", "line-labels", "polygon-labels", "fill"};
+	gchar* g_apszMapRenderTypeNames[] = {"lines", "polygons", "line-labels", "polygon-labels", "fill", "locations", "location-labels"};
 
 	gint i;
 	for(i=0 ; i<G_N_ELEMENTS(g_apszMapRenderTypeNames) ; i++) {

Index: map.h
===================================================================
RCS file: /cvs/cairo/roadster/src/map.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- map.h	25 Sep 2005 19:02:37 -0000	1.23
+++ map.h	30 Sep 2005 05:09:51 -0000	1.24
@@ -48,6 +48,7 @@
 #define MAP_OBJECT_TYPE_FIRST					(1)
 #define MAP_OBJECT_TYPE_LAST					(12)
 
+
 //
 // Line CAP styles
 //
@@ -249,6 +250,8 @@
 	MAP_LAYER_RENDERTYPE_LINE_LABELS,
 	MAP_LAYER_RENDERTYPE_POLYGON_LABELS,
 	MAP_LAYER_RENDERTYPE_FILL,
+	MAP_LAYER_RENDERTYPE_LOCATIONS,
+	MAP_LAYER_RENDERTYPE_LOCATION_LABELS,
 } EMapLayerRenderType;
 
 typedef struct {

Index: map_draw_cairo.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_cairo.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- map_draw_cairo.c	25 Sep 2005 19:02:37 -0000	1.23
+++ map_draw_cairo.c	30 Sep 2005 05:09:51 -0000	1.24
@@ -27,7 +27,7 @@
 #define 	ROUND_DOWN_TEXT_ANGLE	(100.0)		// 10.0 to keep one decimal place or 100.0 to keep two
 
 #define ENABLE_LABEL_LIMIT_TO_ROAD				// take road line length into account when drawing labels!
-#define	ACCEPTABLE_LINE_LABEL_OVERDRAW_IN_PIXELS (15)	// XXX: make this a run-time variable
+#define	ACCEPTABLE_LINE_LABEL_OVERDRAW_IN_PIXELS (18)	// XXX: make this a run-time variable
 #define ENABLE_DRAW_MAP_SCALE
 //#define ENABLE_MAP_DROP_SHADOW
 

Index: map_draw_gdk.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_gdk.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- map_draw_gdk.c	26 Sep 2005 13:57:13 -0000	1.20
+++ map_draw_gdk.c	30 Sep 2005 05:09:51 -0000	1.21
@@ -105,10 +105,14 @@
 											pMap->apLayerData[pLayer->nDataSource]->pRoadsArray,          // data
 											pLayer->paStylesAtZoomLevels[pRenderMetrics->nZoomLevel-1]); 	// style
 			}
+			else if(pLayer->nDrawType == MAP_LAYER_RENDERTYPE_LOCATIONS) {
+				map_draw_gdk_locations(pMap, pPixmap, pRenderMetrics);
+			}
+			else if(pLayer->nDrawType == MAP_LAYER_RENDERTYPE_LOCATION_LABELS) {
+				//map_draw_gdk_locations(pMap, pPixmap, pRenderMetrics);
+			}
 		}
-
 		map_draw_gdk_tracks(pMap, pPixmap, pRenderMetrics);
-		map_draw_gdk_locations(pMap, pPixmap, pRenderMetrics);
 	}
 
 	// 3. Labels
@@ -119,18 +123,6 @@
 	TIMER_END(maptimer, "END RENDER MAP (gdk)");
 }
 
-// static void map_draw_gdk_background(map_t* pMap, GdkPixmap* pPixmap)
-// {
-//     GdkColor clr;
-//     clr.red = 236/255.0 * 65535;
-//     clr.green = 230/255.0 * 65535;
-//     clr.blue = 230/255.0 * 65535;
-//     gdk_gc_set_rgb_fg_color(pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)], &clr);
-//
-//     gdk_draw_rectangle(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
-//             TRUE, 0,0, pMap->MapDimensions.uWidth, pMap->MapDimensions.uHeight);
-// }
-
 static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
 {
 	mappoint_t* pPoint;
@@ -139,8 +131,25 @@
 	gint iPoint;
 
 	if(pLayerStyle->clrPrimary.fAlpha == 0.0) return;	// invisible?  (not that we respect it in gdk drawing anyway)
+	if(pRoadsArray->len == 0) return;
+
+	GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
+
+	GdkGCValues gcValues;
+	if(pLayerStyle->pGlyphFill != NULL) {
+		// Instead of filling with a color, fill with a tiled image
+		gdk_gc_get_values(pGC, &gcValues);
+		gdk_gc_set_fill(pGC, GDK_TILED);
+		gdk_gc_set_tile(pGC, glyph_get_pixmap(pLayerStyle->pGlyphFill));
+		
+		// This makes the fill image scroll with the map, instead of staying still
+		gdk_gc_set_ts_origin(pGC, SCALE_X(pRenderMetrics, pRenderMetrics->fScreenLongitude), SCALE_Y(pRenderMetrics, pRenderMetrics->fScreenLatitude));
+	}
+	else {
+		// Simple color fill
+		map_draw_gdk_set_color(pGC, &(pLayerStyle->clrPrimary));
+	}
 
-	map_draw_gdk_set_color(pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)], &(pLayerStyle->clrPrimary));
 
 	for(iString=0 ; iString<pRoadsArray->len ; iString++) {
 		pRoad = g_ptr_array_index(pRoadsArray, iString);
@@ -154,10 +163,11 @@
 			GdkPoint aPoints[MAX_GDK_LINE_SEGMENTS];
 
 			if(pRoad->pPointsArray->len > MAX_GDK_LINE_SEGMENTS) {
-				//g_warning("not drawing line with > %d segments\n", MAX_GDK_LINE_SEGMENTS);
+				g_warning("not drawing line with > %d segments\n", MAX_GDK_LINE_SEGMENTS);
 				continue;
 			}
 
+			// XXX: the bounding box should be pre-calculated!!!!
 			for(iPoint=0 ; iPoint<pRoad->pPointsArray->len ; iPoint++) {
 				pPoint = g_ptr_array_index(pRoad->pPointsArray, iPoint);
 
@@ -179,18 +189,44 @@
 			{
 			    continue;	// not visible
 			}
+
 			gdk_draw_polygon(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
 				TRUE, aPoints, pRoad->pPointsArray->len);
    		}
 	}
+	if(pLayerStyle->pGlyphFill != NULL) {
+		// Restore fill style
+		gdk_gc_set_values(pGC, &gcValues, GDK_GC_FILL);
+	}
 }
 
 // useful for filling the screen with a color.  not much else.
 static void map_draw_gdk_layer_fill(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, maplayerstyle_t* pLayerStyle)
 {
-	map_draw_gdk_set_color(pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)], &(pLayerStyle->clrPrimary));
+	GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
+
+	GdkGCValues gcValues;
+	if(pLayerStyle->pGlyphFill != NULL) {
+		// Instead of filling with a color, fill with a tiled image
+		gdk_gc_get_values(pGC, &gcValues);
+		gdk_gc_set_fill(pGC, GDK_TILED);
+		gdk_gc_set_tile(pGC, glyph_get_pixmap(pLayerStyle->pGlyphFill));
+		
+		// This makes the fill image scroll with the map, instead of staying still
+		gdk_gc_set_ts_origin(pGC, SCALE_X(pRenderMetrics, pRenderMetrics->fScreenLongitude), SCALE_Y(pRenderMetrics, pRenderMetrics->fScreenLatitude));
+	}
+	else {
+		// Simple color fill
+		map_draw_gdk_set_color(pGC, &(pLayerStyle->clrPrimary));
+	}
+
 	gdk_draw_rectangle(pPixmap, pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)],
 			TRUE, 0,0, pMap->MapDimensions.uWidth, pMap->MapDimensions.uHeight);
+
+	if(pLayerStyle->pGlyphFill != NULL) {
+		// Restore fill style
+		gdk_gc_set_values(pGC, &gcValues, GDK_GC_FILL);
+	}
 }
 
 static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
@@ -336,20 +372,17 @@
 	}
 }
 
+// Draw all locations from sets marked visible
 static void map_draw_gdk_locations(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics)
 {
 	const GPtrArray* pLocationSetsArray = locationset_get_array();
 
-	g_print("pLocationSetsArray->len = %d\n", pLocationSetsArray->len);
-
 	gint i;
 	for(i=0 ; i<pLocationSetsArray->len ; i++) {
 		locationset_t* pLocationSet = g_ptr_array_index(pLocationSetsArray, i);
-
 		if(!locationset_is_visible(pLocationSet)) continue;
-		g_print("visible one: %s\n", pLocationSet->pszName);
 
-		// 2. Get array of Locations from the hash table using LocationSetID
+		// 2. Get the array of Locations from the hash table using LocationSetID
 		GPtrArray* pLocationsArray;
 		pLocationsArray = g_hash_table_lookup(pMap->pLocationArrayHashTable, &(pLocationSet->nID));
 		if(pLocationsArray != NULL) {
@@ -364,7 +397,7 @@
 
 static void map_draw_gdk_locationset(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, locationset_t* pLocationSet, GPtrArray* pLocationsArray)
 {
-	g_print("Drawing set with %d\n", pLocationsArray->len);
+	//g_print("Drawing set with %d\n", pLocationsArray->len);
 	gint i;
 	for(i=0 ; i<pLocationsArray->len ; i++) {
 		location_t* pLocation = g_ptr_array_index(pLocationsArray, i);
@@ -378,34 +411,38 @@
 		    continue;   // not visible
 		}
 
-		gint nX = (gint)SCALE_X(pRenderMetrics, pLocation->Coordinates.fLongitude);
-		gint nY = (gint)SCALE_Y(pRenderMetrics, pLocation->Coordinates.fLatitude);
+		gdouble fX = SCALE_X(pRenderMetrics, pLocation->Coordinates.fLongitude);
+		gdouble fY = SCALE_Y(pRenderMetrics, pLocation->Coordinates.fLatitude);
 
 		GdkGC* pGC = pMap->pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->pTargetWidget)];
-		glyph_draw_centered(pLocationSet->pMapGlyph, pPixmap, pGC, (gdouble)nX, (gdouble)nY);
-
-//		g_print("drawing at %d,%d\n", nX,nY);
-
-//         GdkColor clr1;
-//         clr1.red = 255/255.0 * 65535;
-//         clr1.green = 80/255.0 * 65535;
-//         clr1.blue = 80/255.0 * 65535;
-//         GdkColor clr2;
-//         clr2.red = 255/255.0 * 65535;
-//         clr2.green = 255/255.0 * 65535;
-//         clr2.blue = 255/255.0 * 65535;
-//
-//         gdk_gc_set_rgb_fg_color(pGC, &clr1);
-//         gdk_draw_rectangle(pPixmap, pGC, TRUE,
-//                     nX-3,nY-3,
-//                     7, 7);
-//         gdk_gc_set_rgb_fg_color(pGC, &clr2);
-//         gdk_draw_rectangle(pPixmap, pGC, TRUE,
-//                     nX-2,nY-2,
-//                     5, 5);
-//         gdk_gc_set_rgb_fg_color(pGC, &clr1);
-//         gdk_draw_rectangle(pPixmap, pGC, TRUE,
-//                     nX-1,nY-1,
-//                     3, 3);
+		if(map_get_zoomlevel(pMap) <= 3) {
+			glyph_draw_centered(pLocationSet->pMapGlyphSmall, pPixmap, pGC, fX, fY);
+		}
+		else {
+			glyph_draw_centered(pLocationSet->pMapGlyph, pPixmap, pGC, fX, fY);
+		}
 	}
 }
+
+//             GdkColor clr1;
+//             clr1.red = 255/255.0 * 65535;
+//             clr1.green = 80/255.0 * 65535;
+//             clr1.blue = 80/255.0 * 65535;
+//             GdkColor clr2;
+//             clr2.red = 255/255.0 * 65535;
+//             clr2.green = 255/255.0 * 65535;
+//             clr2.blue = 255/255.0 * 65535;
+//
+//             gdk_gc_set_rgb_fg_color(pGC, &clr1);
+//             gdk_draw_rectangle(pPixmap, pGC, TRUE,
+//                         nX-3,nY-3,
+//                         7, 7);
+//             gdk_gc_set_rgb_fg_color(pGC, &clr2);
+//             gdk_draw_rectangle(pPixmap, pGC, TRUE,
+//                         nX-2,nY-2,
+//                         5, 5);
+//             gdk_gc_set_rgb_fg_color(pGC, &clr1);
+//             gdk_draw_rectangle(pPixmap, pGC, TRUE,
+//                         nX-1,nY-1,
+//                         3, 3);
+

Index: map_style.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_style.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- map_style.c	25 Sep 2005 19:02:37 -0000	1.2
+++ map_style.c	30 Sep 2005 05:09:51 -0000	1.3
@@ -33,8 +33,6 @@
 #define EACH_ATTRIBUTE_OF_NODE(a,n)		(a) = (n)->properties ; (a) != NULL ; (a) = (a)->next
 #define EACH_CHILD_OF_NODE(c,n)			(c) = (n)->children ; (c) != NULL ; (c) = (c)->next
 
-GHashTable* g_pConstantsHash = NULL;	// XXX: globals suck. :(
-
 static maplayer_t* map_style_new_layer();
 
 static void map_style_load_from_file(map_t* pMap, const gchar* pszFileName);
@@ -42,8 +40,6 @@
 static void map_style_parse_layers(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pParentNode);
 static void map_style_parse_layer(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pNode);
 static void map_style_parse_layer_property(map_t* pMap, xmlDocPtr pDoc, maplayer_t *pLayer, xmlNodePtr pNode);
-static void map_style_parse_constants(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pParentNode);
-static void map_style_parse_constant(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pNode);
 
 // Debugging
 static void map_style_print_layer(maplayer_t *layer);
@@ -86,40 +82,9 @@
 	}
 
 	pMap->pLayersArray = g_ptr_array_new();
-
-	if(g_pConstantsHash != NULL) {
-		g_hash_table_destroy(g_pConstantsHash);		// NOTE: This frees all keys and values for us.
-	}
-	g_pConstantsHash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);	// same as above
 	map_style_load_from_file(pMap, pszFileName);
 }
 
-//
-// Constants
-//
-gboolean map_style_constant_get(const gchar* pszName, gchar** ppszReturnValue)
-{
-	g_assert(pszName);
-	g_assert(ppszReturnValue);
-	g_assert(*ppszReturnValue == NULL);	// require pointer to NULL pointer
-
-	gchar* pszValue = g_hash_table_lookup(g_pConstantsHash, pszName);
-	if(pszValue != NULL) {
-		*ppszReturnValue = pszValue;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-void map_style_constant_set(const gchar* pszName, const gchar* pszValue)
-{
-	g_assert(pszName != NULL);
-	g_assert(pszValue != NULL);
-
-	// NOTE: if there was an existing key with this name, the old key and old value will get auto-freed by glib
-	g_hash_table_replace(g_pConstantsHash, (gchar*)pszName, (gchar*)pszValue);
-}
-
 static maplayer_t* map_style_new_layer()
 {
 	maplayer_t *pLayer = g_new0(maplayer_t, 1);
@@ -315,9 +280,6 @@
 			if(strcmp(pChildNode->name, "layers") == 0) {
 				map_style_parse_layers(pMap, pDoc, pChildNode);
 			}
-			else if(strcmp(pChildNode->name, "constants") == 0) {
-				map_style_parse_constants(pMap, pDoc, pChildNode);
-			}
 		}
 	}
 }
@@ -340,55 +302,6 @@
 	}
 }
 
-static void map_style_parse_constants(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pParentNode)
-{
-	g_assert(pMap != NULL);
-	g_assert(pDoc != NULL);
-	g_assert(pParentNode != NULL);
-
-//	g_print("map_style_parse_constants()\n");
-	xmlNodePtr pChildNode = NULL;
-
-	for(EACH_CHILD_OF_NODE(pChildNode, pParentNode)) {
-		if(pChildNode->type == XML_ELEMENT_NODE && strcmp(pChildNode->name, "constant") == 0) {
-			map_style_parse_constant(pMap, pDoc, pChildNode);
-		}
-	}
-}
-
-static void map_style_parse_constant(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pNode)
-{
-	g_assert(pMap != NULL);
-	g_assert(pDoc != NULL);
-	g_assert(pNode != NULL);
-
-//	g_print("map_style_parse_constant()\n");
-	xmlAttrPtr pAttribute = NULL;
-
-	gchar* pszName = NULL;
-	gchar* pszValue = NULL;
-
-	for(EACH_ATTRIBUTE_OF_NODE(pAttribute, pNode)) {
-		if(strcmp(pAttribute->name, "name") == 0) {
-			g_free(pszName);
-			pszName = get_attribute_value(pDoc, pAttribute);
-		}
-		else if(strcmp(pAttribute->name, "value") == 0) {
-			g_free(pszValue);
-			pszValue = get_attribute_value(pDoc, pAttribute);
-		}
-	}
-
-	if(pszName != NULL && pszValue != NULL) {
-		// duplicate strings to keep long-term in the hash table
-		map_style_constant_set(g_strdup(pszName), g_strdup(pszValue));		
-	}
-	g_free(pszName);
-	g_free(pszValue);
-//	g_free(pszName);
-//	g_free(pszValue);
-}
-
 static void map_style_parse_layer(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pNode)
 {
 	g_assert(pMap != NULL);
@@ -467,13 +380,6 @@
 		map_style_parse_zoomlevel(pszZoomLevel, &nMinZoomLevel, &nMaxZoomLevel);
 	}
 
-	// If the 'value' is the name of a constant, replace it with the value of the constant
-	gchar* pszConstantValue = NULL;
-	if(map_style_constant_get(pszValue, &pszConstantValue)) {
-		g_free(pszValue);
-		pszValue = g_strdup(pszConstantValue);
-	}
-
 	if(pszName != NULL && pszValue != NULL) {
 		gint i;
 		if(strcmp(pszName, "line-width") == 0) {
@@ -520,6 +426,11 @@
 				}
 			}
 		}
+		else if(strcmp(pszName, "fill-image") == 0) {
+			for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
+				pLayer->paStylesAtZoomLevels[i]->pGlyphFill = glyph_load(pszValue);
+			}
+		}
 		else if(strcmp(pszName, "bold") == 0) {
 			gboolean bBold = (strcmp(pszValue, "yes") == 0);
 			for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {

Index: map_style.h
===================================================================
RCS file: /cvs/cairo/roadster/src/map_style.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- map_style.h	25 Sep 2005 19:02:37 -0000	1.2
+++ map_style.h	30 Sep 2005 05:09:51 -0000	1.3
@@ -31,6 +31,7 @@
 
 #include "main.h"
 #include "map.h"
+#include "glyph.h"
 
 typedef struct dashstyle {
 	gdouble* pafDashList;	// the dashes, as an array of gdouble's (for Cairo)
@@ -40,17 +41,15 @@
 
 // defines the look of a layer
 typedef struct layerstyle {
-	color_t clrPrimary;	// Color used for polygon fill or line stroke
-	gdouble fLineWidth;
+	color_t clrPrimary;		// Color used for polygon fill or line stroke
+	glyph_t* pGlyphFill;	// glyph image used to fill polygon, or NULL
 
+	// Used just for lines
+	gdouble fLineWidth;
 	gint nJoinStyle;
 	gint nCapStyle;
-	
 	dashstyle_t* pDashStyle;
 
-	// XXX: switch to this:
-	//dashstyle_t pDashStyle;	// can be NULL
-
 	// Used just for text
 	gdouble fFontSize;
 	gboolean bFontBold;

Index: road.h
===================================================================
RCS file: /cvs/cairo/roadster/src/road.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- road.h	25 Sep 2005 19:02:37 -0000	1.3
+++ road.h	30 Sep 2005 05:09:51 -0000	1.4
@@ -26,6 +26,8 @@
 
 typedef struct {
 	GPtrArray* pPointsArray;
+//	maprect_t rcMapBoundingBox;
+
 	gchar* pszName;
 	gint nAddressLeftStart;
 	gint nAddressLeftEnd;

Index: searchwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/searchwindow.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- searchwindow.c	26 Sep 2005 13:57:14 -0000	1.24
+++ searchwindow.c	30 Sep 2005 05:09:51 -0000	1.25
@@ -57,6 +57,10 @@
 
 struct {
 	GtkEntry* pSearchEntry;		// search text box (on the toolbar)
+	GtkComboBoxEntry* pSearchComboBoxEntry;
+
+	GtkEntry* pSearchLocationEntry;		// search text box (on the toolbar)
+
 	GtkButton* pSearchButton;		// search button (on the toolbar)
 
 	// results list (on the sidebar)
@@ -80,6 +84,8 @@
 void searchwindow_init(GladeXML* pGladeXML)
 {
 	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pSearchEntry, GTK_ENTRY, "searchentry");
+	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pSearchComboBoxEntry, GTK_COMBO_BOX_ENTRY, "searchcomboboxentry");
+	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pSearchLocationEntry, GTK_ENTRY, "searchlocationentry");
 	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pSearchButton, GTK_BUTTON, "searchbutton");
 	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pResultsTreeView, GTK_TREE_VIEW, "searchresultstreeview");
 	GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.pNextSearchResultMenuItem, GTK_MENU_ITEM, "nextresultmenuitem");
@@ -112,6 +118,12 @@
 	g_signal_connect(G_OBJECT(pTreeSelection), "changed", (GtkSignalFunc)searchwindow_on_resultslist_selection_changed, NULL);
 
 	searchwindow_update_next_and_prev_buttons();
+
+//	util_gtk_entry_add_hint_text(g_SearchWindow.pSearchEntry, "type place or address");
+	util_gtk_entry_add_hint_text(g_SearchWindow.pSearchLocationEntry, "near here");
+
+	g_SearchWindow.pSearchComboBoxEntry;
+	GtkComboBoxEntry a;
 }
 
 void searchwindow_clear_results(void)

Index: util.c
===================================================================
RCS file: /cvs/cairo/roadster/src/util.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- util.c	25 Sep 2005 19:02:37 -0000	1.12
+++ util.c	30 Sep 2005 05:09:51 -0000	1.13
@@ -403,3 +403,48 @@
 	g_string_free(pStringBuffer, FALSE);	// do NOT free the 'str' memory
 	return pszReturn;
 }
+
+//
+// 
+//
+static void _util_gtk_entry_set_hint_text(GtkEntry* pEntry, const gchar* pszHint)
+{
+	gtk_widget_modify_text(pEntry, GTK_STATE_NORMAL, &(GTK_WIDGET(pEntry)->style->text_aa[GTK_WIDGET_STATE(pEntry)]));
+	gtk_entry_set_text(pEntry, pszHint);
+}
+
+static void _util_gtk_entry_clear_hint_text(GtkEntry* pEntry)
+{
+	gtk_widget_modify_text(pEntry, GTK_STATE_NORMAL, NULL); 
+	gtk_entry_set_text(pEntry, "");
+}
+
+static gboolean _util_gtk_entry_on_focus_in_event(GtkEntry* pEntry, GdkEventFocus* _unused, gchar* pszHint)
+{
+	// If the box is showing pszHint, clear it
+	gchar* pszExistingText = gtk_entry_get_text(pEntry);
+	if(strcmp(pszExistingText, pszHint) == 0) {
+		_util_gtk_entry_clear_hint_text(pEntry);
+	}
+	return FALSE;	// always say we didn't handle it so the normal processing happens
+}
+
+static gboolean _util_gtk_entry_on_focus_out_event(GtkEntry* pEntry, GdkEventFocus* _unused, gchar* pszHint)
+{
+	// If the box is empty, set the hint text
+	gchar* pszExistingText = gtk_entry_get_text(pEntry);
+	if(strcmp(pszExistingText, "") == 0) {
+		_util_gtk_entry_set_hint_text(pEntry, pszHint);
+	}
+	return FALSE;	// always say we didn't handle it so the normal processing happens
+}
+
+// The API
+void util_gtk_entry_add_hint_text(GtkEntry* pEntry, const gchar* pszHint)
+{
+	g_signal_connect(G_OBJECT(pEntry), "focus-in-event", _util_gtk_entry_on_focus_in_event, pszHint);
+	g_signal_connect(G_OBJECT(pEntry), "focus-out-event", _util_gtk_entry_on_focus_out_event, pszHint);
+
+	// Init it
+	_util_gtk_entry_on_focus_out_event(pEntry, NULL, pszHint);
+}

Index: util.h
===================================================================
RCS file: /cvs/cairo/roadster/src/util.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- util.h	25 Sep 2005 19:02:37 -0000	1.12
+++ util.h	30 Sep 2005 05:09:51 -0000	1.13
@@ -73,4 +73,7 @@
 
 gchar* util_str_replace_many(const gchar* pszSource, util_str_replace_t* aReplacements, gint nNumReplacements);
 
+// GtkEntry "hint"
+void util_gtk_entry_add_hint_text(GtkEntry* pEntry, const gchar* pszMessage);
+
 #endif



More information about the cairo-commit mailing list