add download progress, improbable cloud browser, lock touch when pencil is down on iOS

This commit is contained in:
2018-01-04 00:02:28 +00:00
parent 01370642a1
commit 5feb3acb1d
10 changed files with 120 additions and 37 deletions

View File

@@ -30,6 +30,7 @@
@end @end
//std::map< //std::map<
bool pen_down = false;
int t_count = 0; int t_count = 0;
glm::vec2 t_pos; glm::vec2 t_pos;
int lock_count = 0; int lock_count = 0;
@@ -194,6 +195,8 @@ NSThread* lock_thread;
float scale = self.view.contentScaleFactor; float scale = self.view.contentScaleFactor;
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
if (source == kEventSource::Stylus)
pen_down = true;
[self async_lock]; [self async_lock];
App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, touch.force, source); App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, touch.force, source);
[self async_unlock]; [self async_unlock];
@@ -220,7 +223,14 @@ NSThread* lock_thread;
} }
[self async_lock]; [self async_lock];
if (n == 2) if (pen_down)
{
if (t0.type == UITouchType::UITouchTypeStylus)
App::I.mouse_move(p0.x, p0.y, t0.force, kEventSource::Stylus);
if (t1.type == UITouchType::UITouchTypeStylus)
App::I.mouse_move(p1.x, p1.y, t1.force, kEventSource::Stylus);
}
else if (n == 2)
{ {
if (t_count == 1) if (t_count == 1)
{ {
@@ -258,6 +268,7 @@ NSThread* lock_thread;
float scale = self.view.contentScaleFactor; float scale = self.view.contentScaleFactor;
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
pen_down = false;
[self async_lock]; [self async_lock];
if (t_count == 2) if (t_count == 2)

View File

@@ -63,7 +63,15 @@ void App::initLog()
LogRemote::I.file_init(); LogRemote::I.file_init();
} }
void App::download(std::string filename) int progress_callback(void *clientp, curl_off_t dltotal,
curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
std::function<void(float)> progress = *(std::function<void(float)>*)clientp;
progress((float)dlnow / (float)dltotal);
return 0;
}
void App::download(std::string filename, std::function<void(float)> progress)
{ {
CURL *curl = curl_easy_init(); CURL *curl = curl_easy_init();
if (curl) if (curl)
@@ -74,6 +82,9 @@ void App::download(std::string filename)
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_write); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_write);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
auto err = curl_easy_perform(curl); auto err = curl_easy_perform(curl);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
fclose(fp); fclose(fp);
@@ -213,6 +224,11 @@ void App::async_update()
#endif #endif
} }
void App::async_redraw()
{
redraw = true;
}
void App::async_end() void App::async_end()
{ {
#if __OSX__ #if __OSX__

View File

@@ -97,6 +97,7 @@ public:
void update(float dt); void update(float dt);
void async_start(); void async_start();
void async_update(); void async_update();
void async_redraw();
void async_end(); void async_end();
void resize(float w, float h); void resize(float w, float h);
bool mouse_down(int button, float x, float y, float pressure, kEventSource source); bool mouse_down(int button, float x, float y, float pressure, kEventSource source);
@@ -129,7 +130,7 @@ public:
void cloud_upload_all(); void cloud_upload_all();
void cloud_browse(); void cloud_browse();
void upload(std::string filename, std::string name = ""); void upload(std::string filename, std::string name = "");
void download(std::string filename); void download(std::string filename, std::function<void(float)> progress);
void brush_update(); void brush_update();
void title_update(std::string name, int resolution); void title_update(std::string name, int resolution);

View File

@@ -117,11 +117,18 @@ void App::cloud_browse()
async_start(); async_start();
auto* m = layout[main_id]->add_child<NodeMessageBox>(); auto* m = layout[main_id]->add_child<NodeMessageBox>();
m->m_title->set_text("Downloading"); m->m_title->set_text("Downloading");
m->m_message->set_text("Download in progress, please wait..."); m->m_message->set_text("Download in progress");
async_update(); async_redraw();
async_end(); async_end();
download(dialog->selected_file); download(dialog->selected_file, [this,m](float p){
static char progress[256];
sprintf(progress, "Download in progress %.2f%%", p * 100.f);
async_start();
m->m_message->set_text(progress);
async_redraw();
async_end();
});
async_start(); async_start();
canvas->reset_camera(); canvas->reset_camera();
@@ -137,7 +144,7 @@ void App::cloud_browse()
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str()); layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
ActionManager::clear(); ActionManager::clear();
m->destroy(); m->destroy();
async_update(); async_redraw();
async_end(); async_end();
}).detach(); }).detach();
}; };

View File

@@ -1399,8 +1399,11 @@ void ui::Canvas::project_open_thread(std::string file_path)
fread(compressed.data(), 1, data_size, fp); fread(compressed.data(), 1, data_size, fp);
int imgw, imgh, imgc; int imgw, imgh, imgc;
uint8_t* rgba = stbi_load_from_memory(compressed.data(), data_size, &imgw, &imgh, &imgc, 4); uint8_t* rgba = stbi_load_from_memory(compressed.data(), data_size, &imgw, &imgh, &imgc, 4);
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get()); if (rgba)
delete rgba; {
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get());
delete rgba;
}
} }
progress++; progress++;

View File

@@ -191,6 +191,11 @@ void Node::added(Node* parent)
} }
void Node::removed(Node* parent)
{
}
const Node* Node::init_template(const char* id) const Node* Node::init_template(const char* id)
{ {
const auto& m_template = static_cast<Node*>((*m_manager)[const_hash(id)]->m_children[0].get()); const auto& m_template = static_cast<Node*>((*m_manager)[const_hash(id)]->m_children[0].get());
@@ -247,6 +252,7 @@ void Node::remove_child(Node* n)
auto i = std::find_if(m_children.begin(), m_children.end(), [=](auto& ptr) { return ptr.get() == n; }); auto i = std::find_if(m_children.begin(), m_children.end(), [=](auto& ptr) { return ptr.get() == n; });
if (i != m_children.end()) if (i != m_children.end())
{ {
n->removed(this);
YGNodeRemoveChild(y_node, n->y_node); YGNodeRemoveChild(y_node, n->y_node);
m_children.erase(i); m_children.erase(i);
} }
@@ -255,7 +261,10 @@ void Node::remove_child(Node* n)
void Node::remove_all_children() void Node::remove_all_children()
{ {
for (auto& n : m_children) for (auto& n : m_children)
{
n->removed(this);
YGNodeRemoveChild(y_node, n->y_node); YGNodeRemoveChild(y_node, n->y_node);
}
m_children.clear(); m_children.clear();
} }

View File

@@ -194,6 +194,7 @@ public:
virtual void init(); virtual void init();
virtual void loaded(); virtual void loaded();
virtual void added(Node* parent); virtual void added(Node* parent);
virtual void removed(Node* parent);
const Node* init_template(const char* id); const Node* init_template(const char* id);
void async_start(); void async_start();
void async_update(); void async_update();

View File

@@ -43,40 +43,90 @@ void NodeDialogCloud::loaded()
{ {
} }
void NodeDialogCloud::removed(Node* parent)
{
closed = true;
}
void NodeDialogCloud::load_thumbs_thread() void NodeDialogCloud::load_thumbs_thread()
{ {
CURL *curl = curl_easy_init(); CURL *curl = curl_easy_init();
std::string res; std::string res;
if (curl) if (curl)
{ {
async_start();
auto* align = container->add_child<Node>();
align->SetWidthP(100.f);
align->SetHeightP(100.f);
align->SetAlign(YGAlignCenter);
align->SetJustify(YGJustifyCenter);
auto* text = align->add_child<NodeText>();
text->set_font(kFont::Arial_30);
text->set_text("Connecting to the server...");
async_update();
async_end();
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
curl_easy_setopt(curl, CURLOPT_URL, "http://omigamedev.com/panopainter/cloud/cloud-list.php"); curl_easy_setopt(curl, CURLOPT_URL, "http://omigamedev.com/panopainter/cloud/cloud-list.php");
auto err = curl_easy_perform(curl); auto err = curl_easy_perform(curl);
if (err != CURLE_OK) if (err != CURLE_OK)
{ {
async_start(); async_start();
auto* align = container->add_child<Node>(); text->set_text("Could not connect to the server");
align->SetWidthP(100.f);
align->SetHeightP(100.f);
align->SetAlign(YGAlignCenter);
align->SetJustify(YGJustifyCenter);
auto* t = align->add_child<NodeText>();
t->set_font(kFont::Arial_30);
t->set_text("Could not connect to the server");
async_update(); async_update();
async_end(); async_end();
return; return;
} }
async_start();
align->destroy();
async_end();
LOG("CLOUD LIST: %s", res.c_str()); LOG("CLOUD LIST: %s", res.c_str());
auto names = split(res, ','); auto names = split(res, ',');
std::vector<NodeDialogCloudItem*> nodes;
// create slots with name
App::I.async_start();
for (const auto& n : names) for (const auto& n : names)
{ {
auto node = new NodeDialogCloudItem;
node->m_manager = m_manager;
node->init();
node->m_text->set_text(n.c_str());
node->m_path = data_path + "/" + n;
node->m_file_name = n;
container->add_child(node);
node->on_selected = [&](NodeDialogCloudItem* target) {
if (target == current)
return;
selected_path = target->m_path;
selected_file = target->m_file_name;
selected_name = selected_file.substr(0, selected_file.length() - 5);
if (current)
current->m_selected = false;
current = target;
};
nodes.push_back(node);
}
App::I.async_update();
App::I.async_end();
// load the icons
for (int i = 0; i < names.size(); i++)
{
const auto& n = names[i];
auto* node = nodes[i];
if (closed)
break;
res.clear(); res.clear();
std::string url = "http://omigamedev.com/panopainter/cloud/cloud-info.php?file=" + n; std::string url = "http://omigamedev.com/panopainter/cloud/cloud-info.php?file=" + n;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
LOG("%s", url.c_str());
auto err = curl_easy_perform(curl); auto err = curl_easy_perform(curl);
if (err != CURLE_OK) if (err != CURLE_OK)
break; // TODO: handle this error with a message or something break; // TODO: handle this error with a message or something
@@ -93,29 +143,11 @@ void NodeDialogCloud::load_thumbs_thread()
thumb.copy_from((uint8_t*)rgb.data()); thumb.copy_from((uint8_t*)rgb.data());
App::I.async_start(); App::I.async_start();
auto node = new NodeDialogCloudItem;
node->m_manager = m_manager;
node->init();
node->m_text->set_text(n.c_str());
node->m_path = data_path + "/" + n;
node->m_file_name = n;
auto image_tex = node->find<NodeImageTexture>("thumb-tex"); auto image_tex = node->find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy(); image_tex->tex.destroy();
image_tex->tex.create(thumb); image_tex->tex.create(thumb);
container->add_child(node);
App::I.async_update(); App::I.async_update();
App::I.async_end(); App::I.async_end();
node->on_selected = [&](NodeDialogCloudItem* target) {
if (target == current)
return;
selected_path = target->m_path;
selected_file = target->m_file_name;
selected_name = selected_file.substr(0, selected_file.length() - 5);
if (current)
current->m_selected = false;
current = target;
};
} }
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }

View File

@@ -29,6 +29,7 @@ public:
class NodeDialogCloud : public NodeBorder class NodeDialogCloud : public NodeBorder
{ {
public: public:
bool closed = false;
NodeButton* btn_cancel; NodeButton* btn_cancel;
NodeButton* btn_ok; NodeButton* btn_ok;
NodeButton* btn_delete; NodeButton* btn_delete;
@@ -43,5 +44,6 @@ public:
virtual void init() override; virtual void init() override;
void init_controls(); void init_controls();
virtual void loaded() override; virtual void loaded() override;
virtual void removed(Node* parent) override;
void load_thumbs_thread(); void load_thumbs_thread();
}; };

View File

@@ -93,7 +93,7 @@ kEventResult NodeSliderH::handle_event(Event* e)
auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz) * m_mask; auto pos = glm::clamp(((MouseEvent*)e)->m_pos - m_pos, { 0, 0 }, sz) * m_mask;
m_value = pos / glm::max({ 1, 1 }, sz); m_value = pos / glm::max({ 1, 1 }, sz);
if (on_value_changed) if (on_value_changed)
on_value_changed(this, glm::length(m_value)); on_value_changed(this, glm::length(m_value * m_mask));
} }
break; break;
case kEventType::MouseCancel: case kEventType::MouseCancel:
@@ -103,7 +103,7 @@ kEventResult NodeSliderH::handle_event(Event* e)
m_value = m_old_value; m_value = m_old_value;
set_value(glm::length(m_value)); set_value(glm::length(m_value));
if (on_value_changed) if (on_value_changed)
on_value_changed(this, glm::length(m_value)); on_value_changed(this, glm::length(m_value * m_mask));
} }
dragging = false; dragging = false;
break; break;
@@ -143,6 +143,7 @@ void NodeSliderHue::init_controls()
glm::vec4 NodeSliderHue::get_hue() glm::vec4 NodeSliderHue::get_hue()
{ {
m_color = glm::vec4(convert_hsv2rgb({ glm::length(m_value * m_mask), 1, 1 }), 1);
return m_color; return m_color;
} }