make bundle on mac os x and persist settings

This commit is contained in:
Konstantin Käfer
2014-01-16 13:53:10 +01:00
parent 8fd762b5f3
commit c01719bc04
12 changed files with 280 additions and 47 deletions

View File

@@ -1,7 +1,16 @@
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
project(llmr)
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_PATCH "1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
add_subdirectory(src)
if(APPLE)
add_subdirectory(macosx)
endif(APPLE)

View File

@@ -5,6 +5,7 @@
#include "../renderer/painter.hpp"
#include "transform.hpp"
#include <llmr/map/tile.hpp>
#include "settings.hpp"
#include <forward_list>
@@ -12,10 +13,11 @@ namespace llmr {
class map {
public:
map();
map(settings *settings);
~map();
void setup();
void loadSettings();
void resize(uint32_t width, uint32_t height);
/* callback */
@@ -34,6 +36,8 @@ public:
// void setZoom(double zoom);
// void setLonLatZoom(double lon, double lat, double zoom);
void toggleDebug();
private:
bool findLoadedChildren(const tile_id& id, int32_t maxCoveringZoom, std::forward_list<tile_id>& retain);
bool findLoadedParent(const tile_id& id, int32_t minCoveringZoom, std::forward_list<tile_id>& retain);
@@ -41,7 +45,11 @@ private:
tile::ptr addTile(const tile_id& id);
tile::ptr hasTile(const tile_id& id);
void update();
private:
settings *settings;
transform *transform;
painter *painter;

View File

@@ -0,0 +1,23 @@
#ifndef LLMR_MAP_SETTINGS
#define LLMR_MAP_SETTINGS
namespace llmr {
class settings {
public:
virtual void save() = 0;
public:
// position
double longitude = 0;
double latitude = 0;
double scale = 0;
double angle = 0;
// debug
bool debug = false;
};
}
#endif

View File

@@ -29,6 +29,8 @@ public:
// Getters
void matrixFor(float matrix[16], const vec3<int32_t>& id) const;
int32_t getZoom() const;
double getScale() const;
double getAngle() const;
void getLonLat(double& lon, double& lat) const;

View File

@@ -0,0 +1,19 @@
#ifndef LLMR_UTIL_STRING
#define LLMR_UTIL_STRING
#include <string>
namespace llmr {
namespace util {
template<typename... Args>
inline std::string sprintf(const char *msg, Args... args) {
char res[1024];
int len = snprintf(res, sizeof(res), msg, args...);
return std::string(res, len);
}
}
}
#endif

View File

@@ -9,6 +9,7 @@ PKG_SEARCH_MODULE(GLFW REQUIRED glfw3)
SET(macosx_SOURCES
main.mm
settings.mm
)
SET(macosx_HEADERS
@@ -23,10 +24,30 @@ LINK_DIRECTORIES(
${GLFW_LIBRARY_DIRS}
)
ADD_EXECUTABLE(macosx
# Define some settings for the Bundle
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME})
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.mapbox.llmr.native")
set(MACOSX_BUNDLE_ICON_FILE "macosx.icns")
set(MACOSX_BUNDLE_INFO_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(MACOSX_BUNDLE_COPYRIGHT "(c) 2014 Mapbox")
# Add Mac OS X specific icon
#list(APPEND macosx_RESOURCES ../resources/macosx.icns)
# Ensures that resources end up in the Resources folder
set_source_files_properties(${macosx_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
add_executable(macosx MACOSX_BUNDLE
${macosx_SOURCES}
${macosx_RESOURCES}
)
set_target_properties(macosx PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/macosx/Info.plist.in)
TARGET_LINK_LIBRARIES(macosx
llmr
${COCOA_LIBRARY}

36
macosx/Info.plist.in Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>LLMR</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View File

@@ -1,8 +1,10 @@
#include <llmr/llmr.hpp>
#include <GLFW/glfw3.h>
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <llmr/platform/platform.hpp>
#include <llmr/map/tile.hpp>
#include "settings.hpp"
class MapView {
public:
@@ -11,7 +13,8 @@ public:
tracking(false),
rotating(false),
last_click(-1),
map(new llmr::map()) {
settings(new llmr::macosx_settings()),
map(new llmr::map(settings)) {
}
void init() {
@@ -32,18 +35,16 @@ public:
glfwMakeContextCurrent(window);
int stencil_bits = glfwGetWindowAttrib(window, GLFW_STENCIL_BITS);
fprintf(stderr, "stencil bits: %d\n", stencil_bits);
settings->load();
map->setup();
int width, height;
glfwGetWindowSize(window, &width, &height);
map->resize(width, height);
glfwSwapInterval(1);
map->loadSettings();
glfwSetCursorPosCallback(window, mousemove);
glfwSetMouseButtonCallback(window, mouseclick);
@@ -56,28 +57,27 @@ public:
}
static void character(GLFWwindow *window, unsigned int codepoint) {
MapView *view = (MapView *)glfwGetWindowUserPointer(window);
switch (codepoint) {
case L'n':
case L'N':
view->map->resetNorth();
break;
case L'r':
case L'R':
view->map->resetPosition();
break;
}
}
static void key(GLFWwindow *window, int key, int scancode, int action, int mods) {
// MapView *view = (MapView *)glfwGetWindowUserPointer(window);
MapView *view = (MapView *)glfwGetWindowUserPointer(window);
if (action == GLFW_RELEASE) {
switch (key) {
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, true);
break;
case GLFW_KEY_TAB:
view->map->toggleDebug();
break;
case GLFW_KEY_R:
if (!mods) view->map->resetPosition();
break;
case GLFW_KEY_N:
if (!mods) view->map->resetNorth();
break;
}
}
}
@@ -195,6 +195,7 @@ public:
double last_click;
GLFWwindow *window;
llmr::macosx_settings *settings;
llmr::map *map;
};
@@ -210,9 +211,7 @@ void restart(void *) {
void request(void *, tile::ptr tile) {
assert((bool)tile);
// fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y);
// fprintf(stderr, "requesting tile\n");
// NSString *urlTemplate = @"http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf";
NSString *urlTemplate = @"http://localhost:3333/gl/tiles/plain/%d-%d-%d.vector.pbf";
NSString *urlString = [NSString
@@ -248,8 +247,6 @@ void request(void *, tile::ptr tile) {
return;
}
}
fprintf(stderr, "[%s] status code %d\n", [urlString UTF8String], code);
}
dispatch_async(dispatch_get_main_queue(), ^ {

18
macosx/settings.hpp Normal file
View File

@@ -0,0 +1,18 @@
#ifndef LLMR_MACOSX_SETTINGS
#define LLMR_MACOSX_SETTINGS
#include <llmr/map/settings.hpp>
namespace llmr {
class macosx_settings : public settings {
public:
macosx_settings();
virtual void save();
virtual void load();
virtual void clear();
};
}
#endif

62
macosx/settings.mm Normal file
View File

@@ -0,0 +1,62 @@
#import <Foundation/Foundation.h>
#include "settings.hpp"
using namespace llmr;
macosx_settings::macosx_settings() {
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
// position
[NSNumber numberWithDouble:longitude], @"longitude",
[NSNumber numberWithDouble:latitude], @"latitude",
[NSNumber numberWithDouble:scale], @"scale",
[NSNumber numberWithDouble:angle], @"angle",
// debug
[NSNumber numberWithBool:debug], @"debug",
nil
];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
}
void macosx_settings::load() {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// position
longitude = [defaults doubleForKey:@"longitude"];
latitude = [defaults doubleForKey:@"latitude"];
scale = [defaults doubleForKey:@"scale"];
angle = [defaults doubleForKey:@"angle"];
// debug
debug = [defaults boolForKey:@"debug"];
}
void macosx_settings::save() {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
// position
[NSNumber numberWithDouble:longitude], @"longitude",
[NSNumber numberWithDouble:latitude], @"latitude",
[NSNumber numberWithDouble:scale], @"scale",
[NSNumber numberWithDouble:angle], @"angle",
// debug
[NSNumber numberWithBool:debug], @"debug",
nil
];
[defaults setPersistentDomain:appDefaults forName:[[NSBundle mainBundle] bundleIdentifier]];
[defaults synchronize];
}
void macosx_settings::clear() {
// TODO
}

View File

@@ -10,14 +10,12 @@
using namespace llmr;
map::map()
: transform(new class transform()),
map::map(class settings *settings)
: settings(settings),
transform(new class transform()),
painter(new class painter(transform)),
min_zoom(0),
max_zoom(14) {
// transform->setLonLat(13, 50);
// transform->setZoom(3);
}
map::~map() {
@@ -28,45 +26,77 @@ void map::setup() {
painter->setup();
}
void map::loadSettings() {
transform->setAngle(settings->angle);
transform->setScale(settings->scale);
transform->setLonLat(settings->longitude, settings->latitude);
update();
}
void map::resize(uint32_t width, uint32_t height) {
transform->width = width;
transform->height = height;
updateTiles();
platform::restart(this);
update();
}
void map::moveBy(double dx, double dy) {
transform->moveBy(dx, dy);
updateTiles();
platform::restart(this);
update();
transform->getLonLat(settings->longitude, settings->latitude);
settings->save();
}
void map::scaleBy(double ds, double cx, double cy) {
transform->scaleBy(ds, cx, cy);
updateTiles();
platform::restart(this);
update();
transform->getLonLat(settings->longitude, settings->latitude);
settings->scale = transform->getScale();
settings->save();
}
void map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey) {
transform->rotateBy(cx, cy, sx, sy, ex, ey);
updateTiles();
platform::restart(this);
update();
settings->angle = transform->getAngle();
settings->save();
}
void map::resetNorth() {
transform->setAngle(0);
updateTiles();
platform::restart(this);
update();
settings->angle = transform->getAngle();
settings->save();
}
void map::resetPosition() {
transform->setAngle(0);
transform->setLonLat(0, 0);
transform->setZoom(0);
update();
transform->getLonLat(settings->longitude, settings->latitude);
settings->scale = transform->getScale();
settings->angle = transform->getAngle();
settings->save();
}
void map::toggleDebug() {
settings->debug = !settings->debug;
update();
settings->save();
}
void map::update() {
updateTiles();
platform::restart(this);
}
tile::ptr map::hasTile(const tile_id& id) {
for (tile::ptr& tile : tiles) {
if (tile->id == id) {
@@ -238,7 +268,7 @@ bool map::render() {
void map::tileLoaded(tile::ptr tile) {
// std::cerr << "loaded " << tile->toString() << std::endl;
platform::restart(this);
update();
}
void map::tileFailed(tile::ptr tile) {

View File

@@ -36,21 +36,22 @@ void transform::moveBy(double dx, double dy) {
void transform::scaleBy(double ds, double cx, double cy) {
// clamp scale to min/max values
const double new_scale = scale * ds;
double new_scale = scale * ds;
if (new_scale < min_scale) {
ds = min_scale / scale;
new_scale = min_scale;
} else if (new_scale > max_scale) {
ds = max_scale / scale;
new_scale = max_scale;
}
setScale(new_scale);
// Correct for non-center scaling location.
const double dx = (cx - width / 2) * (1.0 - ds);
const double dy = (cy - height / 2) * (1.0 - ds);
const double fx = cos(angle) * dx + sin(angle) * dy;
const double fy = cos(angle) * dy + sin(-angle) * dx;
scale *= ds;
x = (x * ds) + fx;
y = (y * ds) + fy;
x += cos(angle) * dx + sin(angle) * dy;
y += cos(angle) * dy + sin(-angle) * dx;
}
@@ -154,6 +155,13 @@ int32_t transform::getZoom() const {
return floor(log(scale) / M_LN2);
}
double transform::getScale() const {
return scale;
}
double transform::getAngle() const {
return angle;
}
void transform::mapCornersToBox(uint32_t z, box& b) const {
const double ref_scale = pow(2, z);