refactor file explorer to parse extensions/hidden entries on render

This commit is contained in:
Matthew Berry 2021-06-27 16:22:55 -10:00
parent 6b516a6567
commit bd7e588fdd
2 changed files with 22 additions and 24 deletions

View file

@ -43,7 +43,7 @@ class SDLOpenGLImGuiFrontend < Frontend
@opengl_info = OpenGLInfo.new @opengl_info = OpenGLInfo.new
@io = setup_imgui @io = setup_imgui
@file_explorer = ImGui::FileExplorer.new(ROM_EXTENSIONS) @file_explorer = ImGui::FileExplorer.new
@open_first_frame = @controller.class == StubbedController @open_first_frame = @controller.class == StubbedController
LibSDL.gl_set_swap_interval(1) if @open_first_frame LibSDL.gl_set_swap_interval(1) if @open_first_frame
@ -59,14 +59,14 @@ class SDLOpenGLImGuiFrontend < Frontend
render_imgui render_imgui
LibSDL.gl_swap_window(@window) LibSDL.gl_swap_window(@window)
update_draw_count update_draw_count
load_new_rom(@file_explorer.chosen_rom.not_nil!.to_s) if @file_explorer.chosen_rom load_new_rom(@file_explorer.selection.not_nil!.to_s) if @file_explorer.selection
end end
end end
private def load_new_rom(rom : String?) : Nil private def load_new_rom(rom : String?) : Nil
LibSDL.close_audio(1) LibSDL.close_audio(1)
@controller = init_controller(nil, rom) @controller = init_controller(nil, rom)
@file_explorer.clear_chosen_rom @file_explorer.clear_selection
LibSDL.set_window_size(@window, @controller.window_width * SCALE, @controller.window_height * SCALE) LibSDL.set_window_size(@window, @controller.window_width * SCALE, @controller.window_height * SCALE)
LibSDL.set_window_position(@window, LibSDL::WindowPosition::CENTERED, LibSDL::WindowPosition::CENTERED) LibSDL.set_window_position(@window, LibSDL::WindowPosition::CENTERED, LibSDL::WindowPosition::CENTERED)
LibGL.viewport(0, 0, @controller.window_width * SCALE, @controller.window_height * SCALE) LibGL.viewport(0, 0, @controller.window_width * SCALE, @controller.window_height * SCALE)
@ -161,7 +161,7 @@ class SDLOpenGLImGuiFrontend < Frontend
end end
end end
@file_explorer.render(open_file_explorer) @file_explorer.render(open_file_explorer, ROM_EXTENSIONS)
if @enable_overlay if @enable_overlay
ImGui.set_next_window_pos(ImGui::ImVec2.new 10, overlay_height) ImGui.set_next_window_pos(ImGui::ImVec2.new 10, overlay_height)

View file

@ -1,6 +1,5 @@
module ImGui module ImGui
class FileExplorer class FileExplorer
property extensions = [] of String
@matched_entries = [] of Entry @matched_entries = [] of Entry
@selected_entry_idx = 0 @selected_entry_idx = 0
@match_hidden = false @match_hidden = false
@ -8,13 +7,13 @@ module ImGui
@path : Path @path : Path
@name = "File Explorer" @name = "File Explorer"
getter chosen_rom : Path? = nil getter selection : Path? = nil
def initialize(@extensions = [] of String, @path = Path[explorer_dir].expand(home: true)) def initialize(@path = Path[explorer_dir].expand(home: true))
gather_entries gather_entries
end end
def render(open_popup : Bool) : Nil def render(open_popup : Bool, extensions : Array(String)?) : Nil
ImGui.open_popup(@name) if open_popup ImGui.open_popup(@name) if open_popup
center = ImGui.get_main_viewport.get_center center = ImGui.get_main_viewport.get_center
ImGui.set_next_window_pos(center, ImGui::ImGuiCond::Appearing, ImGui::ImVec2.new(0.5, 0.5)) ImGui.set_next_window_pos(center, ImGui::ImGuiCond::Appearing, ImGui::ImVec2.new(0.5, 0.5))
@ -29,6 +28,8 @@ module ImGui
height = Math.min(display_size.y - 40, 16 * ImGui.get_text_line_height_with_spacing) height = Math.min(display_size.y - 40, 16 * ImGui.get_text_line_height_with_spacing)
if ImGui.begin_list_box("", ImGui::ImVec2.new(width, height)) if ImGui.begin_list_box("", ImGui::ImVec2.new(width, height))
@matched_entries.each_with_index do |entry, idx| @matched_entries.each_with_index do |entry, idx|
next if entry[:hidden] && !@match_hidden
next if entry[:file?] && !extensions.nil? && !extensions.includes?(entry[:extension])
is_selected = idx == @selected_entry_idx is_selected = idx == @selected_entry_idx
if entry[:file?] if entry[:file?]
letter = 'F' letter = 'F'
@ -37,7 +38,7 @@ module ImGui
letter = 'D' letter = 'D'
flags = ImGui::ImGuiSelectableFlags::None | ImGui::ImGuiSelectableFlags::AllowDoubleClick flags = ImGui::ImGuiSelectableFlags::None | ImGui::ImGuiSelectableFlags::AllowDoubleClick
end end
if ImGui.selectable("[#{letter}] #{entry[:name]}", is_selected, flags) if ImGui.selectable("[#{letter}] #{entry[:name]}#{'/' unless entry[:file?]}", is_selected, flags)
if entry[:file?] if entry[:file?]
@selected_entry_idx = idx @selected_entry_idx = idx
open_file if ImGui.is_mouse_double_clicked(ImGui::ImGuiMouseButton::Left) open_file if ImGui.is_mouse_double_clicked(ImGui::ImGuiMouseButton::Left)
@ -54,19 +55,18 @@ module ImGui
ImGui.same_line ImGui.same_line
ImGui.close_current_popup if ImGui.button "Cancel" ImGui.close_current_popup if ImGui.button "Cancel"
ImGui.same_line(spacing: 10) ImGui.same_line(spacing: 10)
gather_entries if ImGui.checkbox("Show hidden files?", pointerof(@match_hidden)) ImGui.checkbox("Show hidden files?", pointerof(@match_hidden))
ImGui.end_group ImGui.end_group
ImGui.end_popup ImGui.end_popup
end end
end end
def clear_chosen_rom : Nil def clear_selection : Nil
@chosen_rom = nil @selection = nil
end end
private def open_file : Nil private def open_file : Nil
selected_item = @matched_entries[@selected_entry_idx] @selection = (@path / @matched_entries[@selected_entry_idx][:name]).normalize
@chosen_rom = (@path / selected_item[:name]).normalize
ImGui.close_current_popup ImGui.close_current_popup
set_explorer_dir @path.to_s set_explorer_dir @path.to_s
end end
@ -78,16 +78,14 @@ module ImGui
private def gather_entries : Nil private def gather_entries : Nil
@matched_entries.clear @matched_entries.clear
extensions.each do |extension| Dir.each_child(@path) do |name|
path = @path / "*.#{extension}" is_file = !Dir.exists?(@path / name)
@matched_entries.concat(Dir[path, match_hidden: @match_hidden].map { |file| Entry.new(name: Path[file].basename, file?: true) }) rpart = name.rpartition('.')
extension = rpart[2] unless rpart[1].size == 0
hidden = name.starts_with?('.')
@matched_entries << Entry.new(name: name, file?: is_file, extension: extension, hidden: hidden)
end end
Dir.each_child(@path) do |child| @matched_entries << Entry.new(name: "..", file?: false, extension: nil, hidden: false)
next unless Dir.exists?(@path / child)
next if !@match_hidden && child.starts_with? '.'
@matched_entries << Entry.new(name: "#{child}/", file?: false)
end
@matched_entries << Entry.new(name: "..", file?: false)
@matched_entries.sort! do |a, b| @matched_entries.sort! do |a, b|
if a[:file?] && !b[:file?] if a[:file?] && !b[:file?]
1 1
@ -99,6 +97,6 @@ module ImGui
end end
end end
private alias Entry = NamedTuple(name: String, file?: Bool) private alias Entry = NamedTuple(name: String, file?: Bool, extension: String?, hidden: Bool)
end end
end end