From 102d345a8fde33be1e814f0a5e848bd40015bf84 Mon Sep 17 00:00:00 2001 From: Mohsan Ali Date: Fri, 3 Sep 2021 23:36:13 +0500 Subject: [PATCH] ImageViewer: Enable and disable navigation Before there was dialogs to indicate if current file is last or first. So in this commit, I added functionality to enable and disable forward and backward navigation based on if the next file is avialable or not and if the pervious file is avialable or not, respectively. ImageViewer: Refactor code and init data Data intialization was not happening properly, now I did Initializations properly so that navigation can work from the very first image. --- .../Applications/ImageViewer/ViewWidget.cpp | 68 +++++++++++-------- .../Applications/ImageViewer/ViewWidget.h | 8 ++- Userland/Applications/ImageViewer/main.cpp | 23 +++++-- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Userland/Applications/ImageViewer/ViewWidget.cpp b/Userland/Applications/ImageViewer/ViewWidget.cpp index 93b4b6ac6a..c851668ec7 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.cpp +++ b/Userland/Applications/ImageViewer/ViewWidget.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2021, Andreas Kling * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021, Mohsan Ali * * SPDX-License-Identifier: BSD-2-Clause */ @@ -60,42 +61,52 @@ void ViewWidget::rotate(Gfx::RotationDirection rotation_direction) resize_window(); } +bool ViewWidget::is_next_available() const +{ + if (m_current_index.has_value()) + return m_current_index.value() + 1 < m_files_in_same_dir.size(); + return false; +} + +bool ViewWidget::is_previous_available() const +{ + if (m_current_index.has_value()) + return m_current_index.value() > 0; + return false; +} + +Vector ViewWidget::load_files_from_directory(const String& path) const +{ + Vector files_in_directory; + + auto current_dir = LexicalPath(path).parent().string(); + Core::DirIterator iterator(current_dir, Core::DirIterator::Flags::SkipDots); + while (iterator.has_next()) { + String file = iterator.next_full_path(); + if (!Gfx::Bitmap::is_path_a_supported_image_format(file)) + continue; + files_in_directory.append(file); + } + return files_in_directory; +} + +void ViewWidget::set_path(const String& path) +{ + m_path = path; + m_files_in_same_dir = load_files_from_directory(path); + m_current_index = m_files_in_same_dir.find_first_index(path); +} + void ViewWidget::navigate(Directions direction) { - if (m_path == nullptr) - return; - - auto current_dir = LexicalPath(m_path).parent().string(); - - if (m_files_in_same_dir.is_empty()) { - Core::DirIterator iterator(current_dir, Core::DirIterator::Flags::SkipDots); - while (iterator.has_next()) { - String file = iterator.next_full_path(); - if (!Gfx::Bitmap::is_path_a_supported_image_format(file)) - continue; - m_files_in_same_dir.append(file); - } - } - - auto current_index = m_files_in_same_dir.find_first_index(m_path); - if (!current_index.has_value()) { + if (!m_current_index.has_value()) { return; } - size_t index = current_index.value(); + auto index = m_current_index.value(); if (direction == Directions::Back) { - if (index == 0) { - GUI::MessageBox::show(window(), "This is the first file.", "Cannot open image", GUI::MessageBox::Type::Error); - return; - } - index--; } else if (direction == Directions::Forward) { - if (index == m_files_in_same_dir.size() - 1) { - GUI::MessageBox::show(window(), "This is the last file.", "Cannot open image", GUI::MessageBox::Type::Error); - return; - } - index++; } else if (direction == Directions::First) { index = 0; @@ -103,6 +114,7 @@ void ViewWidget::navigate(Directions direction) index = m_files_in_same_dir.size() - 1; } + m_current_index = index; this->load_from_file(m_files_in_same_dir.at(index)); } diff --git a/Userland/Applications/ImageViewer/ViewWidget.h b/Userland/Applications/ImageViewer/ViewWidget.h index dc68b23eb9..00ed34df0e 100644 --- a/Userland/Applications/ImageViewer/ViewWidget.h +++ b/Userland/Applications/ImageViewer/ViewWidget.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021, Mohsan Ali * * SPDX-License-Identifier: BSD-2-Clause */ @@ -34,8 +35,12 @@ public: int toolbar_height() { return m_toolbar_height; } bool scaled_for_first_image() { return m_scaled_for_first_image; } void set_scaled_for_first_image(bool val) { m_scaled_for_first_image = val; } + void set_path(const String& path); void resize_window(); + bool is_next_available() const; + bool is_previous_available() const; + void clear(); void flip(Gfx::Orientation); void rotate(Gfx::RotationDirection); @@ -59,10 +64,10 @@ private: virtual void drop_event(GUI::DropEvent&) override; void set_bitmap(const Gfx::Bitmap* bitmap); - void relayout(); void reset_view(); void animate(); + Vector load_files_from_directory(const String& path) const; String m_path; RefPtr m_bitmap; @@ -80,6 +85,7 @@ private: Gfx::IntPoint m_click_position; Gfx::FloatPoint m_saved_pan_origin; Vector m_files_in_same_dir; + Optional m_current_index; }; } diff --git a/Userland/Applications/ImageViewer/main.cpp b/Userland/Applications/ImageViewer/main.cpp index 7a31c52786..c755d45c3e 100644 --- a/Userland/Applications/ImageViewer/main.cpp +++ b/Userland/Applications/ImageViewer/main.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Mohsan Ali * * SPDX-License-Identifier: BSD-2-Clause */ @@ -77,6 +78,9 @@ int main(int argc, char** argv) auto& main_toolbar = toolbar_container.add(); auto& widget = root_widget.add(); + if (path) { + widget.set_path(path); + } widget.on_scale_change = [&](int scale) { if (!widget.bitmap()) { window->set_title("Image Viewer"); @@ -100,7 +104,10 @@ int main(int argc, char** argv) return; window->move_to_front(); - widget.load_from_file(urls.first().path()); + + auto path = urls.first().path(); + widget.set_path(path); + widget.load_from_file(path); for (size_t i = 1; i < urls.size(); ++i) { Desktop::Launcher::open(URL::create_with_file_protocol(urls[i].path().characters()), "/bin/ImageViewer"); @@ -117,6 +124,7 @@ int main(int argc, char** argv) [&](auto&) { auto path = GUI::FilePicker::get_open_filepath(window, "Open Image"); if (path.has_value()) { + widget.set_path(path.value()); widget.load_from_file(path.value()); } }); @@ -231,19 +239,22 @@ int main(int argc, char** argv) if (widget.bitmap()) GUI::Clipboard::the().set_bitmap(*widget.bitmap()); }); - widget.on_image_change = [&](const Gfx::Bitmap* bitmap) { bool should_enable_image_actions = (bitmap != nullptr); + bool should_enable_forward_actions = (widget.is_next_available() && should_enable_image_actions); + bool should_enable_backward_actions = (widget.is_previous_available() && should_enable_image_actions); delete_action->set_enabled(should_enable_image_actions); rotate_left_action->set_enabled(should_enable_image_actions); rotate_right_action->set_enabled(should_enable_image_actions); vertical_flip_action->set_enabled(should_enable_image_actions); horizontal_flip_action->set_enabled(should_enable_image_actions); desktop_wallpaper_action->set_enabled(should_enable_image_actions); - go_first_action->set_enabled(should_enable_image_actions); - go_back_action->set_enabled(should_enable_image_actions); - go_forward_action->set_enabled(should_enable_image_actions); - go_last_action->set_enabled(should_enable_image_actions); + + go_first_action->set_enabled(should_enable_backward_actions); + go_back_action->set_enabled(should_enable_backward_actions); + go_forward_action->set_enabled(should_enable_forward_actions); + go_last_action->set_enabled(should_enable_forward_actions); + zoom_in_action->set_enabled(should_enable_image_actions); reset_zoom_action->set_enabled(should_enable_image_actions); zoom_out_action->set_enabled(should_enable_image_actions);