make bundle on mac os x and persist settings
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
23
include/llmr/map/settings.hpp
Normal file
23
include/llmr/map/settings.hpp
Normal 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
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
19
include/llmr/util/string.hpp
Normal file
19
include/llmr/util/string.hpp
Normal 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
|
||||
@@ -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
36
macosx/Info.plist.in
Normal 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>
|
||||
@@ -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
18
macosx/settings.hpp
Normal 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
62
macosx/settings.mm
Normal 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
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user