implement external timelapse file
This commit is contained in:
@@ -238,10 +238,6 @@
|
||||
<checkbox id="tools-vr-check" width="20" height="20"/>
|
||||
<text text="Enable VR" margin="0 0 0 5"/>
|
||||
</button-custom>
|
||||
<button-custom id="tools-timeline" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<checkbox id="tools-timeline-check" width="20" height="20"/>
|
||||
<text text="Show Timeline" margin="0 0 0 5"/>
|
||||
</button-custom>
|
||||
<button-custom id="clear-grids" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||
<icon icon="bin" width="20"/>
|
||||
<text text="Clear Guides" margin="0 0 0 5"/>
|
||||
@@ -483,20 +479,6 @@
|
||||
<scroll id="drop-left" color="0 0 0 .5" min-width="10" mouse-capture="true" rtl="ltr"/>
|
||||
|
||||
<node dir="col" width="1" grow="1" height="100%">
|
||||
<!-- timeline -->
|
||||
<node width="100%" shrink="1" dir="col" rtl="ltr" id="timeline">
|
||||
<border color=".3 .3 .3 .4" height="50" width="100%" pad="10" dir="row" mouse-capture="true">
|
||||
<text text="Timeline: " margin="8 10 0 0"/>
|
||||
<slider-h id="frames-slider" width="1" grow="1" margin="0 10 0 0"></slider-h>
|
||||
<node width="30" margin="0 10 0 10">
|
||||
<text id="timeline-frame" text="00" font-size="30"/>
|
||||
</node>
|
||||
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
||||
<icon width="30" icon="add"/>
|
||||
</button-custom>
|
||||
</border>
|
||||
</node>
|
||||
|
||||
<!--tools options-->
|
||||
<border id="tools-container" color="0 0 0 0.3" dir="row" justify="center" mouse-capture="true">
|
||||
</border>
|
||||
|
||||
@@ -115,7 +115,6 @@ public:
|
||||
std::shared_ptr<NodePanelGrid> grid;
|
||||
std::shared_ptr<NodePanelBrushPreset> presets;
|
||||
std::shared_ptr<NodePanelAnimation> animation;
|
||||
std::shared_ptr<Node> timeline;
|
||||
NodePanelQuick* quick;
|
||||
std::map<kCanvasMode, NodePanelQuick::MiniState> quick_mode_state;
|
||||
Node* floatings_container;
|
||||
|
||||
@@ -1014,23 +1014,6 @@ void App::init_menu_tools()
|
||||
};
|
||||
}
|
||||
|
||||
if (auto vr_btn = popup_exp->find<NodeButtonCustom>("tools-timeline"))
|
||||
{
|
||||
NodeCheckBox* cb = vr_btn->find<NodeCheckBox>("tools-timeline-check");
|
||||
cb->set_value(timeline->GetVisibility());
|
||||
|
||||
vr_btn->on_click = [this, popup_exp, vr_btn](Node* b)
|
||||
{
|
||||
NodeCheckBox* cb = vr_btn->find<NodeCheckBox>("tools-timeline-check");
|
||||
cb->set_value(!cb->checked, true);
|
||||
};
|
||||
|
||||
vr_btn->find<NodeCheckBox>("tools-timeline-check")->on_value_changed = [this, main](Node* target, bool checked)
|
||||
{
|
||||
timeline->SetVisibility(checked);
|
||||
};
|
||||
}
|
||||
|
||||
popup_exp->find<NodeButtonCustom>("clear-grids")->on_click = [this, popup_exp](Node*) {
|
||||
CanvasModeGrid* mode = (CanvasModeGrid*)Canvas::modes[(int)kCanvasMode::Grid][0];
|
||||
mode->clear();
|
||||
@@ -1285,6 +1268,7 @@ void App::initLayout()
|
||||
{
|
||||
layers->add_layer("Default", false, true);
|
||||
Canvas::I->m_unsaved = false;
|
||||
Canvas::I->timelapse_reset_encoder();
|
||||
}
|
||||
|
||||
init_toolbar_draw();
|
||||
@@ -1354,93 +1338,6 @@ void App::initLayout()
|
||||
toggle_ui();
|
||||
};
|
||||
|
||||
timeline = layout[main_id]->find_ref("timeline");
|
||||
if (timeline)
|
||||
{
|
||||
if (auto * slider = layout[main_id]->find<NodeSliderH>("frames-slider"))
|
||||
{
|
||||
auto frame_text = layout[main_id]->find<NodeText>("timeline-frame");
|
||||
slider->on_value_changed = [this, frame_text](Node*, float value)
|
||||
{
|
||||
auto& l = Canvas::I->layer();
|
||||
l.m_frame_index = (int)glm::clamp<int>(
|
||||
floor(value * l.frames_count()), 0, l.frames_count() - 1);
|
||||
/*
|
||||
auto& c = *Canvas::I;
|
||||
for (int i = 0; i < c.m_layers.size(); i++)
|
||||
{
|
||||
auto l = layers->get_layer_at(i);
|
||||
layers->handle_layer_opacity(l, .0f);
|
||||
}
|
||||
|
||||
int current_layer = (int)glm::clamp<int>(
|
||||
floor(value * c.m_layers.size()), 1, (int)c.m_layers.size() - 1);
|
||||
auto l = layers->get_layer_at(current_layer);
|
||||
layers->handle_layer_selected(l);
|
||||
layers->handle_layer_opacity(l, 1.f);
|
||||
if (current_layer > 0)
|
||||
{
|
||||
auto l = layers->get_layer_at(current_layer - 1);
|
||||
layers->handle_layer_opacity(l, .25f);
|
||||
}
|
||||
|
||||
// First layer always visible
|
||||
{
|
||||
auto l = layers->get_layer_at(0);
|
||||
layers->handle_layer_opacity(l, 1.0f);
|
||||
}
|
||||
|
||||
if (frame_text)
|
||||
{
|
||||
char str[16];
|
||||
snprintf(str, sizeof(str), "%02d", current_layer);
|
||||
frame_text->set_text(str);
|
||||
}
|
||||
*/
|
||||
};
|
||||
if (auto btn_add = timeline->find<NodeButtonCustom>("btn-add"))
|
||||
{
|
||||
btn_add->on_click = [this, slider] (Node*) {
|
||||
Canvas::I->layer().add_frame();
|
||||
slider->set_value(1.f, true);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// test floating panel
|
||||
auto fp_presets = layout[main_id]->add_child<NodePanelFloating>();
|
||||
floating_presets = fp_presets->m_container->add_child<NodePanelBrushPreset>();
|
||||
floating_presets->SetHeightP(100);
|
||||
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
|
||||
auto c = Canvas::I->m_current_brush->m_tip_color;
|
||||
*Canvas::I->m_current_brush = *b;
|
||||
Canvas::I->m_current_brush->m_tip_color = c;
|
||||
Canvas::I->m_current_brush->load();
|
||||
brush_update();
|
||||
};
|
||||
|
||||
auto fp_color = layout[main_id]->add_child<NodePanelFloating>();
|
||||
floating_color = fp_color->m_container->add_child<NodePanelColor>();
|
||||
floating_color->SetHeightP(100);
|
||||
floating_color->find("title")->destroy();
|
||||
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||
Canvas::I->m_current_brush->m_tip_color = color;
|
||||
brush_update();
|
||||
};
|
||||
|
||||
auto fp_picker = layout[main_id]->add_child<NodePanelFloating>();
|
||||
fp_picker->m_container->SetSize(300, 500);
|
||||
floating_picker = fp_picker->m_container->add_child<NodeColorPicker>();
|
||||
floating_picker->m_autohide = false;
|
||||
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
|
||||
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
|
||||
brush_update();
|
||||
};
|
||||
//picker->SetHeightP(100);
|
||||
//color->find("title")->destroy();
|
||||
*/
|
||||
ui_restore();
|
||||
|
||||
redraw = true;
|
||||
@@ -1538,7 +1435,6 @@ void App::ui_save()
|
||||
|
||||
Settings::set("ui", d);
|
||||
Settings::set("ui-rtl", Serializer::Boolean(ui_rtl));
|
||||
Settings::set("timeline-visible", Serializer::Boolean(timeline->GetVisibility()));
|
||||
|
||||
#if _WIN32
|
||||
extern void win32_save_window_state();
|
||||
@@ -1556,12 +1452,7 @@ void App::ui_restore()
|
||||
set_ui_rtl(Settings::value<Serializer::Integer>("ui-rtl"));
|
||||
|
||||
if (!Settings::has("ui"))
|
||||
{
|
||||
timeline->SetVisibility(false);
|
||||
return;
|
||||
}
|
||||
|
||||
timeline->SetVisibility(Settings::value_or<Serializer::Boolean>("timeline-visible", false));
|
||||
|
||||
auto floatings = layout[main_id]->find_ref("floatings");
|
||||
auto drop_left = layout[main_id]->find_ref("drop-left");
|
||||
|
||||
@@ -2088,7 +2088,8 @@ bool Canvas::project_save_thread(std::string file_path, bool show_progress)
|
||||
|
||||
auto start = file_path.rfind('/') + 1;
|
||||
std::string file_name = file_path.substr(start, file_path.length() - start - strlen(".ppi"));
|
||||
std::string tmp_path = App::I->data_path + '/' + file_name + ".tmp.ppi";
|
||||
std::string tmp_path = App::I->data_path + '/' + file_name + ".tmp.ppi";
|
||||
std::string lapse_path = App::I->data_path + '/' + file_name + ".pptl";
|
||||
|
||||
LOG("file name %s", file_name.c_str());
|
||||
LOG("tmp path %s", tmp_path.c_str());
|
||||
@@ -2225,10 +2226,10 @@ bool Canvas::project_save_thread(std::string file_path, bool show_progress)
|
||||
Serializer::Descriptor info;
|
||||
info.class_id = "ppi_info";
|
||||
info.name = L"info header";
|
||||
info.props["has_encoder"] = std::make_shared<Serializer::Boolean>(m_encoder != nullptr);
|
||||
//info.props["has_encoder"] = std::make_shared<Serializer::Boolean>(m_encoder != nullptr);
|
||||
sw << info;
|
||||
if (m_encoder != nullptr)
|
||||
sw << *m_encoder;
|
||||
//if (m_encoder != nullptr)
|
||||
// sw << *m_encoder;
|
||||
|
||||
int bytes = sw.m_data.size();
|
||||
fwrite(&bytes, sizeof(int), 1, fp);
|
||||
@@ -2271,6 +2272,16 @@ bool Canvas::project_save_thread(std::string file_path, bool show_progress)
|
||||
{
|
||||
m_unsaved = false;
|
||||
m_newdoc = false;
|
||||
|
||||
// save timelapse
|
||||
if (Canvas::I->m_encoder)
|
||||
{
|
||||
BinaryStreamWriter sw;
|
||||
sw.init(BinaryStream::ByteOrder::LittleEndian);
|
||||
sw << *Canvas::I->m_encoder;
|
||||
if (!sw.save(lapse_path))
|
||||
LOG("cannot save timelase to %s", lapse_path.c_str());
|
||||
}
|
||||
#if __WEB__
|
||||
webgl_sync();
|
||||
#endif
|
||||
@@ -2448,25 +2459,40 @@ bool Canvas::project_open_thread(std::string file_path)
|
||||
sr.init(data.data(), data.size(), BinaryStream::ByteOrder::LittleEndian);
|
||||
Serializer::Descriptor info;
|
||||
sr >> info;
|
||||
|
||||
if (info.value<Serializer::Boolean>("has_encoder"))
|
||||
{
|
||||
m_encoder = std::make_unique<MP4Encoder>();
|
||||
sr >> *m_encoder;
|
||||
m_encoder->init();
|
||||
}
|
||||
else
|
||||
{
|
||||
timelapse_reset_encoder();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timelapse_reset_encoder();
|
||||
//if (info.value<Serializer::Boolean>("has_encoder"))
|
||||
//{
|
||||
// m_encoder = std::make_unique<MP4Encoder>();
|
||||
// sr >> *m_encoder;
|
||||
// m_encoder->init();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// timelapse_reset_encoder();
|
||||
//}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// timelapse_reset_encoder();
|
||||
//}
|
||||
|
||||
fclose(fp);
|
||||
LOG("project restore from %s", file_path.c_str());
|
||||
|
||||
auto start = file_path.rfind('/') + 1;
|
||||
std::string file_name = file_path.substr(start, file_path.length() - start - strlen(".ppi"));
|
||||
std::string lapse_path = App::I->data_path + '/' + file_name + ".pptl";
|
||||
if (Asset::exist(lapse_path))
|
||||
{
|
||||
BinaryStreamReader sr;
|
||||
sr.load(lapse_path, BinaryStream::ByteOrder::LittleEndian);
|
||||
m_encoder = std::make_unique<MP4Encoder>();
|
||||
sr >> *m_encoder;
|
||||
m_encoder->init();
|
||||
}
|
||||
else
|
||||
{
|
||||
timelapse_reset_encoder();
|
||||
}
|
||||
|
||||
m_current_layer_idx = 0;
|
||||
m_current_stroke = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user