1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:58:11 +00:00
serenity/Userland/Applications/Magnifier/main.cpp
Timothy Flynn 25e0ab3ee4 Userland: Tighten promises by removing 'proc' where it isn't used
This is a partial revert of commit 7af5eef. After 97d15e9, the 'proc'
promise is not needed for operations using getsid().

This also fixes launching several applications in which 7af5eef added
the 'proc' promise only in the second call to pledge().
2022-10-03 17:09:21 +01:00

206 lines
8.8 KiB
C++

/*
* Copyright (c) 2021, Valtteri Koskivuori <vkoskiv@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "MagnifierWidget.h"
#include <AK/LexicalPath.h>
#include <LibCore/System.h>
#include <LibFileSystemAccessClient/Client.h>
#include <LibGUI/ActionGroup.h>
#include <LibGUI/Application.h>
#include <LibGUI/Icon.h>
#include <LibGUI/Menu.h>
#include <LibGUI/Menubar.h>
#include <LibGUI/MessageBox.h>
#include <LibGUI/Window.h>
#include <LibGfx/BMPWriter.h>
#include <LibGfx/Filters/ColorBlindnessFilter.h>
#include <LibGfx/PNGWriter.h>
#include <LibGfx/QOIWriter.h>
#include <LibMain/Main.h>
static ErrorOr<ByteBuffer> dump_bitmap(RefPtr<Gfx::Bitmap> bitmap, AK::StringView extension)
{
if (extension == "bmp") {
Gfx::BMPWriter dumper;
return dumper.dump(bitmap);
} else if (extension == "png") {
return Gfx::PNGWriter::encode(*bitmap);
} else if (extension == "qoi") {
return Gfx::QOIWriter::encode(*bitmap);
} else {
return Error::from_string_literal("invalid image format");
}
}
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio cpath rpath recvfd sendfd unix"));
auto app = TRY(GUI::Application::try_create(arguments));
TRY(Core::System::unveil("/tmp/session/%sid/portal/filesystemaccess", "rw"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil(nullptr, nullptr));
auto app_icon = GUI::Icon::default_icon("app-magnifier"sv);
// 4px on each side for padding
constexpr int window_dimensions = 200 + 4 + 4;
auto window = GUI::Window::construct();
window->set_title("Magnifier");
window->resize(window_dimensions, window_dimensions);
window->set_minimizable(false);
window->set_icon(app_icon.bitmap_for_size(16));
auto magnifier = TRY(window->try_set_main_widget<MagnifierWidget>());
auto file_menu = TRY(window->try_add_menu("&File"));
TRY(file_menu->try_add_action(GUI::CommonActions::make_quit_action([&](auto&) {
app->quit();
})));
TRY(file_menu->try_add_action(GUI::CommonActions::make_save_as_action([&](auto&) {
AK::String filename = "file for saving";
auto do_save = [&]() -> ErrorOr<void> {
auto response = FileSystemAccessClient::Client::the().try_save_file(window, "Capture", "png");
if (response.is_error())
return {};
auto file = response.release_value();
auto path = AK::LexicalPath(file->filename());
filename = path.basename();
auto encoded = TRY(dump_bitmap(magnifier->current_bitmap(), path.extension()));
if (!file->write(encoded.data(), encoded.size())) {
return Error::from_errno(file->error());
}
return {};
};
auto result = do_save();
if (result.is_error()) {
GUI::MessageBox::show(window, "Unable to save file.\n"sv, "Error"sv, GUI::MessageBox::Type::Error);
warnln("Error saving bitmap to {}: {}", filename, result.error().string_literal());
}
})));
auto size_action_group = make<GUI::ActionGroup>();
auto two_x_action = GUI::Action::create_checkable(
"&2x", { Key_2 }, [&](auto&) {
magnifier->set_scale_factor(2);
});
auto four_x_action = GUI::Action::create_checkable(
"&4x", { Key_4 }, [&](auto&) {
magnifier->set_scale_factor(4);
});
auto eight_x_action = GUI::Action::create_checkable(
"&8x", { Key_8 }, [&](auto&) {
magnifier->set_scale_factor(8);
});
auto pause_action = GUI::Action::create_checkable(
"&Pause Capture", { Key_Space }, [&](auto& action) {
magnifier->pause_capture(action.is_checked());
});
size_action_group->add_action(two_x_action);
size_action_group->add_action(four_x_action);
size_action_group->add_action(eight_x_action);
size_action_group->set_exclusive(true);
auto view_menu = TRY(window->try_add_menu("&View"));
TRY(view_menu->try_add_action(two_x_action));
TRY(view_menu->try_add_action(four_x_action));
TRY(view_menu->try_add_action(eight_x_action));
two_x_action->set_checked(true);
TRY(view_menu->try_add_separator());
TRY(view_menu->try_add_action(pause_action));
auto timeline_menu = TRY(window->try_add_menu("&Timeline"));
auto previous_frame_action = GUI::Action::create(
"&Previous frame", { Key_Left }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png"sv)), [&](auto&) {
pause_action->set_checked(true);
magnifier->pause_capture(true);
magnifier->display_previous_frame();
});
auto next_frame_action = GUI::Action::create(
"&Next frame", { Key_Right }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png"sv)), [&](auto&) {
pause_action->set_checked(true);
magnifier->pause_capture(true);
magnifier->display_next_frame();
});
TRY(timeline_menu->try_add_action(previous_frame_action));
TRY(timeline_menu->try_add_action(next_frame_action));
auto accessibility_menu = TRY(window->try_add_menu("&Accessibility"));
auto default_accessibility_action = GUI::Action::create_checkable("Default - non-impaired", { Mod_AltGr, Key_1 }, [&](auto&) {
magnifier->set_color_filter(nullptr);
});
default_accessibility_action->set_checked(true);
auto pratanopia_accessibility_action = GUI::Action::create_checkable("Protanopia", { Mod_AltGr, Key_2 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_protanopia());
});
auto pratanomaly_accessibility_action = GUI::Action::create_checkable("Protanomaly", { Mod_AltGr, Key_3 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_protanomaly());
});
auto tritanopia_accessibility_action = GUI::Action::create_checkable("Tritanopia", { Mod_AltGr, Key_4 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_tritanopia());
});
auto tritanomaly_accessibility_action = GUI::Action::create_checkable("Tritanomaly", { Mod_AltGr, Key_5 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_tritanomaly());
});
auto deuteranopia_accessibility_action = GUI::Action::create_checkable("Deuteranopia", { Mod_AltGr, Key_6 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_deuteranopia());
});
auto deuteranomaly_accessibility_action = GUI::Action::create_checkable("Deuteranomaly", { Mod_AltGr, Key_7 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_deuteranomaly());
});
auto achromatopsia_accessibility_action = GUI::Action::create_checkable("Achromatopsia", { Mod_AltGr, Key_8 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_achromatopsia());
});
auto achromatomaly_accessibility_action = GUI::Action::create_checkable("Achromatomaly", { Mod_AltGr, Key_9 }, [&](auto&) {
magnifier->set_color_filter(Gfx::ColorBlindnessFilter::create_achromatomaly());
});
auto preview_type_action_group = make<GUI::ActionGroup>();
preview_type_action_group->set_exclusive(true);
preview_type_action_group->add_action(*default_accessibility_action);
preview_type_action_group->add_action(*pratanopia_accessibility_action);
preview_type_action_group->add_action(*pratanomaly_accessibility_action);
preview_type_action_group->add_action(*tritanopia_accessibility_action);
preview_type_action_group->add_action(*tritanomaly_accessibility_action);
preview_type_action_group->add_action(*deuteranopia_accessibility_action);
preview_type_action_group->add_action(*deuteranomaly_accessibility_action);
preview_type_action_group->add_action(*achromatopsia_accessibility_action);
preview_type_action_group->add_action(*achromatomaly_accessibility_action);
TRY(accessibility_menu->try_add_action(default_accessibility_action));
TRY(accessibility_menu->try_add_action(pratanopia_accessibility_action));
TRY(accessibility_menu->try_add_action(pratanomaly_accessibility_action));
TRY(accessibility_menu->try_add_action(tritanopia_accessibility_action));
TRY(accessibility_menu->try_add_action(tritanomaly_accessibility_action));
TRY(accessibility_menu->try_add_action(deuteranopia_accessibility_action));
TRY(accessibility_menu->try_add_action(deuteranomaly_accessibility_action));
TRY(accessibility_menu->try_add_action(achromatopsia_accessibility_action));
TRY(accessibility_menu->try_add_action(achromatomaly_accessibility_action));
auto help_menu = TRY(window->try_add_menu("&Help"));
help_menu->add_action(GUI::CommonActions::make_about_action("Magnifier", app_icon, window));
window->show();
return app->exec();
}