[cairo-commit]
roadster/src Makefile.am, 1.17, 1.18 animator.c, 1.5,
1.6 db.c, 1.25, 1.26 db.h, 1.10, 1.11 gotowindow.c, 1.9,
1.10 gpsclient.c, 1.10, 1.11 gpsclient.h, 1.3, 1.4 gui.c, 1.10,
1.11 gui.h, 1.2, 1.3 import_tiger.c, 1.19, 1.20 importwindow.c,
1.8, 1.9 layers.c, 1.16, NONE layers.h, 1.8,
NONE locationeditwindow.c, NONE, 1.1 locationeditwindow.h,
NONE, 1.1 locationset.c, 1.11, 1.12 main.c, 1.22, 1.23 main.h,
1.2, 1.3 mainwindow.c, 1.39, 1.40 map.c, 1.43, 1.44 map.h,
1.20, 1.21 map_draw_cairo.c, 1.21, 1.22 map_draw_gdk.c, 1.17,
1.18 map_style.c, NONE, 1.1 map_style.h, NONE, 1.1 prefs.c,
1.3, NONE prefs.h, 1.1, NONE road.c, 1.5, 1.6 scenemanager.c,
1.13, 1.14 search.c, 1.5, 1.6 search_road.c, 1.21,
1.22 searchwindow.c, 1.19, 1.20 util.c, 1.9, 1.10 util.h, 1.9, 1.10
Ian McIntosh
commit at pdx.freedesktop.org
Wed Sep 14 13:06:56 PDT 2005
Committed by: ian
Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv9354/src
Modified Files:
Makefile.am animator.c db.c db.h gotowindow.c gpsclient.c
gpsclient.h gui.c gui.h import_tiger.c importwindow.c
locationset.c main.c main.h mainwindow.c map.c map.h
map_draw_cairo.c map_draw_gdk.c road.c scenemanager.c search.c
search_road.c searchwindow.c util.c util.h
Added Files:
locationeditwindow.c locationeditwindow.h map_style.c
map_style.h
Removed Files:
layers.c layers.h prefs.c prefs.h
Log Message:
* src/*.c: Removed many unneeded #includes. Removed NUM_ELEMS in favor of existing glib G_N_ELEMENTS.
* src/*window.c: Use GLADE_LINK_WIDGET to connect widget to Glade XML element.
* src/gpsclient.c: Work to make GPSD support optional at compile time.
* src/mainwindow.c: Fixed bug: mouse cursor returning to default pointer while scrolling.
* src/searchwindow.c: Change map zoomlevel when going to search results. Some code refactoring.
* src/gotowindow.c: Removed dead code.
* src/map_style.c: Added to replace layers.c. Add support for arbitrary dash patterns.
* src/map_draw_gdk.c: Support new arbitrary dash patterns.
* src/ma_draw_cairo.c: More work to restore Cairo drawing.
* src/prefs.c:
* src/prefs.h:
* src/layers.c:
* src/layers.h: Removed.
Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/roadster/src/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- Makefile.am 28 Aug 2005 22:23:14 -0000 1.17
+++ Makefile.am 14 Sep 2005 20:06:53 -0000 1.18
@@ -24,7 +24,9 @@
mainwindow.c\
gotowindow.c\
map.c\
- layers.c\
+ map_style.c\
+ map_draw_cairo.c\
+ map_draw_gdk.c\
import.c\
import_tiger.c\
importwindow.c\
@@ -33,6 +35,7 @@
gpsclient.c\
location.c\
locationset.c\
+ locationeditwindow.c\
searchwindow.c\
search_road.c\
search_location.c\
@@ -42,10 +45,7 @@
pointstring.c\
track.c\
glyph.c\
- map_draw_cairo.c\
- map_draw_gdk.c\
road.c\
- prefs.c\
animator.c\
gfreelist.c\
history.c\
Index: animator.c
===================================================================
RCS file: /cvs/cairo/roadster/src/animator.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- animator.c 28 Aug 2005 22:23:14 -0000 1.5
+++ animator.c 14 Sep 2005 20:06:53 -0000 1.6
@@ -25,11 +25,9 @@
# include <config.h>
#endif
-#include <gtk/gtk.h>
+#include <glib.h>
-#include "main.h"
#include "animator.h"
-#include "util.h"
void animator_init()
{
@@ -115,7 +113,7 @@
}
// Make 100% sure it's capped to 0.0 -> 1.0
- fReturn = min(fReturn, 1.0);
- fReturn = max(fReturn, 0.0);
+ fReturn = MIN(fReturn, 1.0);
+ fReturn = MAX(fReturn, 0.0);
return fReturn;
}
Index: db.c
===================================================================
RCS file: /cvs/cairo/roadster/src/db.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- db.c 6 Sep 2005 02:44:19 -0000 1.25
+++ db.c 14 Sep 2005 20:06:53 -0000 1.26
@@ -38,7 +38,6 @@
#include "db.h"
#include "mainwindow.h"
#include "util.h"
-#include "layers.h"
#include "location.h"
#include "locationset.h"
@@ -104,7 +103,7 @@
// Initialize the embedded server
// NOTE: if not linked with libmysqld, this call will do nothing (but will succeed)
- if(mysql_server_init(NUM_ELEMS(apszServerOptions), apszServerOptions, NULL) != 0) {
+ if(mysql_server_init(G_N_ELEMENTS(apszServerOptions), apszServerOptions, NULL) != 0) {
return;
}
g_free(pszDataDir);
@@ -577,12 +576,7 @@
// lots of indexes:
" PRIMARY KEY (ID)," // XXX: we'll probably want to keep a unique ID, but we don't use this for anything yet.
-
" INDEX(RoadNameID)," // to get roads when we've matched a RoadName
-// " INDEX(AddressLeftStart, AddressLeftEnd)," // drop these? they reduce a few seeks on address searches IF the
-// " INDEX(AddressRightStart, AddressRightEnd)," // user puts in a street #. they take up 8*roadsegments bytes of
- // disk and eat up precious index cache memory
-
" SPATIAL KEY (Coordinates));", NULL);
// RoadName
@@ -612,7 +606,7 @@
" Code CHAR(3) NOT NULL," // eg. "MA"
" CountryID INT2 NOT NULL," // NOTE: 2 bytes
" PRIMARY KEY (ID),"
- " INDEX (Name(5)));" // 4 is enough for decent uniqueness.
+ " INDEX (Name(5)));" // 5 is enough for decent uniqueness.
,NULL);
// Location
@@ -659,120 +653,3 @@
" Name VARCHAR(60) NOT NULL,"
" PRIMARY KEY (ID));", NULL);
}
-
-#ifdef ROADSTER_DEAD_CODE
-/*
-static void db_disconnect(void)
-{
- g_return_if_fail(g_pDB != NULL);
-
- // close database and free all strings
- mysql_close(g_pDB->m_pMySQLConnection);
- g_free(g_pDB->m_pzHost);
- g_free(g_pDB->m_pzUserName);
- g_free(g_pDB->m_pzPassword);
- g_free(g_pDB->m_pzDatabase);
-
- // free structure itself
- g_free(g_pDB);
- g_pDB = NULL;
-}
-
-//
-// WordHash functionality
-//
-#define DB_WORDHASH_TABLENAME "WordHash"
-
-gint32 db_wordhash_insert(db_connection_t* pConnection, const gchar* pszWord)
-{
- gchar azQuery[MAX_SQLBUFFER_LEN];
- int nResult;
-
- g_snprintf(azQuery, MAX_SQLBUFFER_LEN,
- "INSERT INTO %s SET ID=NULL, Value='%s';",
- DB_WORDHASH_TABLENAME, pszWord);
-
- if((nResult = mysql_query(pConnection->m_pMySQLConnection, azQuery)) != MYSQL_RESULT_SUCCESS) {
- g_message("db_word_to_int failed to insert: %s\n", mysql_error(pConnection->m_pMySQLConnection));
- return 0;
- }
- return mysql_insert_id(pConnection->m_pMySQLConnection);
-}
-
-gint32 db_wordhash_lookup(db_connection_t* pConnection, const gchar* pszWord)
-{
- MYSQL_RES* pResultSet;
- MYSQL_ROW aRow;
- gint nWordNumber = 0;
- int nResult;
- gchar azQuery[MAX_SQLBUFFER_LEN];
-
- if(!db_is_connected(pConnection)) return FALSE;
-
- // generate SQL
- g_snprintf(azQuery, MAX_SQLBUFFER_LEN, "SELECT ID FROM %s WHERE Value='%s';", DB_WORDHASH_TABLENAME, pszWord);
-
- // get row
- if((nResult = mysql_query(pConnection->m_pMySQLConnection, azQuery)) != MYSQL_RESULT_SUCCESS) {
- g_message("db_word_to_int failed to select: %s\n", mysql_error(pConnection->m_pMySQLConnection));
- return 0;
- }
- if((pResultSet = MYSQL_GET_RESULT(pConnection->m_pMySQLConnection)) != NULL) {
- if((aRow = mysql_fetch_row(pResultSet)) != NULL) {
- nWordNumber = atoi(aRow[0]);
- }
- mysql_free_result(pResultSet);
- }
-
- // Successful? Return it.
- if(nWordNumber != 0) return nWordNumber;
- else return 0;
-}
-
-void db_parse_pointstring(const gchar* pszText, pointstring_t* pPointString, gboolean (*callback_get_point)(mappoint_t**))
-{
- // parse string and add points to the string
- const gchar* p = pszText;
- if(p[0] == 'L') { //g_str_has_prefix(p, "LINESTRING")) {
- // format is "LINESTRING(1.2345 5.4321, 10 10, 20 20)"
- mappoint_t* pPoint;
-
- p += (11); // move past "LINESTRING("
-
- while(TRUE) {
- // g_print("reading a point...\n");
- pPoint = NULL;
- if(!callback_get_point(&pPoint)) return;
-
- // read in latitude
- pPoint->m_fLatitude = g_ascii_strtod(p, (gchar**)&p);
-
- // space between coordinates
- g_return_if_fail(*p == ' ');
- p++;
-
- // read in longitude
- pPoint->m_fLongitude = g_ascii_strtod(p, (gchar**)&p);
-
- // g_print("got (%f,%f)\n", pPoint->m_fLatitude, pPoint->m_fLongitude);
-
- // add point to the list
- g_ptr_array_add(pPointString->m_pPointsArray, pPoint);
-
- if(*p == ',') {
- p++;
-
- // after this, we're ready to read in next point, so loop...
- // g_print("looping for another!...\n");
- }
- else {
- break;
- }
- }
- }
- else {
- g_assert_not_reached();
- }
-}
-*/
-#endif
Index: db.h
===================================================================
RCS file: /cvs/cairo/roadster/src/db.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- db.h 29 Mar 2005 09:16:20 -0000 1.10
+++ db.h 14 Sep 2005 20:06:53 -0000 1.11
@@ -41,7 +41,7 @@
#define DB_FEATURES_TABLENAME ("Feature")
#include "map.h"
-#include "layers.h"
+//#include "layers.h"
#include "pointstring.h"
void db_create_tables(void);
Index: gotowindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/gotowindow.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- gotowindow.c 28 Mar 2005 18:49:50 -0000 1.9
+++ gotowindow.c 14 Sep 2005 20:06:53 -0000 1.10
@@ -26,6 +26,7 @@
#include "main.h"
#include "mainwindow.h"
#include "gotowindow.h"
+#include "gui.h"
struct {
GtkWindow* m_pWindow;
@@ -35,9 +36,9 @@
void gotowindow_init(GladeXML* pGladeXML)
{
- g_GotoWindow.m_pWindow = GTK_WINDOW(glade_xml_get_widget(pGladeXML, "gotowindow")); g_return_if_fail(g_GotoWindow.m_pWindow != NULL);
- g_GotoWindow.m_pLongitudeEntry = GTK_ENTRY(glade_xml_get_widget(pGladeXML, "longitudeentry")); g_return_if_fail(g_GotoWindow.m_pLongitudeEntry != NULL);
- g_GotoWindow.m_pLatitudeEntry = GTK_ENTRY(glade_xml_get_widget(pGladeXML, "latitudeentry")); g_return_if_fail(g_GotoWindow.m_pLatitudeEntry != NULL);
+ GLADE_LINK_WIDGET(pGladeXML, g_GotoWindow.m_pWindow, GTK_WINDOW, "gotowindow");
+ GLADE_LINK_WIDGET(pGladeXML, g_GotoWindow.m_pLongitudeEntry, GTK_ENTRY, "longitudeentry");
+ GLADE_LINK_WIDGET(pGladeXML, g_GotoWindow.m_pLatitudeEntry, GTK_ENTRY, "latitudeentry");
// don't delete window on X, just hide it
g_signal_connect(G_OBJECT(g_GotoWindow.m_pWindow), "delete_event", G_CALLBACK(gtk_widget_hide), NULL);
@@ -93,13 +94,6 @@
//
// Callbacks
//
-void gotowindow_on_knownlocationtreeview_row_activated(GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer user_data)
-{
- if(gotowindow_go()) {
- gotowindow_hide();
- }
-}
-
void gotowindow_on_gobutton_clicked(GtkButton *button, gpointer user_data)
{
// hide window when "Go" button clicked (successfully)
Index: gpsclient.c
===================================================================
RCS file: /cvs/cairo/roadster/src/gpsclient.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- gpsclient.c 28 Aug 2005 22:23:14 -0000 1.10
+++ gpsclient.c 14 Sep 2005 20:06:53 -0000 1.11
@@ -21,14 +21,18 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#define HAVE_GPSD // XXX: this should come from configure.ac
+
#include <gtk/gtk.h>
#include <gps.h>
#include "main.h"
#include "gpsclient.h"
struct {
- struct gps_data_t * m_pGPSConnection;
- gpsdata_t* m_pPublicGPSData;
+#ifdef HAVE_GPSD
+ struct gps_data_t * m_pGPSConnection; // gps_data_t is from gpsd.h
+#endif
+ gpsdata_t* m_pPublicGPSData; // our public struct (annoyingly similar name...)
} g_GPSClient = {0};
gboolean gpsclient_callback_data_waiting(GIOChannel *source, GIOCondition condition, gpointer data);
@@ -38,11 +42,16 @@
{
g_GPSClient.m_pPublicGPSData = g_new0(gpsdata_t, 1);
+#ifndef HAVE_GPSD
+ // No libgpsd at compile time
+ g_GPSClient.m_pPublicGPSData->m_eStatus = GPS_STATUS_NO_GPS_COMPILED_IN;
+#endif
gpsclient_connect();
}
static void gpsclient_connect(void)
{
+#ifdef HAVE_GPSD
// don't do anything if already connected
if(g_GPSClient.m_pPublicGPSData->m_eStatus != GPS_STATUS_NO_GPSD) return; // already connected
@@ -69,25 +78,28 @@
else {
g_GPSClient.m_pPublicGPSData->m_eStatus = GPS_STATUS_NO_GPSD;
}
+#endif
}
-
const gpsdata_t* gpsclient_getdata()
{
gpsclient_connect(); // connect if necessary
-
+
return g_GPSClient.m_pPublicGPSData;
}
// callback for g_io_add_watch on the GPSD file descriptor
-gboolean gpsclient_callback_data_waiting(GIOChannel *source, GIOCondition condition, gpointer data)
+gboolean gpsclient_callback_data_waiting(GIOChannel *_source_unused, GIOCondition eCondition, gpointer _data_unused)
{
+#ifdef HAVE_GPSD
// g_print("Data from GPSD...\n");
+ g_assert(g_GPSClient.m_pGPSConnection != NULL);
+ g_assert(g_GPSClient.m_pPublicGPSData != NULL);
gpsdata_t* l = g_GPSClient.m_pPublicGPSData; // our public data struct, for easy access
// is there data waiting on the socket?
- if(condition == G_IO_IN) {
+ if(eCondition == G_IO_IN) {
// read new data
if(gps_poll(g_GPSClient.m_pGPSConnection) == -1) {
l->m_eStatus = GPS_STATUS_NO_GPSD;
@@ -145,9 +157,10 @@
}
}
else {
- //g_print("condition: %d\n", condition);
+ //g_print("eCondition: %d\n", eCondition);
}
return TRUE; // TRUE = keep socket notification coming
+#endif
}
#ifdef ROADSTER_DEAD_CODE
Index: gpsclient.h
===================================================================
RCS file: /cvs/cairo/roadster/src/gpsclient.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- gpsclient.h 3 Mar 2005 07:32:46 -0000 1.3
+++ gpsclient.h 14 Sep 2005 20:06:53 -0000 1.4
@@ -29,6 +29,8 @@
#include "map.h"
typedef enum {
+ GPS_STATUS_NO_GPS_COMPILED_IN = -1, // no gpsd present at compile time
+
GPS_STATUS_NO_GPSD = 0, // daemon is absent :( (0 should be default state)
GPS_STATUS_NO_DEVICE = 1, // no physical GPS device :(
GPS_STATUS_NO_SIGNAL = 2, // can't get a signal :(
Index: gui.c
===================================================================
RCS file: /cvs/cairo/roadster/src/gui.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- gui.c 28 Aug 2005 22:23:14 -0000 1.10
+++ gui.c 14 Sep 2005 20:06:53 -0000 1.11
@@ -36,6 +36,7 @@
#include "importwindow.h"
#include "welcomewindow.h"
#include "searchwindow.h"
+#include "locationeditwindow.h"
void gui_init()
{
@@ -49,6 +50,7 @@
importwindow_init(pGladeXML);
//datasetwindow_init(pGladeXML);
welcomewindow_init(pGladeXML);
+ locationeditwindow_init(pGladeXML);
}
GladeXML* gui_load_xml(gchar* pszFileName, gchar* pszXMLTreeRoot)
Index: gui.h
===================================================================
RCS file: /cvs/cairo/roadster/src/gui.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- gui.h 23 Apr 2005 18:13:39 -0000 1.2
+++ gui.h 14 Sep 2005 20:06:54 -0000 1.3
@@ -27,17 +27,9 @@
#include <gtk/gtk.h>
#include <glade/glade.h>
-#define GLADE_FILE_NAME ("roadster.glade")
-
-extern GtkWidget *g_pApplicationWidget;
-extern GtkWidget *g_pDisplaySettingsWidget;
-
-struct gui_state_t {
- float m_fCenterX;
- float m_fCenterY;
+#define GLADE_LINK_WIDGET(glade, ptr, type, name) ptr = type(glade_xml_get_widget(glade, name)); g_return_if_fail(ptr != NULL)
- guint8 m_nZoomLevel;
-};
+#define GLADE_FILE_NAME ("roadster.glade")
//
// prototypes
Index: import_tiger.c
===================================================================
RCS file: /cvs/cairo/roadster/src/import_tiger.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- import_tiger.c 6 Sep 2005 02:44:19 -0000 1.19
+++ import_tiger.c 14 Sep 2005 20:06:54 -0000 1.20
@@ -1123,13 +1123,13 @@
gchar* pszFilePath;
gchar* apszExtensions[7] = {"MET", "RT1", "RT2", "RT7", "RT8", "RTC", "RTI"};
- gint8* apBuffers[NUM_ELEMS(apszExtensions)] = {0};
- gint nSizes[NUM_ELEMS(apszExtensions)] = {0};
+ gint8* apBuffers[G_N_ELEMENTS(apszExtensions)] = {0};
+ gint nSizes[G_N_ELEMENTS(apszExtensions)] = {0};
// open, read, and delete (unlink) each file
gint i;
gboolean bSuccess = TRUE;
- for(i=0 ; i<NUM_ELEMS(apszExtensions) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(apszExtensions) ; i++) {
pszFilePath = g_strdup_printf("file://%s/TGR%05d.%s", pszDirectoryPath, nTigerSetNumber, apszExtensions[i]);
if(GNOME_VFS_OK != gnome_vfs_read_entire_file(pszFilePath, &nSizes[i], (char**)&apBuffers[i])) {
bSuccess = FALSE;
@@ -1141,15 +1141,15 @@
// did we read all files?
if(bSuccess) {
gint nStateID = (nTigerSetNumber / 1000); // int division (eg. turn 25017 into 25)
- if(nStateID < NUM_ELEMS(g_aStates)) {
+ if(nStateID < G_N_ELEMENTS(g_aStates)) {
gint nCountryID = 1; // USA is #1 *gag*
db_insert_state(g_aStates[nStateID].m_pszName, g_aStates[nStateID].m_pszCode, nCountryID, &g_nStateID);
}
- g_assert(NUM_ELEMS(apszExtensions) == 7);
+ g_assert(G_N_ELEMENTS(apszExtensions) == 7);
bSuccess = import_tiger_from_buffers(apBuffers[0], nSizes[0], apBuffers[1], nSizes[1], apBuffers[2], nSizes[2], apBuffers[3], nSizes[3], apBuffers[4], nSizes[4], apBuffers[5], nSizes[5], apBuffers[6], nSizes[6]);
}
- for(i=0 ; i<NUM_ELEMS(apszExtensions) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(apszExtensions) ; i++) {
g_free(apBuffers[i]); // can be null
}
return bSuccess;
Index: importwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/importwindow.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- importwindow.c 6 Sep 2005 02:44:19 -0000 1.8
+++ importwindow.c 14 Sep 2005 20:06:54 -0000 1.9
@@ -29,6 +29,7 @@
#include "mainwindow.h"
#include "importwindow.h"
#include "util.h"
+#include "gui.h"
struct {
GtkWindow* m_pWindow;
@@ -43,14 +44,12 @@
void importwindow_init(GladeXML* pGladeXML)
{
- g_ImportWindow.m_pWindow = GTK_WINDOW(glade_xml_get_widget(pGladeXML, "importwindow")); g_return_if_fail(g_ImportWindow.m_pWindow != NULL);
- g_ImportWindow.m_pProgressBar = GTK_PROGRESS_BAR(glade_xml_get_widget(pGladeXML, "importprogressbar")); g_return_if_fail(g_ImportWindow.m_pProgressBar != NULL);
- g_ImportWindow.m_pOKButton = GTK_BUTTON(glade_xml_get_widget(pGladeXML, "importokbutton")); g_return_if_fail(g_ImportWindow.m_pOKButton != NULL);
-// g_ImportWindow.m_pCancelButton = GTK_BUTTON(glade_xml_get_widget(pGladeXML, "importcancelbutton")); g_return_if_fail(g_ImportWindow.m_pCancelButton != NULL);
- g_ImportWindow.m_pLogTextView = GTK_TEXT_VIEW(glade_xml_get_widget(pGladeXML, "importlogtextview")); g_return_if_fail(g_ImportWindow.m_pLogTextView != NULL);
+ GLADE_LINK_WIDGET(pGladeXML, g_ImportWindow.m_pWindow, GTK_WINDOW, "importwindow");
+ GLADE_LINK_WIDGET(pGladeXML, g_ImportWindow.m_pProgressBar, GTK_PROGRESS_BAR, "importprogressbar");
+ GLADE_LINK_WIDGET(pGladeXML, g_ImportWindow.m_pOKButton, GTK_BUTTON, "importokbutton");
+ GLADE_LINK_WIDGET(pGladeXML, g_ImportWindow.m_pLogTextView, GTK_TEXT_VIEW, "importlogtextview");
}
-
void importwindow_show(void)
{
gtk_widget_show(GTK_WIDGET(g_ImportWindow.m_pWindow));
--- layers.c DELETED ---
--- layers.h DELETED ---
--- NEW FILE: locationeditwindow.c ---
/***************************************************************************
* locationeditwindow.c
*
* Copyright 2005 Ian McIntosh
* ian_mcintosh at linuxadvocate.org
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include <glib-object.h>
#include "locationeditwindow.h"
#include "main.h"
#include "gui.h"
#include "util.h"
struct {
GtkWindow* m_pWindow;
GtkTreeView* m_pAttributeTreeView;
GtkListStore* m_pAttributeListStore;
GtkLabel* m_pCustomAttributesLabel;
GtkEntry* m_pLocationNameEntry;
GtkComboBox* m_pLocationSetComboBox;
GtkTextView* m_pLocationAddressTextView;
GtkExpander* m_pAttributeExpander;
GtkButton* m_pAttributeAddButton;
GtkButton* m_pAttributeRemoveButton;
GtkListStore* m_pAttributeNameListStore;
//
gint m_nEditingLocationID;
gboolean m_bModified;
} g_LocationEditWindow = {0};
#define ATTRIBUTELIST_COLUMN_NAME (0)
#define ATTRIBUTELIST_COLUMN_VALUE (1)
#define ATTRIBUTELIST_COLUMN_NAMELISTMODEL_COLUMN (2)
#define ATTRIBUTENAMELIST_COLUMN_NAME (0)
static void locationeditwindow_set_title();
//static void locationeditwindow_nameentry_insert_text(GtkEditable *pEditable, gchar *pszNewText, gint nNewTextLen, gint *pPosition, gpointer pUserData);
static void locationeditwindow_configure_attribute_list();
static void locationeditwindow_something_changed_callback(GtkEditable *_unused, gpointer __unused);
void locationeditwindow_show_for_new(gint nDefaultLocationSetID);
void locationeditwindow_show_for_edit(gint nLocationID);
// When an 'entry' is created to do in-place editing in a tree, we want to attach this "insert-text" hander to it.
static void callback_install_insert_text_callback_on_entry(GtkCellRenderer *pCellRenderer, GtkCellEditable *pEditable, const gchar *pszTreePath, gpointer pUserData)
{
if(GTK_IS_ENTRY(pEditable)) {
g_signal_connect(G_OBJECT(GTK_ENTRY(pEditable)), "insert-text", G_CALLBACK(pUserData), NULL);
}
else if(GTK_IS_COMBO_BOX_ENTRY(pEditable)) {
g_signal_connect(G_OBJECT(GTK_COMBO_BOX_ENTRY(pEditable)), "insert-text", G_CALLBACK(pUserData), NULL);
}
}
// Save the results of in-place cell editing
static void callback_store_attribute_editing(GtkCellRendererText *pCell, const gchar *pszTreePath, const gchar *pszNewValue, gpointer *pUserData)
{
gint nColumn = (gint)(pUserData);
GtkTreeIter iter;
GtkTreePath* pPath = gtk_tree_path_new_from_string(pszTreePath);
if(gtk_tree_model_get_iter(GTK_TREE_MODEL(g_LocationEditWindow.m_pAttributeListStore), &iter, pPath)) {
gtk_list_store_set(g_LocationEditWindow.m_pAttributeListStore, &iter, nColumn, pszNewValue, -1);
}
gtk_tree_path_free(pPath);
}
void locationeditwindow_init(GladeXML* pGladeXML)
{
// Widgets
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pWindow, GTK_WINDOW, "locationeditwindow");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pAttributeTreeView, GTK_TREE_VIEW, "locationattributestreeview");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pCustomAttributesLabel, GTK_LABEL, "customattributeslabel");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pLocationNameEntry, GTK_ENTRY, "locationnameentry");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pLocationSetComboBox, GTK_COMBO_BOX, "locationsetcombobox");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pLocationAddressTextView, GTK_TEXT_VIEW, "locationaddresstextview");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pAttributeExpander, GTK_EXPANDER, "attributeexpander");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pAttributeAddButton, GTK_BUTTON, "attributeaddbutton");
GLADE_LINK_WIDGET(pGladeXML, g_LocationEditWindow.m_pAttributeRemoveButton, GTK_BUTTON, "attributeremovebutton");
locationeditwindow_configure_attribute_list();
// Update window title with changed to 'name'
g_signal_connect(G_OBJECT(g_LocationEditWindow.m_pLocationNameEntry), "changed", G_CALLBACK(locationeditwindow_something_changed_callback), NULL);
g_signal_connect(G_OBJECT(g_LocationEditWindow.m_pLocationSetComboBox), "changed", G_CALLBACK(locationeditwindow_something_changed_callback), NULL);
// g_signal_connect(G_OBJECT(g_LocationEditWindow.m_pLocationAddressTextView), "changed", G_CALLBACK(locationeditwindow_something_changed_callback), NULL);
locationeditwindow_show_for_new(1); // XXX: debug
}
static void locationeditwindow_configure_attribute_list()
{
GtkCellRenderer* pCellRenderer;
GtkTreeViewColumn* pColumn;
GtkTreeIter iter;
// set up the location attributes list
g_LocationEditWindow.m_pAttributeListStore = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
gtk_tree_view_set_model(g_LocationEditWindow.m_pAttributeTreeView, GTK_TREE_MODEL(g_LocationEditWindow.m_pAttributeListStore));
g_LocationEditWindow.m_pAttributeNameListStore = gtk_list_store_new(1, G_TYPE_STRING);
gtk_list_store_append (g_LocationEditWindow.m_pAttributeNameListStore, &iter);
gtk_list_store_set (g_LocationEditWindow.m_pAttributeNameListStore, &iter, 0, "url", -1);
gtk_list_store_append (g_LocationEditWindow.m_pAttributeNameListStore, &iter);
gtk_list_store_set (g_LocationEditWindow.m_pAttributeNameListStore, &iter, 0, "phone", -1);
// NEW COLUMN: Editable "name" column (combobox-entry control)
pCellRenderer = gtk_cell_renderer_combo_new();
g_object_set(G_OBJECT(pCellRenderer),
"model", g_LocationEditWindow.m_pAttributeNameListStore,
"editable", TRUE,
NULL);
g_object_set(G_OBJECT(pCellRenderer),
"width-chars", 20,
NULL);
// add signals
// g_signal_connect(G_OBJECT(pCellRenderer),
// "editing-started", G_CALLBACK(callback_install_insert_text_callback_on_entry),
// locationeditwindow_nameentry_insert_text);
g_signal_connect(G_OBJECT(pCellRenderer),
"edited", G_CALLBACK(callback_store_attribute_editing),
ATTRIBUTELIST_COLUMN_NAME);
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(g_LocationEditWindow.m_pAttributeTreeView), -1, "Field", pCellRenderer,
"text", ATTRIBUTELIST_COLUMN_NAME,
"text-column", ATTRIBUTELIST_COLUMN_NAMELISTMODEL_COLUMN,
NULL);
// NEW COLUMN: Editable "value" column (text input)
pCellRenderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(pCellRenderer),
"editable", TRUE,
NULL);
// add signals
// g_signal_connect(G_OBJECT(pCellRenderer),
// "editing-started", G_CALLBACK(callback_install_insert_text_callback_on_entry),
// locationeditwindow_nameentry_insert_text);
g_signal_connect(G_OBJECT(pCellRenderer),
"edited", G_CALLBACK(callback_store_attribute_editing),
(gpointer)ATTRIBUTELIST_COLUMN_VALUE);
pColumn = gtk_tree_view_column_new_with_attributes("Value", pCellRenderer,
"text", ATTRIBUTELIST_COLUMN_VALUE,
NULL);
gtk_tree_view_append_column(g_LocationEditWindow.m_pAttributeTreeView, pColumn);
// Add test data
gtk_list_store_append(g_LocationEditWindow.m_pAttributeListStore, &iter);
gtk_list_store_set(g_LocationEditWindow.m_pAttributeListStore, &iter,
ATTRIBUTELIST_COLUMN_NAME, "phone", ATTRIBUTELIST_COLUMN_VALUE, "(617) 555-3314",
ATTRIBUTELIST_COLUMN_NAMELISTMODEL_COLUMN, ATTRIBUTENAMELIST_COLUMN_NAME,
-1);
gtk_list_store_append(g_LocationEditWindow.m_pAttributeListStore, &iter);
gtk_list_store_set(g_LocationEditWindow.m_pAttributeListStore, &iter,
ATTRIBUTELIST_COLUMN_NAME, "url", ATTRIBUTELIST_COLUMN_VALUE, "http://www.fusionrestaurant.com",
ATTRIBUTELIST_COLUMN_NAMELISTMODEL_COLUMN, ATTRIBUTENAMELIST_COLUMN_NAME,
-1);
}
void locationeditwindow_show_for_new(gint nDefaultLocationSetID)
{
// Set controls to default values
gtk_entry_set_text(g_LocationEditWindow.m_pLocationNameEntry, "");
gtk_text_buffer_set_text(gtk_text_view_get_buffer(g_LocationEditWindow.m_pLocationAddressTextView), "", -1);
gtk_combo_box_set_active(g_LocationEditWindow.m_pLocationSetComboBox, nDefaultLocationSetID);
gtk_expander_set_expanded(g_LocationEditWindow.m_pAttributeExpander, FALSE);
g_LocationEditWindow.m_bModified = FALSE;
locationeditwindow_set_title();
gtk_widget_grab_focus(GTK_WIDGET(g_LocationEditWindow.m_pLocationNameEntry));
gtk_widget_show(GTK_WIDGET(g_LocationEditWindow.m_pWindow));
}
void locationeditwindow_show_for_edit(gint nLocationID)
{
// void location_load_attributes(gint nLocationID, GPtrArray* pAttributeArray);
g_LocationEditWindow.m_bModified = FALSE;
locationeditwindow_set_title();
}
static void locationeditwindow_set_title()
{
const gchar* pszNameValue = gtk_entry_get_text(g_LocationEditWindow.m_pLocationNameEntry); // note: pointer to internal memory
gchar* pszNewName;
if(pszNameValue[0] == '\0') {
pszNewName = g_strdup_printf("%sunnamed POI", (g_LocationEditWindow.m_bModified) ? "*" : "");
}
else {
pszNewName = g_strdup_printf("%s%s", (g_LocationEditWindow.m_bModified) ? "*" : "", pszNameValue);
}
gtk_window_set_title(g_LocationEditWindow.m_pWindow, pszNewName);
g_free(pszNewName);
}
// Widget Callbacks
static void locationeditwindow_something_changed_callback(GtkEditable *_unused, gpointer __unused)
{
g_LocationEditWindow.m_bModified = TRUE;
locationeditwindow_set_title();
}
// static void locationeditwindow_nameentry_insert_text(GtkEditable *pEditable, gchar *pszNewText, gint nNewTextLen, gint *pPosition, gpointer pUserData)
// {
// g_print("nNewTextLen=%d\n", nNewTextLen);
//
// int i;
// gchar *pszReplacement = g_utf8_strdown(pszNewText, nNewTextLen);
//
// g_signal_handlers_block_by_func(GTK_OBJECT(pEditable),
// GTK_SIGNAL_FUNC(locationeditwindow_nameentry_insert_text),
// pUserData);
// gtk_editable_insert_text(pEditable, pszReplacement, nNewTextLen, pPosition);
// g_signal_handlers_unblock_by_func(GTK_OBJECT(pEditable),
// GTK_SIGNAL_FUNC(locationeditwindow_nameentry_insert_text),
// pUserData);
//
// gtk_signal_emit_stop_by_name(GTK_OBJECT(pEditable), "insert_text");
//
// g_free(pszReplacement);
// }
--- NEW FILE: locationeditwindow.h ---
/***************************************************************************
* locationeditwindow.h
*
* Copyright 2005 Ian McIntosh
* ian_mcintosh at linuxadvocate.org
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _LOCATIONEDITWINDOW_H
#define _LOCATIONEDITWINDOW_H
#include <glade/glade.h>
#include "map.h"
G_BEGIN_DECLS
void locationeditwindow_init(GladeXML* pGladeXML);
G_END_DECLS
#endif
Index: locationset.c
===================================================================
RCS file: /cvs/cairo/roadster/src/locationset.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- locationset.c 23 Apr 2005 18:13:39 -0000 1.11
+++ locationset.c 14 Sep 2005 20:06:54 -0000 1.12
@@ -54,7 +54,7 @@
// get a new locationset struct from the allocator
static gboolean locationset_alloc(locationset_t** ppReturn)
{
- g_return_val_if_fail(g_LocationSet.m_pLocationSetChunkAllocator != NULL, NULL);
+ g_return_val_if_fail(g_LocationSet.m_pLocationSetChunkAllocator != NULL, FALSE);
locationset_t* pNew = g_mem_chunk_alloc0(g_LocationSet.m_pLocationSetChunkAllocator);
Index: main.c
===================================================================
RCS file: /cvs/cairo/roadster/src/main.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- main.c 28 Aug 2005 22:23:14 -0000 1.22
+++ main.c 14 Sep 2005 20:06:54 -0000 1.23
@@ -32,7 +32,6 @@
#include "map.h"
#include "gpsclient.h"
#include "scenemanager.h"
-#include "prefs.h"
#include "animator.h"
#include "road.h"
#include "locationset.h"
@@ -76,8 +75,6 @@
location_insert_attribute(nNewLocationID, LOCATION_ATTRIBUTE_ID_NAME, "1369 Coffee House", NULL);
location_insert_attribute(nNewLocationID, LOCATION_ATTRIBUTE_ID_ADDRESS, "757 Massachusetts Avenue\nCambridge, MA 02139", NULL);
*/
- prefs_read();
-
g_print("Running %s\n", g_thread_supported() ? "multi-threaded" : "single-threaded");
gui_run();
@@ -98,9 +95,6 @@
gnome_vfs_make_directory(pszApplicationDir, 0700);
g_free(pszApplicationDir);
#endif
- g_print("initializing prefs\n");
- prefs_init(); // note: doesn't READ prefs yet
-
g_print("initializing points\n");
point_init();
g_print("initializing pointstrings\n");
@@ -111,8 +105,8 @@
g_print("initializing tracks\n");
track_init();
- g_print("initializing layers\n");
- layers_init();
+ g_print("initializing map styles\n");
+ map_style_init();
g_print("initializing glyphs\n");
glyph_init();
g_print("initializing map\n");
Index: main.h
===================================================================
RCS file: /cvs/cairo/roadster/src/main.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- main.h 31 Mar 2005 08:29:53 -0000 1.2
+++ main.h 14 Sep 2005 20:06:54 -0000 1.3
@@ -21,7 +21,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+#include <gtk/gtk.h>
+
#define USE_GNOME_VFS // comment this out to get a faster single-threaded compile (can't import, though)
-//#define ENABLE_TIMING
#define USE_GFREELIST
+//#define ENABLE_TIMING
+
+typedef struct color {
+ gfloat m_fRed;
+ gfloat m_fGreen;
+ gfloat m_fBlue;
+ gfloat m_fAlpha;
+} color_t;
+
+#endif
+
Index: mainwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/mainwindow.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- mainwindow.c 6 Sep 2005 02:44:19 -0000 1.39
+++ mainwindow.c 14 Sep 2005 20:06:54 -0000 1.40
@@ -39,7 +39,7 @@
#include "gotowindow.h"
#include "db.h"
#include "map.h"
-#include "layers.h"
+#include "map_style.h"
#include "importwindow.h"
#include "welcomewindow.h"
#include "locationset.h"
@@ -55,17 +55,19 @@
#define PROGRAM_DESCRIPTION "Mapping for everyone!"
#define WEBSITE_URL "http://linuxadvocate.org/projects/roadster"
+#define MAP_STYLE_FILENAME ("layers.xml")
+
// how long after stopping various movements should we redraw in high-quality mode
#define DRAW_PRETTY_SCROLL_TIMEOUT_MS (110) // NOTE: should be longer than the SCROLL_TIMEOUT_MS below!!
#define DRAW_PRETTY_ZOOM_TIMEOUT_MS (180)
#define DRAW_PRETTY_DRAG_TIMEOUT_MS (250)
#define DRAW_PRETTY_RESIZE_TIMEOUT_MS (180)
-#define SCROLL_TIMEOUT_MS (80) // how often (in MS) to move
-#define SCROLL_DISTANCE_IN_PIXELS (100) // how far to move every (above) MS
+#define SCROLL_TIMEOUT_MS (70) // how often (in MS) to move
+#define SCROLL_DISTANCE_IN_PIXELS (60) // how far to move every (above) MS
#define BORDER_SCROLL_CLICK_TARGET_SIZE (16) // the size of the click target (distance from edge of map view) to begin scrolling
-#define SLIDE_TIMEOUT_MS (50) // time between frames (in MS) for smooth-sliding (on double click?)
+#define SLIDE_TIMEOUT_MS (50) // time between frames (in MS) for smooth-sliding on double click
#define SLIDE_TIME_IN_SECONDS (0.4) // how long the whole slide should take, in seconds
#define SLIDE_TIME_IN_SECONDS_AUTO (0.8) // time for sliding to search results, etc.
@@ -75,21 +77,21 @@
// Locationset columns
#define LOCATIONSETLIST_COLUMN_ENABLED (0)
-#define LOCATIONSETLIST_COLUMN_NAME (1)
-#define LOCATIONSETLIST_COLUMN_ID (2)
+#define LOCATIONSETLIST_COLUMN_NAME (1)
+#define LOCATIONSETLIST_COLUMN_ID (2)
-//
-#define MOUSE_BUTTON_LEFT (1)
-#define MOUSE_BUTTON_RIGHT (3)
+//
+#define MOUSE_BUTTON_LEFT (1)
+#define MOUSE_BUTTON_RIGHT (3)
// Limits
-#define MAX_SEARCH_TEXT_LENGTH (100)
-#define SPEED_LABEL_FORMAT ("<span font_desc='32'>%.0f</span>")
+#define MAX_SEARCH_TEXT_LENGTH (100)
+#define SPEED_LABEL_FORMAT ("<span font_desc='32'>%.0f</span>")
-#define TOOLTIP_FORMAT ("%s")
+#define TOOLTIP_FORMAT ("%s")
-#define ROAD_TOOLTIP_BG_COLOR 65535, 65535, 39000
-#define LOCATION_TOOLTIP_BG_COLOR 52800, 60395, 65535
+#define ROAD_TOOLTIP_BG_COLOR 65535, 65535, 39000
+#define LOCATION_TOOLTIP_BG_COLOR 52800, 60395, 65535
// Settings
#define TIMER_GPS_REDRAW_INTERVAL_MS (2500) // lower this (to 1000?) when it's faster to redraw track
@@ -151,8 +153,8 @@
// Toolbar
GtkToolbar* m_pToolbar;
- GtkToolButton* m_pPointerToolButton;
- GtkToolButton* m_pZoomToolButton;
+// GtkToolButton* m_pPointerToolButton;
+// GtkToolButton* m_pZoomToolButton;
GtkHScale* m_pZoomScale;
GtkEntry* m_pSearchBox;
GtkImage* m_pStatusbarGPSIcon;
@@ -201,9 +203,10 @@
gboolean m_bScrolling;
EDirection m_eScrollDirection;
gboolean m_bScrollMovement;
-
+
gboolean m_bMouseDragging;
gboolean m_bMouseDragMovement;
+
screenpoint_t m_ptClickLocation;
gint m_nCurrentGPSPath;
@@ -234,7 +237,7 @@
void cursor_init()
{
int i;
- for(i=0 ; i<NUM_ELEMS(g_Tools) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(g_Tools) ; i++) {
g_Tools[i].m_Cursor.m_pGdkCursor = gdk_cursor_new(g_Tools[i].m_Cursor.m_CursorType);
}
}
@@ -291,8 +294,8 @@
// Widgets
g_MainWindow.m_pWindow = GTK_WINDOW(glade_xml_get_widget(pGladeXML, "mainwindow")); g_return_if_fail(g_MainWindow.m_pWindow != NULL);
g_MainWindow.m_pMapPopupMenu = GTK_MENU(glade_xml_get_widget(pGladeXML, "mappopupmenu")); g_return_if_fail(g_MainWindow.m_pMapPopupMenu != NULL);
- g_MainWindow.m_pPointerToolButton = GTK_TOOL_BUTTON(glade_xml_get_widget(pGladeXML, "pointertoolbutton")); g_return_if_fail(g_MainWindow.m_pPointerToolButton != NULL);
- g_MainWindow.m_pZoomToolButton = GTK_TOOL_BUTTON(glade_xml_get_widget(pGladeXML, "zoomtoolbutton")); g_return_if_fail(g_MainWindow.m_pZoomToolButton != NULL);
+// g_MainWindow.m_pPointerToolButton = GTK_TOOL_BUTTON(glade_xml_get_widget(pGladeXML, "pointertoolbutton")); g_return_if_fail(g_MainWindow.m_pPointerToolButton != NULL);
+// g_MainWindow.m_pZoomToolButton = GTK_TOOL_BUTTON(glade_xml_get_widget(pGladeXML, "zoomtoolbutton")); g_return_if_fail(g_MainWindow.m_pZoomToolButton != NULL);
g_MainWindow.m_pZoomInButton = GTK_BUTTON(glade_xml_get_widget(pGladeXML, "zoominbutton")); g_return_if_fail(g_MainWindow.m_pZoomInButton != NULL);
g_MainWindow.m_pZoomInMenuItem = GTK_MENU_ITEM(glade_xml_get_widget(pGladeXML, "zoominmenuitem")); g_return_if_fail(g_MainWindow.m_pZoomInMenuItem != NULL);
@@ -335,8 +338,9 @@
g_MainWindow.m_pDrawingArea = GTK_DRAWING_AREA(gtk_drawing_area_new());
g_MainWindow.m_pTooltip = tooltip_new();
- // create map
+ // create map and load style
map_new(&g_MainWindow.m_pMap, GTK_WIDGET(g_MainWindow.m_pDrawingArea));
+ map_style_load(g_MainWindow.m_pMap, MAP_STYLE_FILENAME);
// add signal handlers to drawing area
gtk_widget_add_events(GTK_WIDGET(g_MainWindow.m_pDrawingArea), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
@@ -468,8 +472,13 @@
//
gboolean mainwindow_on_draw_pretty_timeout(gpointer _unused)
{
- g_MainWindow.m_nDrawPrettyTimeoutID = 0;
mainwindow_draw_map(DRAWFLAG_ALL);
+
+ // We've just drawn a complete frame, so we can consider this a new drag with no movement yet
+ g_MainWindow.m_bMouseDragMovement = FALSE; // NOTE: may have already been FALSE, for example if we're not dragging... :)
+
+ // Returning FALSE from the timeout callback kills the timer.
+ g_MainWindow.m_nDrawPrettyTimeoutID = 0;
return FALSE;
}
@@ -793,7 +802,7 @@
void mainwindow_on_reloadstylesmenuitem_activate(GtkMenuItem *menuitem, gpointer user_data)
{
- layers_reload();
+ map_style_load(g_MainWindow.m_pMap, MAP_STYLE_FILENAME);
mainwindow_draw_map(DRAWFLAG_ALL);
}
@@ -1013,16 +1022,15 @@
static gboolean mainwindow_on_mouse_motion(GtkWidget* w, GdkEventMotion *event)
{
- gint nX,nY;
+ gint nX,nY;
+ // XXX: why do we do this?
if (event->is_hint) {
gdk_window_get_pointer(w->window, &nX, &nY, NULL);
}
- else
- {
+ else {
nX = event->x;
nY = event->y;
- //nState = event->state;
}
gint nWidth = GTK_WIDGET(g_MainWindow.m_pDrawingArea)->allocation.width;
@@ -1054,18 +1062,18 @@
EDirection eScrollDirection = match_border(nX, nY, nWidth, nHeight, BORDER_SCROLL_CLICK_TARGET_SIZE);
- if(g_MainWindow.m_eScrollDirection != eScrollDirection) {
- // update cursor
- nCursor = g_aDirectionCursors[eScrollDirection].m_nCursor;
+ // update cursor
+ nCursor = g_aDirectionCursors[eScrollDirection].m_nCursor;
- // update direction if actively scrolling
- g_MainWindow.m_eScrollDirection = eScrollDirection;
+ // update direction if actively scrolling
+ g_MainWindow.m_eScrollDirection = eScrollDirection;
+// if(g_MainWindow.m_eScrollDirection != eScrollDirection) {
//GdkCursor* pCursor = gdk_cursor_new(g_aDirectionCursors[eScrollDirection].m_nCursor);
//gdk_pointer_ungrab(GDK_CURRENT_TIME);
//gdk_pointer_grab(GTK_WIDGET(g_MainWindow.m_pDrawingArea)->window, FALSE, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, NULL, pCursor, GDK_CURRENT_TIME);
//gdk_cursor_unref(pCursor);
- }
+// }
}
else {
// If not dragging or scrolling, user is just moving mouse around.
@@ -1214,12 +1222,12 @@
static void mainwindow_setup_selected_tool(void)
{
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.m_pPointerToolButton))) {
- gui_set_tool(kToolPointer);
- }
- else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.m_pZoomToolButton))) {
- gui_set_tool(kToolZoom);
- }
+// if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.m_pPointerToolButton))) {
+// gui_set_tool(kToolPointer);
+// }
+// else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(g_MainWindow.m_pZoomToolButton))) {
+// gui_set_tool(kToolZoom);
+// }
}
// One handler for all 'tools' buttons
@@ -1231,7 +1239,7 @@
void mainwindow_draw_map(gint nDrawFlags)
{
- map_draw(g_MainWindow.m_pMap, nDrawFlags);
+ map_draw(g_MainWindow.m_pMap, g_MainWindow.m_pMap->m_pPixmap, nDrawFlags);
// push it to screen
GdkPixmap* pMapPixmap = map_get_pixmap(g_MainWindow.m_pMap);
@@ -1275,8 +1283,7 @@
/*
** GPS Functions
-*/
-
+*/
gboolean mainwindow_on_gps_show_position_toggled(GtkWidget* _unused, gpointer* __unused)
{
@@ -1341,9 +1348,14 @@
// unless we're "LIVE", set signal strength to 0
gtk_progress_bar_set_fraction(g_MainWindow.m_pGPSSignalStrengthProgressBar, 0.0);
- if(pData->m_eStatus == GPS_STATUS_NO_SIGNAL) {
+ if(pData->m_eStatus == GPS_STATUS_NO_GPS_COMPILED_IN) {
+ util_set_image_to_stock(g_MainWindow.m_pStatusbarGPSIcon, GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU);
+
+ gtk_tooltips_set_tip(GTK_TOOLTIPS(g_MainWindow.m_pTooltips), pWidget,
+ "GPS support was not enabled at compile time", "");
+ }
+ else if(pData->m_eStatus == GPS_STATUS_NO_SIGNAL) {
// do NOT set speed to 0 if we drop the signal temporarily...
-
util_set_image_to_stock(g_MainWindow.m_pStatusbarGPSIcon, GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU);
gtk_tooltips_set_tip(GTK_TOOLTIPS(g_MainWindow.m_pTooltips), pWidget,
@@ -1404,7 +1416,7 @@
mainwindow_map_center_on_mappoint(&ptNew);
if(bDone) {
// when done, draw a full frame
- mainwindow_draw_map(DRAWFLAG_GEOMETRY);
+ //mainwindow_draw_map(DRAWFLAG_GEOMETRY);
mainwindow_draw_map(DRAWFLAG_ALL);
}
else {
Index: map.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- map.c 6 Sep 2005 02:44:19 -0000 1.43
+++ map.c 14 Sep 2005 20:06:54 -0000 1.44
@@ -27,6 +27,7 @@
#include <math.h>
#include "main.h"
+#include "map_style.h"
#include "gui.h"
#include "map.h"
#include "mainwindow.h"
@@ -34,14 +35,13 @@
#include "db.h"
#include "road.h"
#include "point.h"
-#include "layers.h"
#include "locationset.h"
#include "location.h"
#include "scenemanager.h"
#define ENABLE_RIVER_TO_LAKE_LOADTIME_HACK // change circular rivers to lakes when loading from disk
//#define ENABLE_SCENEMANAGER_DEBUG_TEST
-#define ENABLE_LABELS_WHILE_DRAGGING
+//#define ENABLE_LABELS_WHILE_DRAGGING
#ifdef THREADED_RENDERING
#define RENDERING_THREAD_YIELD g_thread_yield()
@@ -96,14 +96,14 @@
// { 200000, ""},
// { 100000, ""},
- { 100000, UNIT_MILES, 2, UNIT_KILOMETERS, 2, "", }, // 1
- { 48000, UNIT_MILES, 1, UNIT_KILOMETERS, 1, "", }, // 2
+ { 80000, UNIT_MILES, 2, UNIT_KILOMETERS, 2, "", }, // 1
+ { 40000, UNIT_MILES, 1, UNIT_KILOMETERS, 1, "", }, // 2
{ 20000, UNIT_FEET, 2000, UNIT_METERS, 400, "", }, // 3
{ 10000, UNIT_FEET, 1000, UNIT_METERS, 200, "", }, // 4
{ 5000, UNIT_FEET, 500, UNIT_METERS, 100, "", }, // 5
};
-gchar* g_apszMapObjectTypeNames[] = {
+gchar* g_apszMapObjectTypeNames[] = { // XXX: would be nice to remove this. although we *do* need to maintain a link between imported data and styles
"",
"minor-roads",
"major-roads",
@@ -115,7 +115,8 @@
"parks",
"rivers",
"lakes",
- "misc-areas"
+ "misc-areas",
+ "urban-areas",
};
// ========================================================
@@ -127,27 +128,6 @@
{
}
-void map_callback_free_locations_array(gpointer* p)
-{
- GPtrArray* pLocationsArray = (GPtrArray*)p;
- gint i;
- for(i=(pLocationsArray->len-1) ; i>=0 ;i--) {
- location_t* pLocation = g_ptr_array_remove_index_fast(pLocationsArray, i);
- location_free(pLocation);
- }
-}
-
-static void map_init_location_hash(map_t* pMap)
-{
- // destroy it if it exists... it will call map_callback_free_locations_array() on all children and g_free on all keys (see below)
- if(pMap->m_pLocationArrayHashTable != NULL) {
- g_hash_table_destroy(pMap->m_pLocationArrayHashTable);
- }
- pMap->m_pLocationArrayHashTable = g_hash_table_new_full(g_int_hash, g_int_equal,
- g_free, /* key destroy function */
- map_callback_free_locations_array); /* value destroy function */
-}
-
gboolean map_new(map_t** ppMap, GtkWidget* pTargetWidget)
{
g_assert(ppMap != NULL);
@@ -172,7 +152,7 @@
// init containers for geometry data
gint i;
- for(i=0 ; i<NUM_ELEMS(pMap->m_apLayerData) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(pMap->m_apLayerData) ; i++) {
maplayer_data_t* pLayer = g_new0(maplayer_data_t, 1);
pLayer->m_pRoadsArray = g_ptr_array_new();
pMap->m_apLayerData[i] = pLayer;
@@ -187,32 +167,7 @@
return TRUE;
}
-static void map_store_location(map_t* pMap, location_t* pLocation, gint nLocationSetID)
-{
- GPtrArray* pLocationsArray;
- pLocationsArray = g_hash_table_lookup(pMap->m_pLocationArrayHashTable, &nLocationSetID);
- if(pLocationsArray != NULL) {
- // found existing array
- //g_print("existing for set %d\n", nLocationSetID);
- }
- else {
- //g_print("new for set %d\n", nLocationSetID);
-
- // need a new array
- pLocationsArray = g_ptr_array_new();
- g_assert(pLocationsArray != NULL);
-
- gint* pKey = g_malloc(sizeof(gint));
- *pKey = nLocationSetID;
- g_hash_table_insert(pMap->m_pLocationArrayHashTable, pKey, pLocationsArray);
- }
-
- // add location to the array of locations!
- g_ptr_array_add(pLocationsArray, pLocation);
- //g_print("pLocationsArray->len = %d\n", pLocationsArray->len);
-}
-
-void map_draw(map_t* pMap, gint nDrawFlags)
+void map_draw(map_t* pMap, GdkPixmap* pTargetPixmap, gint nDrawFlags)
{
g_assert(pMap != NULL);
@@ -230,7 +185,7 @@
scenemanager_clear(pMap->m_pSceneManager);
scenemanager_set_screen_dimensions(pMap->m_pSceneManager, pRenderMetrics->m_nWindowWidth, pRenderMetrics->m_nWindowHeight);
- gint nRenderMode = RENDERMODE_FAST; // RENDERMODE_PRETTY
+ gint nRenderMode = RENDERMODE_FAST; //RENDERMODE_FAST; // RENDERMODE_PRETTY
#ifdef ENABLE_LABELS_WHILE_DRAGGING
nDrawFlags |= DRAWFLAG_LABELS; // always turn on labels
@@ -244,20 +199,19 @@
if(nRenderMode == RENDERMODE_FAST) {
//
if(nDrawFlags & DRAWFLAG_GEOMETRY) {
- map_draw_gdk(pMap, pRenderMetrics, pMap->m_pPixmap, DRAWFLAG_GEOMETRY);
- }
-
- // Always draw labels with Cairo
- if(nDrawFlags & DRAWFLAG_LABELS) {
- map_draw_cairo(pMap, pRenderMetrics, pMap->m_pPixmap, DRAWFLAG_LABELS);
+ map_draw_gdk(pMap, pRenderMetrics, pTargetPixmap, DRAWFLAG_GEOMETRY);
+ nDrawFlags &= ~DRAWFLAG_GEOMETRY;
}
+
+ // Call cairo for finishing the scene
+ map_draw_cairo(pMap, pRenderMetrics, pTargetPixmap, nDrawFlags);
}
else { // nRenderMode == RENDERMODE_PRETTY
- map_draw_cairo(pMap, pRenderMetrics, pMap->m_pPixmap, nDrawFlags);
+ map_draw_cairo(pMap, pRenderMetrics, pTargetPixmap, nDrawFlags);
}
#ifdef ENABLE_SCENEMANAGER_DEBUG_TEST
- gdk_draw_polygon(pMap->m_pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+ gdk_draw_polygon(pTargetPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
FALSE, aPoints, 4);
#endif
@@ -278,7 +232,6 @@
// nothing since we're not using mutexes
}
-
// ========================================================
// Get/Set Functions
// ========================================================
@@ -294,16 +247,26 @@
}
}
-guint16 map_get_zoomlevel(map_t* pMap)
+guint16 map_get_zoomlevel(const map_t* pMap)
{
return pMap->m_uZoomLevel; // between MIN_ZOOM_LEVEL and MAX_ZOOM_LEVEL
}
-guint32 map_get_zoomlevel_scale(map_t* pMap)
+guint32 map_get_zoomlevel_scale(const map_t* pMap)
{
return g_sZoomLevels[pMap->m_uZoomLevel].m_uScale; // returns "5000" for 1:5000 scale
}
+gboolean map_can_zoom_in(const map_t* pMap)
+{
+ // can we increase zoom level?
+ return (pMap->m_uZoomLevel < MAX_ZOOM_LEVEL);
+}
+gboolean map_can_zoom_out(const map_t* pMap)
+{
+ return (pMap->m_uZoomLevel > MIN_ZOOM_LEVEL);
+}
+
// ========================================================
// Coordinate Conversion Functions
// ========================================================
@@ -335,7 +298,7 @@
// convert pixels to a span of degrees
double map_pixels_to_degrees(map_t* pMap, gint16 nPixels, guint16 uZoomLevel)
{
- double fMonitorPixelsPerInch = 85 + 1/3;
+ double fMonitorPixelsPerInch = 85.333; // XXX: don't hardcode this
double fPixelsPerMeter = fMonitorPixelsPerInch * INCHES_PER_METER;
double fMetersOfPixels = ((float)nPixels) / fPixelsPerMeter;
@@ -348,7 +311,7 @@
double map_degrees_to_pixels(map_t* pMap, gdouble fDegrees, guint16 uZoomLevel)
{
- double fMonitorPixelsPerInch = 85 + 1/3;
+ double fMonitorPixelsPerInch = 85.333; // XXX: don't hardcode this
double fResultInMeters = WORLD_DEGREES_TO_METERS(fDegrees);
double fResultInPixels = (INCHES_PER_METER * fResultInMeters) * fMonitorPixelsPerInch;
@@ -398,7 +361,7 @@
// map_set_redraw_needed(TRUE);
}
-void map_get_centerpoint(map_t* pMap, mappoint_t* pReturnPoint)
+void map_get_centerpoint(const map_t* pMap, mappoint_t* pReturnPoint)
{
g_assert(pReturnPoint != NULL);
@@ -414,6 +377,9 @@
pMap->m_MapDimensions.m_uWidth = pDimensions->m_uWidth;
pMap->m_MapDimensions.m_uHeight = pDimensions->m_uHeight;
+ // XXX: free old pixmap?
+ //g_assert(pMap->m_pPixmap == NULL);
+
pMap->m_pPixmap = gdk_pixmap_new(
pMap->m_pTargetWidget->window,
pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight,
@@ -585,10 +551,11 @@
// Get layer type that this belongs on
gint nTypeID = atoi(aRow[1]);
if(nTypeID < MAP_OBJECT_TYPE_FIRST || nTypeID > MAP_OBJECT_TYPE_LAST) {
- //g_warning("geometry record '%s' has bad type '%s'\n", aRow[0], aRow[1]);
+ g_warning("geometry record '%s' has bad type '%s'\n", aRow[0], aRow[1]);
continue;
}
+ if(nTypeID == 12) g_warning("(got a 12)");
// Extract points
road_t* pNewRoad = NULL;
road_alloc(&pNewRoad);
@@ -724,7 +691,7 @@
{
// Clear layers
gint i,j;
- for(i=0 ; i<NUM_ELEMS(pMap->m_apLayerData) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(pMap->m_apLayerData) ; i++) {
maplayer_data_t* pLayerData = pMap->m_apLayerData[i];
// Free each
@@ -827,7 +794,7 @@
// Test things in the REVERSE order they are drawn (otherwise we'll match things that have been painted-over)
gint i;
- for(i=NUM_ELEMS(layerdraworder)-1 ; i>=0 ; i--) {
+ for(i=G_N_ELEMENTS(layerdraworder)-1 ; i>=0 ; i--) {
if(layerdraworder[i].eSubLayerRenderType != SUBLAYER_RENDERTYPE_LINES) continue;
gint nLayer = layerdraworder[i].nLayer;
@@ -1181,20 +1148,96 @@
return FALSE;
}
-gboolean map_can_zoom_in(map_t* pMap)
+
+// Get an attribute from a selected location
+const gchar* map_location_selection_get_attribute(const map_t* pMap, const locationselection_t* pLocationSelection, const gchar* pszAttributeName)
{
- // can we increase zoom level?
- return (pMap->m_uZoomLevel < MAX_ZOOM_LEVEL);
+ // NOTE: always gets the 'first' one. this is only used for the few hardcoded attributes (name, address, ...)
+ gint i;
+ for(i=0 ; i<pLocationSelection->m_pAttributesArray->len ; i++) {
+ locationattribute_t* pAttribute = g_ptr_array_index(pLocationSelection->m_pAttributesArray, i);
+ if(strcmp(pAttribute->m_pszName, pszAttributeName) == 0) {
+ return pAttribute->m_pszValue;
+ }
+ }
+ return NULL;
}
-gboolean map_can_zoom_out(map_t* pMap)
+
+gboolean map_object_type_atoi(const gchar* pszName, gint* pnReturnObjectTypeID)
{
- return (pMap->m_uZoomLevel > MIN_ZOOM_LEVEL);
+ gint i;
+ for(i=0 ; i<MAP_NUM_OBJECT_TYPES ; i++) {
+ if(strcmp(pszName, g_apszMapObjectTypeNames[i]) == 0) {
+ *pnReturnObjectTypeID = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
}
+gboolean map_layer_render_type_atoi(const gchar* pszName, gint* pnReturnRenderTypeID)
+{
+ gchar* g_apszMapRenderTypeNames[] = {"lines", "polygons", "line-labels", "polygon-labels", "fill"};
-//
-// Map selected POI
-//
+ gint i;
+ for(i=0 ; i<G_N_ELEMENTS(g_apszMapRenderTypeNames) ; i++) {
+ if(strcmp(pszName, g_apszMapRenderTypeNames[i]) == 0) {
+ *pnReturnRenderTypeID = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void map_callback_free_locations_array(gpointer* p)
+{
+ GPtrArray* pLocationsArray = (GPtrArray*)p;
+ gint i;
+ for(i=(pLocationsArray->len-1) ; i>=0 ;i--) {
+ location_t* pLocation = g_ptr_array_remove_index_fast(pLocationsArray, i);
+ location_free(pLocation);
+ }
+}
+
+static void map_init_location_hash(map_t* pMap)
+{
+ // destroy it if it exists... it will call map_callback_free_locations_array() on all children and g_free on all keys (see below)
+ if(pMap->m_pLocationArrayHashTable != NULL) {
+ g_hash_table_destroy(pMap->m_pLocationArrayHashTable);
+ }
+ pMap->m_pLocationArrayHashTable = g_hash_table_new_full(g_int_hash, g_int_equal,
+ g_free, /* key destroy function */
+ map_callback_free_locations_array); /* value destroy function */
+}
+
+static void map_store_location(map_t* pMap, location_t* pLocation, gint nLocationSetID)
+{
+ GPtrArray* pLocationsArray;
+ pLocationsArray = g_hash_table_lookup(pMap->m_pLocationArrayHashTable, &nLocationSetID);
+ if(pLocationsArray != NULL) {
+ // found existing array
+ //g_print("existing for set %d\n", nLocationSetID);
+ }
+ else {
+ //g_print("new for set %d\n", nLocationSetID);
+
+ // need a new array
+ pLocationsArray = g_ptr_array_new();
+ g_assert(pLocationsArray != NULL);
+
+ gint* pKey = g_malloc(sizeof(gint));
+ *pKey = nLocationSetID;
+ g_hash_table_insert(pMap->m_pLocationArrayHashTable, pKey, pLocationsArray);
+ }
+
+ // add location to the array of locations!
+ g_ptr_array_add(pLocationsArray, pLocation);
+ //g_print("pLocationsArray->len = %d\n", pLocationsArray->len);
+}
+
+// ========================================================
+// Functions to deal with "selected" locations (POI), which are always kept in RAM
+// ========================================================
// lookup a selected location by ID
locationselection_t* map_location_selection_get(map_t* pMap, gint nLocationID)
@@ -1208,7 +1251,7 @@
return NULL;
}
-gint map_location_selection_sort_callback(gconstpointer ppA, gconstpointer ppB)
+gint map_location_selection_latitude_sort_callback(gconstpointer ppA, gconstpointer ppB)
{
locationselection_t* pA = *((locationselection_t**)ppA);
locationselection_t* pB = *((locationselection_t**)ppB);
@@ -1237,12 +1280,14 @@
g_ptr_array_add(pMap->m_pLocationSelectionArray, pNew);
- g_ptr_array_sort(pMap->m_pLocationSelectionArray, map_location_selection_sort_callback);
+ // sort in order of latitude
+ // POI that seem "closer" to the user (lower on the screen) will be drawn last (on top)
+ g_ptr_array_sort(pMap->m_pLocationSelectionArray, map_location_selection_latitude_sort_callback);
return TRUE; // added
}
-// add a Location to the selected list
+// remove a Location to the selected list
gboolean map_location_selection_remove(map_t* pMap, gint nLocationID)
{
gint i;
@@ -1255,42 +1300,3 @@
}
return FALSE; // removed
}
-
-// get an attribute from a selected location
-const gchar* map_location_selection_get_attribute(const map_t* pMap, const locationselection_t* pLocationSelection, const gchar* pszAttributeName)
-{
- gint i;
- for(i=0 ; i<pLocationSelection->m_pAttributesArray->len ; i++) {
- locationattribute_t* pAttribute = g_ptr_array_index(pLocationSelection->m_pAttributesArray, i);
- if(strcmp(pAttribute->m_pszName, pszAttributeName) == 0) {
- return pAttribute->m_pszValue;
- }
- }
- return NULL;
-}
-
-gboolean map_object_type_atoi(const gchar* pszName, gint* pnReturnObjectTypeID)
-{
- gint i;
- for(i=0 ; i<MAP_NUM_OBJECT_TYPES ; i++) {
- if(strcmp(pszName, g_apszMapObjectTypeNames[i]) == 0) {
- *pnReturnObjectTypeID = i;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-gboolean map_layer_render_type_atoi(const gchar* pszName, gint* pnReturnRenderTypeID)
-{
- gchar* g_apszMapRenderTypeNames[] = {"lines", "polygons", "line-labels", "polygon-labels"};
-
- gint i;
- for(i=0 ; i<G_N_ELEMENTS(g_apszMapRenderTypeNames) ; i++) {
- if(strcmp(pszName, g_apszMapRenderTypeNames[i]) == 0) {
- *pnReturnRenderTypeID = i;
- return TRUE;
- }
- }
- return FALSE;
-}
Index: map.h
===================================================================
RCS file: /cvs/cairo/roadster/src/map.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- map.h 6 Sep 2005 02:44:19 -0000 1.20
+++ map.h 14 Sep 2005 20:06:54 -0000 1.21
@@ -41,11 +41,12 @@
#define MAP_OBJECT_TYPE_RIVER (9)
#define MAP_OBJECT_TYPE_LAKE (10)
#define MAP_OBJECT_TYPE_MISC_AREA (11)
+#define MAP_OBJECT_TYPE_URBAN_AREA (12)
-#define MAP_NUM_OBJECT_TYPES (12)
+#define MAP_NUM_OBJECT_TYPES (13)
#define MAP_OBJECT_TYPE_FIRST (1)
-#define MAP_OBJECT_TYPE_LAST (11)
+#define MAP_OBJECT_TYPE_LAST (12)
//
// Line CAP styles
@@ -103,7 +104,6 @@
#define NUM_ZOOM_LEVELS (5)
#define MIN_ZOOM_LEVEL_FOR_LOCATIONS (6) // don't show POI above this level
-#include "layers.h"
#include "scenemanager.h"
// World space
@@ -202,9 +202,9 @@
GPtrArray *m_pLocationSelectionArray;
GFreeList *m_pLocationSelectionAllocator;
- // Mutex and the data it controls (always lock before reading/writing)
- //GMutex* m_pPixmapMutex;
GdkPixmap* m_pPixmap;
+
+ GPtrArray* m_pLayersArray;
} map_t;
typedef enum {
@@ -247,15 +247,14 @@
MAP_LAYER_RENDERTYPE_LINES,
MAP_LAYER_RENDERTYPE_POLYGONS,
MAP_LAYER_RENDERTYPE_LINE_LABELS,
- MAP_LAYER_RENDERTYPE_POLYGON_LABELS
+ MAP_LAYER_RENDERTYPE_POLYGON_LABELS,
+ MAP_LAYER_RENDERTYPE_FILL,
} EMapLayerRenderType;
typedef struct {
gint nLayer;
gint nSubLayer;
EMapLayerRenderType eSubLayerRenderType;
-
-// void (*pFunc)(map_t*, cairo_t*, rendermetrics_t*, GPtrArray*, sublayerstyle_t*, textlabelstyle_t*);
} draworder_t;
#define MAX_LOCATIONSELECTION_URLS (5)
@@ -292,17 +291,21 @@
gboolean map_new(map_t** ppMap, GtkWidget* pTargetWidget);
// Gets and Sets
-guint16 map_get_zoomlevel(map_t* pMap);
-guint32 map_get_zoomlevel_scale(map_t* pMap);
+guint16 map_get_zoomlevel(const map_t* pMap);
+guint32 map_get_zoomlevel_scale(const map_t* pMap);
+
+gboolean map_can_zoom_in(const map_t* pMap);
+gboolean map_can_zoom_out(const map_t* pMap);
+
void map_set_zoomlevel(map_t* pMap, guint16 uZoomLevel);
//void map_get_render_metrics(rendermetrics_t* pMetrics);
void map_set_redraw_needed(map_t* pMap, gboolean bNeeded);
-gboolean map_get_redraw_needed(map_t* pMap);
-guint32 map_get_scale(map_t* pMap);
+gboolean map_get_redraw_needed(const map_t* pMap);
+guint32 map_get_scale(const map_t* pMap);
void map_set_centerpoint(map_t* pMap, const mappoint_t* pPoint);
-void map_get_centerpoint(map_t* pMap, mappoint_t* pReturnPoint);
+void map_get_centerpoint(const map_t* pMap, mappoint_t* pReturnPoint);
void map_set_dimensions(map_t* pMap, const dimensions_t* pDimensions);
// Conversions
@@ -320,15 +323,12 @@
GdkPixmap* map_get_pixmap(map_t* pMap);
void map_release_pixmap(map_t* pMap);
-void map_draw(map_t* pMap, gint nDrawFlags);
+void map_draw(map_t* pMap, GdkPixmap* pTargetPixmap, gint nDrawFlags);
void map_add_track(map_t* pMap, gint hTrack);
gboolean map_hit_test(map_t* pMap, mappoint_t* pMapPoint, maphit_t** ppReturnStruct);
void map_hitstruct_free(map_t* pMap, maphit_t* pHitStruct);
-gboolean map_can_zoom_in(map_t* pMap);
-gboolean map_can_zoom_out(map_t* pMap);
-
gboolean map_location_selection_add(map_t* pMap, gint nLocationID);
gboolean map_location_selection_remove(map_t* pMap, gint nLocationID);
Index: map_draw_cairo.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_cairo.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- map_draw_cairo.c 6 Sep 2005 02:44:19 -0000 1.21
+++ map_draw_cairo.c 14 Sep 2005 20:06:54 -0000 1.22
@@ -29,40 +29,39 @@
#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 ENABLE_DRAW_MAP_SCALE
+//#define ENABLE_MAP_DROP_SHADOW
-#define ENABLE_HACK_AROUND_CAIRO_LINE_CAP_BUG // enable to ensure roads have rounded caps if the style dictates
+//#define ENABLE_HACK_AROUND_CAIRO_LINE_CAP_BUG // enable to ensure roads have rounded caps if the style dictates
// supposedly fixed as of 1.0 but I haven't tested yet
#define ROAD_FONT "Free Sans" //Bitstream Vera Sans"
#define AREA_FONT "Free Sans" // "Bitstream Vera Sans"
[...1333 lines suppressed...]
- //cairo_fill(pCairo);
- cairo_restore(pCairo);
-
- // claim the space this took up
- scenemanager_claim_polygon(pMap->m_pSceneManager, aBoundingPolygon, 4);
- }
-
- cairo_restore(pCairo);
-
- // claim the label (so it won't be drawn twice)
- scenemanager_claim_label(pMap->m_pSceneManager, pszLabel);
-
-// // success
-// break;
-// }
-//
-// g_ptr_array_free(pPositionsPtrArray, FALSE);
-}
*/
#endif
Index: map_draw_gdk.c
===================================================================
RCS file: /cvs/cairo/roadster/src/map_draw_gdk.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- map_draw_gdk.c 6 Sep 2005 02:44:19 -0000 1.17
+++ map_draw_gdk.c 14 Sep 2005 20:06:54 -0000 1.18
@@ -23,6 +23,8 @@
#define MAX_GDK_LINE_SEGMENTS (2000)
+//#define ENABLE_MAP_GRAYSCALE_HACK
+
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
@@ -36,25 +38,35 @@
#include "db.h"
#include "road.h"
#include "point.h"
-#include "layers.h"
+#include "map_style.h"
#include "track.h"
#include "locationset.h"
#include "location.h"
#include "scenemanager.h"
-static void map_draw_gdk_background(map_t* pMap, GdkPixmap* pPixmap);
-static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, layerstyle_t* pLayerStyle);
-static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, layerstyle_t* pLayerStyle);
+//static void map_draw_gdk_background(map_t* pMap, GdkPixmap* pPixmap);
+static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle);
+static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle);
+
+static void map_draw_gdk_layer_fill(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, maplayerstyle_t* pLayerStyle);
+
static void map_draw_gdk_tracks(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics);
static void map_draw_gdk_locations(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics);
static void map_draw_gdk_locationset(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, locationset_t* pLocationSet, GPtrArray* pLocationsArray);
+//#define ENABLE_MAP_GRAYSCALE_HACK // just a little test. black and white might be good for something
+
void map_draw_gdk_set_color(GdkGC* pGC, color_t* pColor)
{
GdkColor clr;
+
+#ifdef ENABLE_MAP_GRAYSCALE_HACK
+ clr.red = clr.green = clr.blue = ((pColor->m_fRed + pColor->m_fGreen + pColor->m_fBlue) / 3.0) * 65535;
+#else
clr.red = pColor->m_fRed * 65535;
clr.green = pColor->m_fGreen * 65535;
clr.blue = pColor->m_fBlue * 65535;
+#endif
gdk_gc_set_rgb_fg_color(pGC, &clr);
}
@@ -62,26 +74,28 @@
{
TIMER_BEGIN(maptimer, "BEGIN RENDER MAP (gdk)");
+ GdkGC* pGC = pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)];
+
// 1. Save values (so we can restore them)
GdkGCValues gcValues;
- gdk_gc_get_values(pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], &gcValues);
+ gdk_gc_get_values(pGC, &gcValues);
// 2. Drawing
-
- // 2.1. Draw Background
- if(nDrawFlags & DRAWFLAG_GEOMETRY) {
- map_draw_gdk_background(pMap, pPixmap);
- }
-
- // 2.2. Render Layers
if(nDrawFlags & DRAWFLAG_GEOMETRY) {
gint i;
- // draw list in reverse order (painter's algorithm: http://en.wikipedia.org/wiki/Painter's_algorithm )
- for(i=g_pLayersArray->len-1 ; i>=0 ; i--) {
- layer_t* pLayer = g_ptr_array_index(g_pLayersArray, i);
+ // 2.1. Draw Background
+// map_draw_gdk_background(pMap, pPixmap);
- if(pLayer->m_nDrawType == MAP_LAYER_RENDERTYPE_LINES) {
+ // 2.2. Draw layer list in reverse order (painter's algorithm: http://en.wikipedia.org/wiki/Painter's_algorithm )
+ for(i=pMap->m_pLayersArray->len-1 ; i>=0 ; i--) {
+ maplayer_t* pLayer = g_ptr_array_index(pMap->m_pLayersArray, i);
+
+ if(pLayer->m_nDrawType == MAP_LAYER_RENDERTYPE_FILL) {
+ map_draw_gdk_layer_fill(pMap, pPixmap, pRenderMetrics,
+ pLayer->m_paStylesAtZoomLevels[pRenderMetrics->m_nZoomLevel-1]); // style
+ }
+ else if(pLayer->m_nDrawType == MAP_LAYER_RENDERTYPE_LINES) {
map_draw_gdk_layer_lines(pMap, pPixmap, pRenderMetrics,
pMap->m_apLayerData[pLayer->m_nDataSource]->m_pRoadsArray, // data
pLayer->m_paStylesAtZoomLevels[pRenderMetrics->m_nZoomLevel-1]); // style
@@ -105,19 +119,19 @@
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->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], &clr);
-
- gdk_draw_rectangle(pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
- TRUE, 0,0, pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight);
-}
+// 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->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], &clr);
+//
+// gdk_draw_rectangle(pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+// TRUE, 0,0, pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight);
+// }
-static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, layerstyle_t* pLayerStyle)
+static void map_draw_gdk_layer_polygons(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
{
mappoint_t* pPoint;
road_t* pRoad;
@@ -153,8 +167,8 @@
fMaxLon = max(pPoint->m_fLongitude,fMaxLon);
fMinLon = min(pPoint->m_fLongitude,fMinLon);
- aPoints[iPoint].x = (gint)SCALE_X(pRenderMetrics, pPoint->m_fLongitude);
- aPoints[iPoint].y = (gint)SCALE_Y(pRenderMetrics, pPoint->m_fLatitude);
+ aPoints[iPoint].x = pLayerStyle->m_nPixelOffsetX + (gint)SCALE_X(pRenderMetrics, pPoint->m_fLongitude);
+ aPoints[iPoint].y = pLayerStyle->m_nPixelOffsetY + (gint)SCALE_Y(pRenderMetrics, pPoint->m_fLatitude);
}
// rectangle overlap test
@@ -171,7 +185,15 @@
}
}
-static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, layerstyle_t* pLayerStyle)
+// 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->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)], &(pLayerStyle->m_clrPrimary));
+ gdk_draw_rectangle(pPixmap, pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+ TRUE, 0,0, pMap->m_MapDimensions.m_uWidth, pMap->m_MapDimensions.m_uHeight);
+}
+
+static void map_draw_gdk_layer_lines(map_t* pMap, GdkPixmap* pPixmap, rendermetrics_t* pRenderMetrics, GPtrArray* pRoadsArray, maplayerstyle_t* pLayerStyle)
{
road_t* pRoad;
mappoint_t* pPoint;
@@ -181,17 +203,6 @@
if(pLayerStyle->m_fLineWidth <= 0.0) return; // Don't draw invisible lines
if(pLayerStyle->m_clrPrimary.m_fAlpha == 0.0) return; // invisible? (not that we respect it in gdk drawing anyway)
- // Use GDK dash style if ANY dash pattern is set
- gint nDashStyle = GDK_LINE_SOLID;
- if(g_aDashStyles[pLayerStyle->m_nDashStyle].m_nDashCount > 1) {
- nDashStyle = GDK_LINE_ON_OFF_DASH;
-
- gdk_gc_set_dashes(pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
- 0, /* offset to start at */
- g_aDashStyles[pLayerStyle->m_nDashStyle].m_panDashList,
- g_aDashStyles[pLayerStyle->m_nDashStyle].m_nDashCount);
- }
-
// Translate generic cap style into GDK constant
gint nCapStyle;
if(pLayerStyle->m_nCapStyle == MAP_CAP_STYLE_ROUND) {
@@ -204,6 +215,18 @@
// Convert to integer width. Ouch!
gint nLineWidth = (gint)(pLayerStyle->m_fLineWidth);
+ // Use GDK dash style if ANY dash pattern is set
+ gint nDashStyle = GDK_LINE_SOLID;
+ if(pLayerStyle->m_pDashStyle != NULL) {
+ gdk_gc_set_dashes(pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
+ 0, /* offset to start at */
+ pLayerStyle->m_pDashStyle->m_panDashList,
+ pLayerStyle->m_pDashStyle->m_nDashCount);
+
+ nDashStyle = GDK_LINE_ON_OFF_DASH;
+ // further set line attributes below...
+ }
+
// Set line style
gdk_gc_set_line_attributes(pMap->m_pTargetWidget->style->fg_gc[GTK_WIDGET_STATE(pMap->m_pTargetWidget)],
nLineWidth, nDashStyle, nCapStyle, GDK_JOIN_ROUND);
@@ -236,8 +259,8 @@
fMaxLon = max(pPoint->m_fLongitude,fMaxLon);
fMinLon = min(pPoint->m_fLongitude,fMinLon);
- aPoints[iPoint].x = (gint)SCALE_X(pRenderMetrics, pPoint->m_fLongitude);
- aPoints[iPoint].y = (gint)SCALE_Y(pRenderMetrics, pPoint->m_fLatitude);
+ aPoints[iPoint].x = pLayerStyle->m_nPixelOffsetX + (gint)SCALE_X(pRenderMetrics, pPoint->m_fLongitude);
+ aPoints[iPoint].y = pLayerStyle->m_nPixelOffsetY + (gint)SCALE_Y(pRenderMetrics, pPoint->m_fLatitude);
}
// basic rectangle overlap test
--- NEW FILE: map_style.c ---
/***************************************************************************
* map_style.c
*
* Copyright 2005
* Ian McIntosh <ian_mcintosh at linuxadvocate.org>
* Nathan Fredrickson <nathan at silverorange.com>
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <cairo.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "main.h"
#include "map_style.h"
// utility functions for iterating through lists of XML things
#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);
static void map_style_parse_file(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pNode);
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);
static void map_style_print_color(color_t *color);
// Callbacks
// void map_style_callback_generic_error(void * ctx, const char * msg, ...)
// {
// g_print("map_style_callback_generic_error: %s\n", msg);
// }
//
// void map_style_callback_structured_error(void * userData, xmlErrorPtr error)
// {
// g_print("map_style_callback_structured_error\n");
// }
//
// Functions
//
void map_style_init(void)
{
/* init libxml */
LIBXML_TEST_VERSION ;
}
void map_style_deinit(void)
{
xmlCleanupParser();
}
void map_style_load(map_t* pMap, const gchar* pszFileName)
{
g_assert(pMap != NULL);
g_assert(pszFileName != NULL);
if(pMap->m_pLayersArray != NULL) {
g_warning("reloading styles currently leaks memory so... don't do it very often :)\n");
pMap->m_pLayersArray = NULL;
}
pMap->m_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;
// g_print("map_style_constant_get(%s) == TRUE\n", pszName);
return TRUE;
}
// g_print("map_style_constant_get(%s) == FALSE\n", pszName);
return FALSE;
}
void map_style_constant_set(const gchar* pszName, const gchar* pszValue)
{
g_assert(pszName != NULL);
g_assert(pszValue != NULL);
// g_print("map_style_constant_set(%s, %s)\n", pszName, pszValue);
// 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);
gint i;
for(i=0 ; i<NUM_ZOOM_LEVELS ; i++) {
maplayerstyle_t* pLayerStyle = g_new0(maplayerstyle_t, 1);
pLayerStyle->m_nCapStyle = MAP_CAP_STYLE_DEFAULT;
// XXX: need to init the maplayerstyle_t's?
pLayer->m_paStylesAtZoomLevels[i] = pLayerStyle;
}
return pLayer;
}
gboolean map_style_parse_zoomlevel(const gchar* pszZoomLevel, gint* pnReturnMinZoomLevel, gint* pnReturnMaxZoomLevel)
{
g_assert(pszZoomLevel != NULL);
g_assert(pnReturnMinZoomLevel != NULL);
g_assert(pnReturnMaxZoomLevel != NULL);
gchar* pszStr = g_strdup(pszZoomLevel);
gboolean bReturn = TRUE;
// Support the following formats:
// "4-5", "4"
gint nMin, nMax;
gchar* pszSeparator = g_strrstr(pszStr, "-");
if(pszSeparator != NULL) {
// Parse a "5-8"
*pszSeparator = '\0';
nMin = atoi(pszStr);
nMax = atoi(pszSeparator+1);
}
else {
// For the single value format, we return the same value for both min and max.
nMin = nMax = atoi(pszStr);
}
if(nMin < MIN_ZOOM_LEVEL || nMin > MAX_ZOOM_LEVEL) {
g_warning("zoom-level '%s' out of valid range (%d to %d)\n", pszZoomLevel, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
bReturn = FALSE;
}
else if(nMax < MIN_ZOOM_LEVEL || nMax > MAX_ZOOM_LEVEL) {
g_warning("zoom-level '%s' out of valid range (%d to %d)\n", pszZoomLevel, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
bReturn = FALSE;
}
else {
*pnReturnMinZoomLevel = nMin;
*pnReturnMaxZoomLevel = nMax;
}
g_free(pszStr);
return bReturn;
}
#define MAX_VALUES_IN_DASH_STYLE (20)
#define MAX_DASH_LENGTH (50)
#define MIN_DASH_LENGTH (1)
dashstyle_t* dashstyle_new(gdouble* pafValues, gint nValueCount)
{
g_assert(pafValues != NULL);
g_assert(nValueCount >= 2);
dashstyle_t* pNewDashStyle = g_new0(dashstyle_t, 1);
// The list of gdouble's can just be copied in
pNewDashStyle->m_pafDashList = g_malloc(sizeof(gdouble) * nValueCount);
memcpy(pNewDashStyle->m_pafDashList, pafValues, sizeof(gdouble) * nValueCount);
// The list of int8's has to be converted list
pNewDashStyle->m_panDashList = g_malloc(sizeof(gint8) * nValueCount);
gint i;
for(i=0 ; i<nValueCount ; i++) {
gint8 nVal = (gint)pafValues[i];
//
nVal = MIN(nVal, MAX_DASH_LENGTH);
nVal = MAX(nVal, MIN_DASH_LENGTH);
pNewDashStyle->m_panDashList[i] = nVal;
}
pNewDashStyle->m_nDashCount = nValueCount;
return pNewDashStyle;
}
gboolean map_style_parse_dashstyle(const gchar* pszDashStyle, dashstyle_t** ppReturnDashStyle)
{
g_assert(pszDashStyle);
g_assert(ppReturnDashStyle);
g_assert(*ppReturnDashStyle == NULL); // require pointer to NULL pointer
// Parse a string that looks like this: "3.5 5" etc.
gdouble afValues[MAX_VALUES_IN_DASH_STYLE];
gint nValueCount = 0;
const gchar* pszWorker = pszDashStyle;
while(*pszWorker != '\0' && nValueCount < MAX_VALUES_IN_DASH_STYLE) {
// Read one value
gdouble fNew = atof(pszWorker); // NOTE: atof() stops after it hits a bad character (eg. a space)
if(fNew != 0.0) {
// Add to end of list
afValues[nValueCount] = fNew;
nValueCount++;
// Skip to next whitespace
while(*pszWorker != ' ' && *pszWorker != '\0') pszWorker++; // XXX: use utf8 functions?
// Now skip the whitespace!
while(*pszWorker == ' ') pszWorker++;
}
else {
// Done.
break;
}
}
if(nValueCount >= 2) { // a dash of 1 doesn't make sense
// Success.
*ppReturnDashStyle = dashstyle_new(afValues, nValueCount);
return TRUE;
}
return FALSE;
}
gchar* get_attribute_value(const xmlDocPtr pDoc, const xmlAttrPtr pAttribute)
{
g_assert(pDoc != NULL);
g_assert(pAttribute != NULL);
// allocate a new glib string for this value. free xmllib string.
gchar* pszTmp = xmlNodeListGetString(pDoc, pAttribute->xmlChildrenNode, 1);
gchar* pszValue = g_strdup((pszTmp) ? pszTmp : "");
xmlFree(pszTmp);
return pszValue;
}
static void map_style_load_from_file(map_t* pMap, const gchar* pszFileName)
{
g_assert(pMap != NULL);
g_assert(pszFileName != NULL);
xmlDocPtr pDoc = NULL;
xmlNodePtr pRootElement = NULL;
// Load style definition file
// try source directory first (good for development)
gchar* pszPath = g_strdup_printf(PACKAGE_SOURCE_DIR"/data/%s", pszFileName);
pDoc = xmlReadFile(pszPath, NULL, 0);
g_free(pszPath);
// try alternate path
if(pDoc == NULL) {
pszPath = g_strdup_printf(PACKAGE_DATA_DIR"/data/%s", pszFileName);
pDoc = xmlReadFile(pszPath, NULL, 0);
g_free(pszPath);
}
// still NULL?
if(pDoc == NULL) {
g_message("cannot load map style file %s\n", pszFileName);
// gtk_exit(0);
}
else {
pRootElement = xmlDocGetRootElement(pDoc);
map_style_parse_file(pMap, pDoc, pRootElement);
xmlFreeDoc(pDoc);
}
}
/*****************************************************************
* map_style_parse_* functions for parsing the xml
*****************************************************************/
static void map_style_parse_file(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pParentNode)
{
g_assert(pMap != NULL);
g_assert(pDoc != NULL);
g_assert(pParentNode != NULL);
// Top-level node.
if(pParentNode->type == XML_ELEMENT_NODE) {
xmlNodePtr pChildNode = NULL;
for(EACH_CHILD_OF_NODE(pChildNode, pParentNode)) {
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);
}
}
}
}
static void map_style_parse_layers(map_t* pMap, xmlDocPtr pDoc, xmlNodePtr pParentNode)
{
g_assert(pMap != NULL);
g_assert(pDoc != NULL);
g_assert(pParentNode != NULL);
// g_print("map_style_parse_layers()\n");
xmlNodePtr pChildNode = NULL;
// iterate over "layer" objects
for(EACH_CHILD_OF_NODE(pChildNode, pParentNode)) {
//for(pChildNode = pParentNode->children; pChildNode != NULL; pChildNode = pChildNode->next) {
if(pChildNode->type == XML_ELEMENT_NODE && strcmp(pChildNode->name, "layer") == 0) {
map_style_parse_layer(pMap, pDoc, pChildNode);
}
}
}
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);
g_assert(pDoc != NULL);
g_assert(pNode != NULL);
xmlAttrPtr pAttribute = NULL;
gint i;
// create new layer
maplayer_t *pLayer = map_style_new_layer();
// read attributes of the 'layer' node
for(EACH_ATTRIBUTE_OF_NODE(pAttribute, pNode)) {
if(strcmp(pAttribute->name, "data-source") == 0) {
gchar* pszDataSource = xmlNodeListGetString(pDoc, pAttribute->xmlChildrenNode, 1);
if(!map_object_type_atoi(pszDataSource, &(pLayer->m_nDataSource))) {
g_error("bad data source name %s\n", pszDataSource);
}
}
else if(strcmp(pAttribute->name, "draw-type") == 0) {
gchar* pszDrawType = xmlNodeListGetString(pDoc, pAttribute->xmlChildrenNode, 1);
if(!map_layer_render_type_atoi(pszDrawType, &(pLayer->m_nDrawType))) {
g_error("bad layer draw type name %s\n", pszDrawType);
}
}
}
// read children of the 'layer' node
xmlNodePtr pChild = NULL;
for(EACH_CHILD_OF_NODE(pChild, pNode)) {
if(strcmp(pChild->name, "property") == 0) {
map_style_parse_layer_property(pMap, pDoc, pLayer, pChild);
}
}
// add it to list
g_ptr_array_add(pMap->m_pLayersArray, pLayer);
// map_style_print_layer(pLayer);
}
static void
map_style_parse_layer_property(map_t* pMap, xmlDocPtr pDoc, maplayer_t *pLayer, xmlNodePtr pNode)
{
g_assert(pMap != NULL);
g_assert(pLayer != NULL);
g_assert(pNode != NULL);
gchar* pszName = NULL;
gchar* pszValue = NULL;
gchar* pszZoomLevel = NULL;
// Read 'name', 'value', and 'level' attributes of this property
xmlAttrPtr pAttribute = 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);
}
else if((strcmp(pAttribute->name, "zoom-level") == 0) || (strcmp(pAttribute->name, "zoom-levels") == 0)) {
g_free(pszZoomLevel);
pszZoomLevel = get_attribute_value(pDoc, pAttribute);
}
}
gint nMinZoomLevel = MIN_ZOOM_LEVEL;
gint nMaxZoomLevel = MAX_ZOOM_LEVEL;
if(pszZoomLevel != NULL) {
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) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_fLineWidth = (gdouble)atof(pszValue);
}
}
else if(strcmp(pszName, "line-width") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_fLineWidth = (gdouble)atof(pszValue);
}
}
else if(strcmp(pszName, "pixel-offset-x") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_nPixelOffsetX = (gint)atoi(pszValue);
}
}
else if(strcmp(pszName, "pixel-offset-y") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_nPixelOffsetY = (gint)atoi(pszValue);
}
}
else if(strcmp(pszName, "color") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
util_parse_hex_color(pszValue, &(pLayer->m_paStylesAtZoomLevels[i]->m_clrPrimary));
}
}
else if(strcmp(pszName, "halo-size") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_fHaloSize = (gdouble)atof(pszValue);
}
}
else if(strcmp(pszName, "dash-pattern") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
// NOTE: unlike all the atoi() calls in the loops, we actually DO need to parse this multiple times because each
// layer should have its own copy
dashstyle_t* pNewDashStyle = NULL;
if(map_style_parse_dashstyle(pszValue, &pNewDashStyle)) {
pLayer->m_paStylesAtZoomLevels[i]->m_pDashStyle = pNewDashStyle;
}
else {
g_warning("bad dash style '%s' (should look like \"5.0 3.5\"\n", pszValue);
break;
}
}
}
else if(strcmp(pszName, "bold") == 0) {
gboolean bBold = (strcmp(pszValue, "yes") == 0);
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_bFontBold = bBold;
}
}
else if(strcmp(pszName, "halo-color") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
util_parse_hex_color(pszValue, &(pLayer->m_paStylesAtZoomLevels[i]->m_clrHalo));
}
}
else if(strcmp(pszName, "font-size") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_fFontSize = (gdouble)atof(pszValue);
}
}
// else if(strcmp(pszName, "join-style") == 0) {
// for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
// if(strcmp(pszValue, "mitre") == 0) {
// pLayer->m_paStylesAtZoomLevels[i]->m_nJoinStyle = CAIRO_LINE_JOIN_MITER;
// }
// else if(strcmp(pszValue, "round") == 0) {
// pLayer->m_paStylesAtZoomLevels[i]->m_nJoinStyle = CAIRO_LINE_JOIN_ROUND;
// }
// }
// }
else if(strcmp(pszName, "line-cap") == 0) {
if(strcmp(pszValue, "square") == 0) {
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_nCapStyle = MAP_CAP_STYLE_SQUARE;
}
}
else {
if(strcmp(pszValue, "round") != 0) { g_warning("bad value for line-cap found: '%s' (valid options are 'square' and 'round')\n", pszValue); }
for(i = nMinZoomLevel - 1; i < nMaxZoomLevel ; i++) {
pLayer->m_paStylesAtZoomLevels[i]->m_nCapStyle = MAP_CAP_STYLE_ROUND;
}
}
}
}
g_free(pszName);
g_free(pszValue);
g_free(pszZoomLevel);
}
/******************************************************************
* map_style_print_* functions for debugging
*****************************************************************/
static void
map_style_print_color(color_t* pColor)
{
g_assert(pColor != NULL);
g_print("color: %3.2f, %3.2f, %3.2f, %3.2f\n", pColor->m_fRed, pColor->m_fGreen, pColor->m_fBlue, pColor->m_fAlpha);
}
/*
color_t m_clrPrimary; // Color used for polygon fill or line stroke
gdouble m_fLineWidth;
gint m_nJoinStyle;
gint m_nCapStyle;
gint m_nDashStyle;
// XXX: switch to this:
//dashstyle_t m_pDashStyle; // can be NULL
// Used just for text
gdouble m_fFontSize;
gboolean m_bBold;
gdouble m_fHaloSize; // actually a stroke width
color_t m_clrHalo;
*/
static void
map_style_print_layer(maplayer_t *pLayer)
{
g_assert(pLayer != NULL);
int i;
for(i = 0 ; i < NUM_ZOOM_LEVELS ; i++) {
g_print("\nzoom level %d\n", i+1);
maplayerstyle_t* pStyle = pLayer->m_paStylesAtZoomLevels[i];
g_print(" line width: %f\n", pStyle->m_fLineWidth);
g_print(" primary "); map_style_print_color(&(pStyle->m_clrPrimary));
g_print(" join style: %d\n", pStyle->m_nJoinStyle);
g_print(" cap style: %d\n", pStyle->m_nCapStyle);
//g_print(" dash style: %d\n", pStyle->m_nDashStyle);
}
}
--- NEW FILE: map_style.h ---
/***************************************************************************
* map_style.h
*
* Copyright 2005
* Ian McIntosh <ian_mcintosh at linuxadvocate.org>
* Nathan Fredrickson <nathan at silverorange.com>
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _MAP_STYLE_H_
#define _MAP_STYLE_H_
#include <gtk/gtk.h>
G_BEGIN_DECLS
#include "main.h"
#include "map.h"
typedef struct dashstyle {
gdouble* m_pafDashList; // the dashes, as an array of gdouble's (for Cairo)
gint8* m_panDashList; // the dashes, as an array of gint8's (for GDK)
gint m_nDashCount; // how many
} dashstyle_t;
// defines the look of a layer
typedef struct layerstyle {
color_t m_clrPrimary; // Color used for polygon fill or line stroke
gdouble m_fLineWidth;
gint m_nJoinStyle;
gint m_nCapStyle;
dashstyle_t* m_pDashStyle;
// XXX: switch to this:
//dashstyle_t m_pDashStyle; // can be NULL
// Used just for text
gdouble m_fFontSize;
gboolean m_bFontBold;
gdouble m_fHaloSize; // actually a stroke width
color_t m_clrHalo;
gint m_nPixelOffsetX;
gint m_nPixelOffsetY;
} maplayerstyle_t;
typedef struct layer {
gint m_nDataSource; // which data to use (lakes, roads...)
gint m_nDrawType; // as lines, polygons, etc.
// A layer has a style for each zoomlevel
maplayerstyle_t* m_paStylesAtZoomLevels[ NUM_ZOOM_LEVELS ];
} maplayer_t;
//extern layer_t * g_aLayers[NUM_LAYERS+1];
//extern GPtrArray* g_pLayersArray;
void map_style_init(void);
void map_style_deinit(void);
void map_style_load(map_t* pMap, const gchar* pszFileName);
void map_style_reload(map_t* pMap, const gchar* pszFileName);
G_END_DECLS
#endif /* _MAP_STYLE_H_ */
--- prefs.c DELETED ---
--- prefs.h DELETED ---
Index: road.c
===================================================================
RCS file: /cvs/cairo/roadster/src/road.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- road.c 6 Sep 2005 02:44:19 -0000 1.5
+++ road.c 14 Sep 2005 20:06:54 -0000 1.6
@@ -251,7 +251,7 @@
gboolean road_suffix_atoi(const gchar* pszSuffix, gint* pReturnSuffixID)
{
gint i;
- for(i=0 ; i<NUM_ELEMS(g_RoadNameSuffixLookup) ; i++) {
+ for(i=0 ; i<G_N_ELEMENTS(g_RoadNameSuffixLookup) ; i++) {
if(g_ascii_strcasecmp(pszSuffix, g_RoadNameSuffixLookup[i].m_pszName) == 0) {
*pReturnSuffixID = g_RoadNameSuffixLookup[i].m_nID;
return TRUE;
Index: scenemanager.c
===================================================================
RCS file: /cvs/cairo/roadster/src/scenemanager.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- scenemanager.c 6 Sep 2005 02:44:19 -0000 1.13
+++ scenemanager.c 14 Sep 2005 20:06:54 -0000 1.14
@@ -88,7 +88,7 @@
// else go on to test below
}
else if(nFlags & SCENEMANAGER_FLAG_PARTLY_ON_SCREEN) {
- // one point must be withing screen box
+ // one point must be withing screen box XXX: handle polygon bigger than window case?
gint i;
gboolean bFound = FALSE;
for(i=0 ; i<nNumPoints ; i++) {
Index: search.c
===================================================================
RCS file: /cvs/cairo/roadster/src/search.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- search.c 28 Mar 2005 18:49:50 -0000 1.5
+++ search.c 14 Sep 2005 20:06:54 -0000 1.6
@@ -44,7 +44,7 @@
while(*pReader != '\0') {
if(g_ascii_isspace(*pReader)) {
if(g_ascii_isspace(*(pReader+1)) || *(pReader+1) == '\0') {
- // don't copy this character (space) if the next one is a space also
+ // don't copy this character (space) if the next one is a space
// or if it's the last character
}
else {
@@ -72,9 +72,7 @@
gint nNumber = 0;
- // remove double spaces
while(*pReader != '\0') {
-
if(g_ascii_isdigit(*pReader)) {
nNumber *= 10;
nNumber += g_ascii_digit_value(*pReader);
Index: search_road.c
===================================================================
RCS file: /cvs/cairo/roadster/src/search_road.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- search_road.c 6 Sep 2005 02:44:19 -0000 1.21
+++ search_road.c 14 Sep 2005 20:06:54 -0000 1.22
@@ -34,7 +34,7 @@
#include "search_road.h"
#include "road.h"
-#define ROAD_RESULT_SUGGESTED_ZOOMLEVEL (8)
+#define ROAD_RESULT_SUGGESTED_ZOOMLEVEL (4)
typedef struct {
gint m_nNumber; // house number eg. 51
Index: searchwindow.c
===================================================================
RCS file: /cvs/cairo/roadster/src/searchwindow.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- searchwindow.c 28 Aug 2005 22:23:14 -0000 1.19
+++ searchwindow.c 14 Sep 2005 20:06:54 -0000 1.20
@@ -22,6 +22,7 @@
*/
#include <gtk/gtk.h>
+#include <glib-object.h>
#include <glade/glade.h>
#ifdef HAVE_CONFIG_H
@@ -33,18 +34,21 @@
#include "search_location.h"
#include "mainwindow.h"
#include "searchwindow.h"
-
-#define GTK_PROCESS_MAINLOOP while (gtk_events_pending ()) { gtk_main_iteration (); }
+#include "util.h"
+#include "gui.h"
#define RESULTLIST_COLUMN_NAME 0 // visible data
-#define RESULTLIST_LATITUDE 1
+#define RESULTLIST_LATITUDE 1
#define RESULTLIST_LONGITUDE 2
-#define RESULTLIST_DISTANCE 3
+#define RESULTLIST_DISTANCE 3
#define RESULTLIST_ZOOMLEVEL 4
#define RESULTLIST_CLICKABLE 5
#define MAGIC_GTK_NO_SORT_COLUMN (-2) // why -2? dunno. is there a real define for this? dunno.
+#define SEARCHWINDOW_RESULT_FORMAT ("<span size='small'>%s</span>")
+#define SEARCHWINDOW_INFO_FORMAT ("<span size='small'><i>%s</i></span>")
+
struct {
GtkEntry* m_pSearchEntry; // search text box (on the toolbar)
GtkButton* m_pSearchButton; // search button (on the toolbar)
@@ -60,9 +64,9 @@
void searchwindow_init(GladeXML* pGladeXML)
{
- g_SearchWindow.m_pSearchEntry = GTK_ENTRY(glade_xml_get_widget(pGladeXML, "searchentry")); g_return_if_fail(g_SearchWindow.m_pSearchEntry != NULL);
- g_SearchWindow.m_pSearchButton = GTK_BUTTON(glade_xml_get_widget(pGladeXML, "searchbutton")); g_return_if_fail(g_SearchWindow.m_pSearchButton != NULL);
- g_SearchWindow.m_pResultsTreeView = GTK_TREE_VIEW(glade_xml_get_widget(pGladeXML, "searchresultstreeview")); g_return_if_fail(g_SearchWindow.m_pResultsTreeView != NULL);
+ GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.m_pSearchEntry, GTK_ENTRY, "searchentry");
+ GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.m_pSearchButton, GTK_BUTTON, "searchbutton");
+ GLADE_LINK_WIDGET(pGladeXML, g_SearchWindow.m_pResultsTreeView, GTK_TREE_VIEW, "searchresultstreeview");
// create results tree view
g_SearchWindow.m_pResultsListStore = gtk_list_store_new(6, G_TYPE_STRING, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_INT, G_TYPE_BOOLEAN);
@@ -76,7 +80,7 @@
pColumn = gtk_tree_view_column_new_with_attributes("Road", pCellRenderer, "markup", RESULTLIST_COLUMN_NAME, NULL);
gtk_tree_view_append_column(g_SearchWindow.m_pResultsTreeView, pColumn);
- /* attach handler for selection-changed signal */
+ // attach handler for selection-changed signal
GtkTreeSelection *pTreeSelection = gtk_tree_view_get_selection(g_SearchWindow.m_pResultsTreeView);
g_signal_connect(G_OBJECT(pTreeSelection), "changed", (GtkSignalFunc)searchwindow_on_resultslist_selection_changed, NULL);
}
@@ -92,22 +96,28 @@
void searchwindow_add_message(gchar* pszMessage)
{
+ // Add a basic text message to the list, instead of a search result (eg. "no results")
GtkTreeIter iter;
gtk_list_store_append(g_SearchWindow.m_pResultsListStore, &iter);
- gtk_list_store_set(g_SearchWindow.m_pResultsListStore, &iter, RESULTLIST_COLUMN_NAME, pszMessage, RESULTLIST_CLICKABLE, FALSE, -1);
+ gtk_list_store_set(g_SearchWindow.m_pResultsListStore, &iter,
+ RESULTLIST_COLUMN_NAME, pszMessage,
+ RESULTLIST_CLICKABLE, FALSE,
+ -1);
}
-// begin a search
void searchwindow_on_findbutton_clicked(GtkWidget *pWidget, gpointer* p)
{
- // make list unsorted (sorting once at the end is much faster than for each insert)
-// gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(g_SearchWindow.m_pResultsListStore), MAGIC_GTK_NO_SORT_COLUMN, GTK_SORT_ASCENDING);
+ // Begin a search
+
+ // XXX: make list unsorted (sorting once at the end is much faster than for each insert)
+ //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(g_SearchWindow.m_pResultsListStore), MAGIC_GTK_NO_SORT_COLUMN, GTK_SORT_ASCENDING);
+
searchwindow_clear_results();
const gchar* pszSearch = gtk_entry_get_text(g_SearchWindow.m_pSearchEntry);
if(pszSearch[0] == '\0') {
- gchar* pszBuffer = g_strdup_printf("<span size='small'><i>Type search words above.</i></span>");
+ gchar* pszBuffer = g_strdup_printf(SEARCHWINDOW_INFO_FORMAT, "Type search words above.");
searchwindow_add_message(pszBuffer);
g_free(pszBuffer);
}
@@ -119,11 +129,11 @@
if(g_SearchWindow.m_nNumResults == 0) {
// insert a "no results" message
- gchar* pszBuffer = g_strdup_printf("<span size='small'><i>No results.</i></span>", pszSearch);
+ gchar* pszBuffer = g_strdup_printf(SEARCHWINDOW_INFO_FORMAT, "No results.");
searchwindow_add_message(pszBuffer);
g_free(pszBuffer);
}
- // Sort the list by distance from viewer!
+ // Sort the list by distance from viewer
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(g_SearchWindow.m_pResultsListStore), RESULTLIST_DISTANCE, GTK_SORT_ASCENDING);
}
// ensure the search results are visible
@@ -141,8 +151,17 @@
gdouble fDistance = map_get_distance_in_meters(&ptCenter, pPoint);
- gchar* pszBuffer = g_markup_printf_escaped("<span size='small'>%s</span>", pszText);
- //g_print("Adding: (%f,%f) (%f) %s\n", pPoint->m_fLatitude, pPoint->m_fLongitude, fDistance, pszBuffer);
+ gchar* pszBuffer = NULL;
+ if(g_utf8_validate(pszText, -1, NULL)) {
+ pszBuffer = g_markup_printf_escaped(SEARCHWINDOW_RESULT_FORMAT, pszText);
+ }
+ else {
+ g_warning("Search result not UTF-8: '%s'\n", pszText);
+ pszBuffer = g_strdup_printf(SEARCHWINDOW_RESULT_FORMAT, "<i>Invalid Name</i>");
+ }
+
+// g_print("Adding: (%f,%f) (%f) %s\n", pPoint->m_fLatitude, pPoint->m_fLongitude, fDistance, pszBuffer);
+
gtk_list_store_append(g_SearchWindow.m_pResultsListStore, &iter);
gtk_list_store_set(g_SearchWindow.m_pResultsListStore, &iter,
RESULTLIST_COLUMN_NAME, pszBuffer,
@@ -177,8 +196,10 @@
if(!bClickable) return; // XXX: is this the right way to make a treeview item not clickable?
- mainwindow_map_slide_to_mappoint(&pt);
- //mainwindow_set_zoomlevel(nZoomLevel);
+ // XXX: Slide or jump? Should this be a setting?
+// mainwindow_map_slide_to_mappoint(&pt);
+ mainwindow_set_zoomlevel(nZoomLevel);
+ mainwindow_map_center_on_mappoint(&pt);
mainwindow_draw_map(DRAWFLAG_ALL);
}
}
Index: util.c
===================================================================
RCS file: /cvs/cairo/roadster/src/util.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- util.c 6 Sep 2005 02:44:19 -0000 1.9
+++ util.c 14 Sep 2005 20:06:54 -0000 1.10
@@ -181,8 +181,10 @@
return aLines;
}
-gboolean util_parse_hex_color(const gchar* pszString, color_t* pReturnColor)
+gboolean util_parse_hex_color(const gchar* pszString, void* pvReturnColor)
{
+ color_t* pReturnColor = (color_t*)pvReturnColor;
+
gchar *p = pszString;
if (*p == '#') p++;
@@ -219,12 +221,12 @@
}
#endif
-#if ROADSTER_DEAD_CODE
-void util_random_color(color_t* pColor)
+void util_random_color(void* p)
{
+ color_t* pColor = (color_t*)p;
+
pColor->m_fRed = (random()%1000)/1000.0;
pColor->m_fGreen = (random()%1000)/1000.0;
pColor->m_fBlue = (random()%1000)/1000.0;
pColor->m_fAlpha = 1.0;
}
-#endif /* ROADSTER_DEAD_CODE */
Index: util.h
===================================================================
RCS file: /cvs/cairo/roadster/src/util.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- util.h 6 Sep 2005 02:44:19 -0000 1.9
+++ util.h 14 Sep 2005 20:06:54 -0000 1.10
@@ -25,16 +25,13 @@
#define _UTIL_H_
#include <gtk/gtk.h>
-#include "layers.h"
#define GTK_PROCESS_MAINLOOP while (gtk_events_pending ()) { gtk_main_iteration (); }
-#define NUM_ELEMS(a) (sizeof(a) / sizeof(a[0]))
-
#define SWAP(x, y) { (x) ^= (y) ^= (x) ^= (y); }
void util_random_color(void* pColor);
-gboolean util_parse_hex_color(const gchar* pszString, color_t* pReturnColor);
+gboolean util_parse_hex_color(const gchar* pszString, void* pReturnColor);
#ifdef ENABLE_TIMING
#define TIMER_BEGIN(name, str) GTimer* name = g_timer_new(); g_print("\n%s (%f)\n", str, g_timer_elapsed(name, NULL))
@@ -52,11 +49,6 @@
#define is_even(x) (((x) & 1) == 0)
#define is_odd(x) (((x) & 1) == 1)
-/* Funky, auto-lookup glade signal handlers.
-
- XXX: Better would be to hook these up manually, remove these
- declarations, and make the functions static.
-*/
void util_close_parent_window(GtkWidget* pWidget, gpointer data);
void util_open_uri(const char* pszURI);
More information about the cairo-commit
mailing list