fix thumbnail generator for iOS and open document when file clicked
This commit is contained in:
@@ -38,7 +38,7 @@ void global_signal_handler(int e)
|
|||||||
|
|
||||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
||||||
{
|
{
|
||||||
App::I.canvas->m_canvas->project_open([url fileSystemRepresentation]);
|
App::I.open_document([url fileSystemRepresentation]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,10 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>Export the panoramic to the gallery</string>
|
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
<string>Use the audio jack for the SonarPen</string>
|
<string>Use the audio jack for the SonarPen</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Export the panoramic to the gallery</string>
|
||||||
<key>UIFileSharingEnabled</key>
|
<key>UIFileSharingEnabled</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>public.filename-extension</key>
|
<key>public.filename-extension</key>
|
||||||
<array>
|
<array>
|
||||||
<string>pano</string>
|
<string>ppi</string>
|
||||||
</array>
|
</array>
|
||||||
<key>public.mime-type</key>
|
<key>public.mime-type</key>
|
||||||
<string>image/ppi</string>
|
<string>image/ppi</string>
|
||||||
|
|||||||
@@ -8,6 +8,54 @@
|
|||||||
|
|
||||||
#import "ThumbnailProvider.h"
|
#import "ThumbnailProvider.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct PPIThumb
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int comp;
|
||||||
|
/*
|
||||||
|
bool valid()
|
||||||
|
{
|
||||||
|
return (width == 128 && height == 128 && comp == 4);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPIDocVersion
|
||||||
|
{
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPISoftVersion
|
||||||
|
{
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int fix;
|
||||||
|
int build;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPIHeader
|
||||||
|
{
|
||||||
|
char magic[4];
|
||||||
|
struct PPIDocVersion doc_version;
|
||||||
|
struct PPISoftVersion soft_version;
|
||||||
|
struct PPIThumb thumb_header;
|
||||||
|
/*
|
||||||
|
bool valid()
|
||||||
|
{
|
||||||
|
if (strcmp(magic, "PPI") != 0)
|
||||||
|
return false;
|
||||||
|
if (doc_version.major != 0 || doc_version.minor != 1)
|
||||||
|
return false;
|
||||||
|
if (!thumb_header.valid())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
@implementation ThumbnailProvider
|
@implementation ThumbnailProvider
|
||||||
|
|
||||||
- (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request completionHandler:(void (^)(QLThumbnailReply * _Nullable, NSError * _Nullable))handler {
|
- (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request completionHandler:(void (^)(QLThumbnailReply * _Nullable, NSError * _Nullable))handler {
|
||||||
@@ -35,16 +83,31 @@
|
|||||||
FILE* fp = fopen([u fileSystemRepresentation], "rb");
|
FILE* fp = fopen([u fileSystemRepresentation], "rb");
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
int h[3];
|
struct PPIHeader header;
|
||||||
fread(h, sizeof(int), 3, fp);
|
fread(&header, sizeof(struct PPIHeader), 1, fp);
|
||||||
|
int w = header.thumb_header.width;
|
||||||
|
int h = header.thumb_header.height;
|
||||||
|
int c = header.thumb_header.comp;
|
||||||
|
|
||||||
//uint8_t* data = (uint8_t*)malloc(h[0]*h[1]*h[2]);
|
//uint8_t* data = (uint8_t*)malloc(h[0]*h[1]*h[2]);
|
||||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
CGContextRef bmp = CGBitmapContextCreate(NULL, h[0], h[1], 8, h[0]*h[2], colorSpace, kCGImageAlphaPremultipliedLast);
|
CGContextRef bmp = CGBitmapContextCreate(NULL, w, h, 8, w*c, colorSpace, kCGImageAlphaPremultipliedLast);
|
||||||
uint8_t* data = CGBitmapContextGetData(bmp);
|
|
||||||
fread(data, h[0]*h[1]*h[2], 1, fp);
|
uint8_t* data_dst = (uint8_t*)CGBitmapContextGetData(bmp);
|
||||||
|
uint8_t* data_src = (uint8_t*)malloc(w*h*c);
|
||||||
|
fread(data_src, w*h*c, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
for(int i = 0; i < w*h; i++)
|
||||||
|
{
|
||||||
|
data_dst[i * 4 + 0] = data_src[i * c + 0];
|
||||||
|
data_dst[i * 4 + 1] = data_src[i * c + 1];
|
||||||
|
data_dst[i * 4 + 2] = data_src[i * c + 2];
|
||||||
|
data_dst[i * 4 + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data_src);
|
||||||
|
|
||||||
CGImageRef img = CGBitmapContextCreateImage(bmp);
|
CGImageRef img = CGBitmapContextCreateImage(bmp);
|
||||||
CGRect r2 = CGRectMake(0, 0, 128*request.scale, 128*request.scale);
|
CGRect r2 = CGRectMake(0, 0, 128*request.scale, 128*request.scale);
|
||||||
CGContextDrawImage(context, r2, img);
|
CGContextDrawImage(context, r2, img);
|
||||||
|
|||||||
20
src/app.cpp
20
src/app.cpp
@@ -31,6 +31,26 @@ void App::create()
|
|||||||
height = 1080/2;
|
height = 1080/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::open_document(std::string path)
|
||||||
|
{
|
||||||
|
auto start = path.rfind("/") + 1;
|
||||||
|
doc_name = path.substr(start, path.length() - start - strlen(".ppi"));
|
||||||
|
canvas->reset_camera();
|
||||||
|
layers->clear();
|
||||||
|
canvas->m_canvas->project_open(path, [this] {
|
||||||
|
// on complete
|
||||||
|
async_start();
|
||||||
|
title_update();
|
||||||
|
for (auto& i : canvas->m_canvas->m_order)
|
||||||
|
{
|
||||||
|
auto* l = layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||||
|
l->m_opacity->m_value.x = canvas->m_canvas->m_layers[i].m_opacity;
|
||||||
|
}
|
||||||
|
async_end();
|
||||||
|
});
|
||||||
|
ActionManager::clear();
|
||||||
|
}
|
||||||
|
|
||||||
bool App::request_close()
|
bool App::request_close()
|
||||||
{
|
{
|
||||||
static bool dialog_already_opened = false;
|
static bool dialog_already_opened = false;
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ public:
|
|||||||
void initShaders();
|
void initShaders();
|
||||||
void initAssets();
|
void initAssets();
|
||||||
void initLayout();
|
void initLayout();
|
||||||
|
void open_document(std::string path);
|
||||||
void create();
|
void create();
|
||||||
bool request_close();
|
bool request_close();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|||||||
@@ -192,22 +192,8 @@ void App::dialog_browse()
|
|||||||
|
|
||||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||||
{
|
{
|
||||||
canvas->reset_camera();
|
open_document(dialog->selected_path);
|
||||||
layers->clear();
|
|
||||||
doc_name = dialog->selected_name;
|
|
||||||
canvas->m_canvas->project_open(dialog->selected_path, [this] {
|
|
||||||
// on complete
|
|
||||||
async_start();
|
|
||||||
title_update();
|
|
||||||
for (auto& i : canvas->m_canvas->m_order)
|
|
||||||
{
|
|
||||||
auto* l = layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
|
||||||
l->m_opacity->m_value.x = canvas->m_canvas->m_layers[i].m_opacity;
|
|
||||||
}
|
|
||||||
async_end();
|
|
||||||
});
|
|
||||||
dialog->destroy();
|
dialog->destroy();
|
||||||
ActionManager::clear();
|
|
||||||
};
|
};
|
||||||
async_end();
|
async_end();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user