Files
panopainter/src/app.h

318 lines
9.1 KiB
Objective-C

#pragma once
#include "log.h"
#include "shader.h"
#include "shape.h"
#include "texture.h"
#include "layout.h"
#include "font.h"
#include "rtt.h"
#include "node_message_box.h"
#include "node_settings.h"
#include "node_popup_menu.h"
#include "node_panel_brush.h"
#include "node_panel_layer.h"
#include "node_panel_color.h"
#include "node_panel_stroke.h"
#include "node_scroll.h"
#include "node_canvas.h"
#include "node_dialog_layer_rename.h"
#include "node_progress_bar.h"
#if defined(__OBJC__) && defined(__IOS__)
#import <Foundation/Foundation.h>
#import "GameViewController.h"
#endif
#if defined(__OBJC__) && defined(__OSX__)
#import "main.h"
#endif
#ifdef __ANDROID__
#include "main.h"
#endif
#include "node_panel_grid.h"
#include "node_panel_quick.h"
struct VRController
{
enum class kButton : uint8_t
{
Pad,
Trigger,
Menu,
Grip,
A,
COUNT,
};
enum class kAction
{
Press,
Release,
};
std::array<bool, (int)kButton::COUNT> m_buttons;
std::array<bool, (int)kButton::COUNT> m_analog_buttons;
glm::mat4 m_mat;
bool m_valid = false;
glm::vec3 get_pos() const { return m_mat[3]; }
glm::vec3 get_pos_n() const { return glm::normalize(xyz(m_mat[3])); }
virtual float get_trigger_value() const { return 1.f; }
};
class App
{
public:
static App I;
std::string data_path{ "." };
std::string work_path{ "." };
std::string rec_path{ "." };
std::thread rec_thread;
bool rec_running = false;
int rec_count = 0;
std::mutex rec_mutex;
std::condition_variable rec_cv;
std::deque<std::unique_ptr<uint8_t[]>> rec_frames;
RTT uirtt;
Sampler sampler;
Sampler sampler_stencil;
Sampler sampler_linear;
Plane m_face_plane;
Sphere sphere;
LayoutManager layout;
NodeMessageBox* msgbox;
NodeSettings* settings;
NodeBorder* sidebar = nullptr;
std::shared_ptr<NodePanelLayer> layers;
std::shared_ptr<NodePanelColor> color;
std::shared_ptr<NodePanelStroke> stroke;
std::shared_ptr<NodePanelGrid> grid;
std::shared_ptr<NodePanelBrushPreset> presets;
NodePanelQuick* quick;
std::map<kCanvasMode, NodePanelQuick::MiniState> quick_mode_state;
Node* floatings_container;
std::shared_ptr<NodePanelColor> floating_color;
std::shared_ptr<NodeColorPicker> floating_picker;
std::shared_ptr<NodePanelBrushPreset> floating_presets;
std::shared_ptr<NodePanelLayer> floating_layers;
NodeCanvas* canvas;
const uint16_t main_id = const_hash("main");
const std::array<int, 6> res_map{ 512, 1024, 1536, 2048, 4096, 8192 };
const std::array<std::string, 6> res_map_str{ "2K", "4K", "6K", "8K", "16K", "32K" };
std::string doc_name = "no-name";
std::string doc_path;
std::string doc_dir;
std::string doc_filename;
bool has_stylus = false;
bool has_vr = false;
float off_x = 0;
float off_y = 0;
float width;
float height;
bool keys[256];
bool redraw = true;
bool animate = false;
bool ui_visible = true;
bool ui_rtl = false;
bool vr_active = false;
bool vr_only = false;
VRController vr_controllers[2];
glm::mat4 vr_head;
float vr_pressure = 1.f;
glm::mat4 vr_rot{ 0 };
glm::mat4 vr_uirot{ 0 };
glm::vec2 cursor{ 0, 0 };
glm::vec2 gesture_p0;
glm::vec2 gesture_p1;
#ifdef __ANDROID__
float zoom = 3.0;
#elif __IOS__
float zoom = 2.0;
#else
float zoom = 1.0;
#endif // __ANDROID__
#if defined(__IOS__) && defined(__OBJC__)
GameViewController* ios_view;
#endif
#if defined(__OSX__) && defined(__OBJC__)
View* osx_view;
#endif
#ifdef __ANDROID__
struct android_app* and_app;
struct engine* and_engine;
#endif
std::string clipboard_get_text();
bool clipboard_set_text(const std::string& s);
void pick_image(std::function<void(std::string path)> callback);
void pick_file(std::vector<std::string> types, std::function<void(std::string path)> callback);
void pick_dir(std::function<void(std::string path)> callback);
void display_file(std::string path);
void share_file(std::string path);
void showKeyboard();
void hideKeyboard();
void initLog();
void init();
void initShaders();
void initAssets();
void initLayout();
void open_document(std::string path);
void create();
bool request_close();
void terminate();
void clear();
void tick(float dt);
void update(float dt);
bool update_ui_observer(Node* n);
bool vr_start();
void vr_stop();
void vr_update(float dt);
void vr_draw(const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose);
void vr_analog(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 force);
void vr_digital(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 axis);
void vr_draw_ui();
void async_start();
void async_update();
void async_redraw();
void async_end();
void resize(float w, float h);
void show_cursor();
void hide_cursor();
bool mouse_down(int button, float x, float y, float pressure, kEventSource source, bool eraser);
bool mouse_move(float x, float y, float pressure, kEventSource source, bool eraser);
bool mouse_up(int button, float x, float y, kEventSource source, bool eraser);
bool mouse_scroll(float x, float y, float delta);
bool mouse_cancel(int button);
bool gesture_start(const glm::vec2& p0, const glm::vec2& p1);
bool gesture_move(const glm::vec2& p0, const glm::vec2& p1);
bool gesture_end();
bool key_down(kKey key);
bool key_up(kKey key);
bool key_char(char key);
void toggle_ui();
void set_stylus();
NodeMessageBox* message_box(const std::string& title, const std::string& text, bool cancel_button = false);
void rec_clear();
void rec_loop();
void rec_start();
void rec_stop();
void rec_export(std::string path);
void init_toolbar_main();
void init_toolbar_draw();
void init_sidebar();
void init_menu_file();
void init_menu_edit();
void init_menu_layer();
void init_menu_tools();
void init_menu_about();
void dialog_usermanual();
void dialog_changelog();
void dialog_about();
void dialog_newdoc();
void dialog_save();
void dialog_save_ver();
void dialog_open();
void dialog_browse();
void dialog_export(std::string ext);
void dialog_export_layers();
void dialog_export_depth();
void dialog_export_cubes();
void dialog_layer_rename();
void dialog_resize();
void cloud_upload();
void cloud_upload_all();
void cloud_browse();
void upload(std::string filename, std::string name = "", std::function<void(float)> progress = nullptr);
void download(std::string url, std::string dest_filepath, std::function<void(float)> progress = nullptr);
bool check_license();
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title);
void brush_update();
void title_update();
void update_memory_usage(size_t bytes);
void update_rec_frames();
int res_from_index(int i);
int res_to_index(int res);
std::string res_to_string(int res);
void crash_test();
void ui_save();
void ui_restore();
void set_ui_rtl(bool rtl);
bool get_ui_rtl() const;
void cmd_convert(std::string pano_path, std::string out_path);
bool is_render_thread()
{
extern std::thread::id render_thread_id;
extern std::thread::id gl_thread;
return std::this_thread::get_id() == render_thread_id || std::this_thread::get_id() == gl_thread;
}
// don't capture a reference to this ptr as the object may be destroyed
// by the time the task is executed
template<typename T, typename R = std::result_of<T()>::type>
std::future<R> render_task_async(T task)
{
#ifdef _WIN32
extern std::deque<std::packaged_task<R()>> render_tasklist;
extern std::mutex render_task_mutex;
extern std::condition_variable render_cv;
std::packaged_task<R()> pt(task);
std::future<R> f = pt.get_future();
if (is_render_thread())
{
pt();
}
else
{
{
std::lock_guard<std::mutex> lock(render_task_mutex);
render_tasklist.push_back(std::move(pt));
}
render_cv.notify_all();
}
return f;
#endif // _WIN32
}
template<typename T, typename R = std::result_of<T()>::type>
R render_task(T task)
{
#ifdef _WIN32
extern std::deque<std::packaged_task<R()>> render_tasklist;
extern std::mutex render_task_mutex;
extern std::condition_variable render_cv;
std::packaged_task<R()> pt(task);
std::future<R> f = pt.get_future();
if (is_render_thread())
{
pt();
}
else
{
{
std::lock_guard<std::mutex> lock(render_task_mutex);
render_tasklist.push_back(std::move(pt));
}
render_cv.notify_all();
}
return f.get();
#endif // _WIN32
}
void render_sync()
{
render_task([] {});
}
};