Skip to content

Commit

Permalink
Bugfix in gui dialog (#1013)
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy authored Aug 15, 2020
1 parent 7d23bf7 commit 9ea7ac3
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 72 deletions.
12 changes: 6 additions & 6 deletions apps/ysceneitrace/ysceneitrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ void print_obj_camera(scene_camera* camera);
// Application scene
struct app_state {
// loading options
string filename = "app->yaml";
string filename = "scene.json";
string imagename = "out.png";
string outname = "out.yaml";
string outname = "out.json";
string name = "";

// scene
Expand Down Expand Up @@ -268,7 +268,7 @@ void load_scene_async(app_states* apps, const string& filename,
app->name = path{filename}.filename().string() + " [loading]";
app->filename = filename;
app->imagename = path{filename}.replace_extension(".png").string();
app->outname = path{filename}.replace_extension(".edited.yaml").string();
app->outname = path{filename}.replace_extension(".edited.json").string();
app->params = apps->params;
app->status = "load";
app->loader = std::async(std::launch::async, [app, camera_name,
Expand Down Expand Up @@ -457,14 +457,14 @@ T1* get_element(
void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
static string load_path = "", save_path = "", error_message = "";
if (draw_filedialog_button(win, "load", true, "load", load_path, false, "./",
"", "*.yaml;*.obj;*.pbrt")) {
"", "*.json;*.obj;*.pbrt")) {
load_scene_async(apps, load_path);
load_path = "";
}
continue_line(win);
if (draw_filedialog_button(win, "save", apps->selected && apps->selected->ok,
"save", save_path, true, path{save_path}.parent_path().string(),
path{save_path}.filename().string(), "*.yaml;*.obj;*.pbrt")) {
path{save_path}.filename().string(), "*.json;*.obj;*.pbrt")) {
auto app = apps->selected;
app->outname = save_path;
save_scene(app->outname, app->ioscene, app->error);
Expand Down Expand Up @@ -598,7 +598,7 @@ void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
}
end_header(win);
}
if (!app->ioscene->instances.empty() && begin_header(win, "objects")) {
if (!app->ioscene->instances.empty() && begin_header(win, "instances")) {
draw_combobox(win, "instance##2", app->selected_instance,
app->ioscene->instances, true);
if (draw_widgets(win, app->ioscene, app->selected_instance)) {
Expand Down
2 changes: 1 addition & 1 deletion apps/ysceneitraces/ysceneitraces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using namespace yocto;
// Application state
struct app_state {
// loading options
string filename = "scene.yaml";
string filename = "scene.json";
string imagename = "out.png";
string name = "";

Expand Down
10 changes: 5 additions & 5 deletions apps/ysceneview/ysceneview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void load_scene_async(
auto app = apps->states.emplace_back(new app_state{});
app->filename = filename;
app->imagename = path{filename}.replace_extension(".png").string();
app->outname = path{filename}.replace_extension(".edited.yaml").string();
app->outname = path{filename}.replace_extension(".edited.json").string();
app->name = path{app->filename}.filename().string();
app->drawgl_prms = apps->drawgl_prms;
app->status = "load";
Expand Down Expand Up @@ -417,14 +417,14 @@ T1* get_element(
void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
static auto load_path = ""s, save_path = ""s, error_message = ""s;
if (draw_filedialog_button(win, "load", true, "load", load_path, false, "./",
"", "*.yaml;*.obj;*.pbrt")) {
"", "*.json;*.obj;*.pbrt")) {
load_scene_async(apps, load_path);
load_path = "";
}
continue_line(win);
if (draw_filedialog_button(win, "save", apps->selected && apps->selected->ok,
"save", save_path, true, path{save_path}.parent_path().string(),
path{save_path}.filename().string(), "*.yaml;*.obj;*.pbrt")) {
path{save_path}.filename().string(), "*.json;*.obj;*.pbrt")) {
auto app = apps->selected;
app->outname = save_path;
save_scene(app->outname, app->ioscene, app->error);
Expand Down Expand Up @@ -514,10 +514,10 @@ void draw_widgets(gui_window* win, app_states* apps, const gui_input& input) {
}
end_header(win);
}
if (!app->ioscene->instances.empty() && begin_header(win, "objects")) {
if (!app->ioscene->instances.empty() && begin_header(win, "instances")) {
draw_combobox(
win, "instance##2", app->selected_instance, app->ioscene->instances);
if (!draw_widgets(win, app->ioscene, app->selected_instance)) {
if (draw_widgets(win, app->ioscene, app->selected_instance)) {
auto ioobject = app->selected_instance;
auto globject = get_element(
ioobject, app->ioscene->instances, app->glscene->instances);
Expand Down
4 changes: 2 additions & 2 deletions libs/yocto/yocto_sceneio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static bool load_json_scene(const string& filename, scene_model* scene,
}
};

// parse yaml reference
// parse json reference
auto get_ref = [&material_error, &get_value](const json& ejs,
const string& name, auto& value,
const auto& refs) -> bool {
Expand Down Expand Up @@ -808,7 +808,7 @@ static bool save_json_scene(const string& filename, const scene_model* scene,
0, 2 + (int)scene->shapes.size() + (int)scene->textures.size()};
if (progress_cb) progress_cb("save scene", progress.x++, progress.y);

// save yaml file
// save json file
auto js = json::object();

// asset
Expand Down
120 changes: 62 additions & 58 deletions libs/yocto_gui/yocto_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,25 +430,59 @@ struct filedialog_state {
vector<string> extensions = {};

filedialog_state() {}
filedialog_state(const string& dirname, const string& filename, bool save,
const string& filter) {
filedialog_state(const string& dirname, const string& filename,
const string& filter, bool save) {
set(dirname, filename, filter, save);
}

void set(const string& dirname, const string& filename, const string& filter,
bool save) {
this->save = save;
set_filter(filter);
set_dirname(dirname);
set_filename(filename);
_set_filter(filter);
_set_dirname(dirname);
_set_filename(filename);
}
void set_dirname(const string& name) {
dirname = name;
dirname = normalize_path(dirname);
if (dirname == "") dirname = "./";
if (dirname.back() != '/') dirname += '/';
refresh();

void _set_dirname(const string& name) {
if (exists(path{name}) && is_directory(path{name})) {
dirname = name;
} else if (exists(path{dirname}) && is_directory(path{dirname})) {
// leave it like this
} else {
dirname = std::filesystem::current_path().string();
}
dirname = canonical(path{dirname}).string();
entries.clear();
for (auto entry : directory_iterator(path{dirname})) {
if (remove_hidden && entry.path().stem().string()[0] == '.') continue;
if (entry.is_directory()) {
entries.push_back({entry.path().filename().string() + "/", true});
} else {
entries.push_back({entry.path().filename().string(), false});
}
}
std::sort(entries.begin(), entries.end(), [](auto& a, auto& b) {
if (a.second == b.second) return a.first < b.first;
return a.second;
});
}
void set_filename(const string& name) {

void _set_filename(const string& name) {
filename = name;
check_filename();
if (filename.empty()) return;
auto ext = path{filename}.extension().string();
if (std::find(extensions.begin(), extensions.end(), ext) ==
extensions.end()) {
filename = "";
return;
}
if (!save && !exists(path{dirname} / path{filename})) {
filename = "";
return;
}
}
void set_filter(const string& flt) {

void _set_filter(const string& flt) {
auto globs = vector<string>{""};
for (auto i = 0; i < flt.size(); i++) {
if (flt[i] == ';') {
Expand All @@ -468,64 +502,32 @@ struct filedialog_state {
}
}
}
void check_filename() {
if (filename.empty()) return;
auto ext = get_extension(filename);
if (std::find(extensions.begin(), extensions.end(), ext) ==
extensions.end()) {
filename = "";
return;
}
if (!save && !exists_file(dirname + filename)) {
filename = "";
return;
}
}
void select_entry(int idx) {

void select(int idx) {
if (entries[idx].second) {
set_dirname(dirname + entries[idx].first);
set((path{dirname} / path{entries[idx].first}).string(), filename, filter,
save);
} else {
set_filename(entries[idx].first);
set(dirname, entries[idx].first, filter, save);
}
}

void refresh() {
entries.clear();
for (auto entry : directory_iterator(path{dirname})) {
if (remove_hidden && entry.path().stem().string()[0] == '.') continue;
if (entry.is_directory()) {
entries.push_back({entry.path().stem().string() + "/", true});
} else {
entries.push_back({entry.path().stem().string(), false});
}
}
std::sort(entries.begin(), entries.end(), [](auto& a, auto& b) {
if (a.second == b.second) return a.first < b.first;
return a.second;
});
}

string get_path() const { return dirname + filename; }
bool exists_file(const string& filename) {
auto f = fopen(filename.c_str(), "r");
if (!f) return false;
fclose(f);
return true;
}
string get_path() const { return (path{dirname} / path{filename}).string(); }
};

bool draw_filedialog(gui_window* win, const char* lbl, string& path, bool save,
const string& dirname, const string& filename, const string& filter) {
static auto states = unordered_map<string, filedialog_state>{};
ImGui::SetNextWindowSize({500, 300}, ImGuiCond_FirstUseEver);
if (ImGui::BeginPopupModal(lbl)) {
if (states.find(lbl) == states.end()) {
states[lbl] = filedialog_state{dirname, filename, save, filter};
states[lbl] = filedialog_state{dirname, filename, filter, save};
}
auto& state = states.at(lbl);
char dir_buffer[1024];
snprintf(dir_buffer, sizeof(dir_buffer), "%s", state.dirname.c_str());
if (ImGui::InputText("dir", dir_buffer, sizeof(dir_buffer))) {
state.set_dirname(dir_buffer);
state.set(dir_buffer, state.filename, state.filter, save);
}
auto current_item = -1;
if (ImGui::ListBox(
Expand All @@ -536,17 +538,17 @@ bool draw_filedialog(gui_window* win, const char* lbl, string& path, bool save,
return true;
},
&state, (int)state.entries.size())) {
state.select_entry(current_item);
state.select(current_item);
}
char file_buffer[1024];
snprintf(file_buffer, sizeof(file_buffer), "%s", state.filename.c_str());
if (ImGui::InputText("file", file_buffer, sizeof(file_buffer))) {
state.set_filename(file_buffer);
state.set(state.dirname, file_buffer, state.filter, save);
}
char filter_buffer[1024];
snprintf(filter_buffer, sizeof(filter_buffer), "%s", state.filter.c_str());
if (ImGui::InputText("filter", filter_buffer, sizeof(filter_buffer))) {
state.set_filter(filter_buffer);
state.set(state.dirname, state.filename, filter_buffer, save);
}
auto ok = false, exit = false;
if (ImGui::Button("Ok")) {
Expand All @@ -568,10 +570,12 @@ bool draw_filedialog(gui_window* win, const char* lbl, string& path, bool save,
return false;
}
}

bool draw_filedialog_button(gui_window* win, const char* button_lbl,
bool button_active, const char* lbl, string& path, bool save,
const string& dirname, const string& filename, const string& filter) {
if (is_glmodal_open(win, lbl)) {
draw_button(win, button_lbl, button_active);
return draw_filedialog(win, lbl, path, save, dirname, filename, filter);
} else {
if (draw_button(win, button_lbl, button_active)) {
Expand Down

0 comments on commit 9ea7ac3

Please sign in to comment.