mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 11:15:07 +00:00

The purpose of this patch is to support addition, subtraction, multiplication and division without using conversion to double. To this end, we use the BigFraction class of LibCrypto. With this solution, we can store values without any losses and forward rounding as the last step before displaying.
79 lines
3 KiB
C++
79 lines
3 KiB
C++
/*
|
|
* Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "CalculatorWidget.h"
|
|
#include <LibCore/System.h>
|
|
#include <LibCrypto/NumberTheory/ModularFunctions.h>
|
|
#include <LibGUI/Action.h>
|
|
#include <LibGUI/Application.h>
|
|
#include <LibGUI/Clipboard.h>
|
|
#include <LibGUI/Icon.h>
|
|
#include <LibGUI/Menu.h>
|
|
#include <LibGUI/Menubar.h>
|
|
#include <LibGUI/Window.h>
|
|
#include <LibGfx/Bitmap.h>
|
|
#include <LibMain/Main.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|
{
|
|
TRY(Core::System::pledge("stdio recvfd sendfd rpath unix"));
|
|
auto app = TRY(GUI::Application::try_create(arguments));
|
|
|
|
TRY(Core::System::pledge("stdio recvfd sendfd rpath"));
|
|
TRY(Core::System::unveil("/res", "r"));
|
|
TRY(Core::System::unveil(nullptr, nullptr));
|
|
|
|
auto app_icon = GUI::Icon::default_icon("app-calculator"sv);
|
|
|
|
auto window = TRY(GUI::Window::try_create());
|
|
window->set_title("Calculator");
|
|
window->set_resizable(false);
|
|
window->resize(250, 215);
|
|
|
|
auto widget = TRY(window->try_set_main_widget<CalculatorWidget>());
|
|
|
|
window->set_icon(app_icon.bitmap_for_size(16));
|
|
|
|
auto& file_menu = window->add_menu("&File");
|
|
file_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
|
|
GUI::Application::the()->quit();
|
|
}));
|
|
|
|
auto& edit_menu = window->add_menu("&Edit");
|
|
edit_menu.add_action(GUI::CommonActions::make_copy_action([&](auto&) {
|
|
GUI::Clipboard::the().set_plain_text(widget->get_entry());
|
|
}));
|
|
edit_menu.add_action(GUI::CommonActions::make_paste_action([&](auto&) {
|
|
auto clipboard = GUI::Clipboard::the().fetch_data_and_type();
|
|
if (clipboard.mime_type == "text/plain") {
|
|
if (!clipboard.data.is_empty()) {
|
|
widget->set_entry(Crypto::BigFraction(StringView(clipboard.data)));
|
|
}
|
|
}
|
|
}));
|
|
|
|
auto& constants_menu = window->add_menu("&Constants");
|
|
auto const power = Crypto::NumberTheory::Power("10"_bigint, "10"_bigint);
|
|
|
|
constants_menu.add_action(GUI::Action::create("&Pi", TRY(Gfx::Bitmap::try_load_from_file("/res/icons/calculator/pi.png"sv)), [&](auto&) {
|
|
widget->set_entry(Crypto::BigFraction { Crypto::SignedBigInteger(31415926535), power });
|
|
}));
|
|
constants_menu.add_action(GUI::Action::create("&Euler's Number", TRY(Gfx::Bitmap::try_load_from_file("/res/icons/calculator/eulers_number.png"sv)), [&](auto&) {
|
|
widget->set_entry(Crypto::BigFraction { Crypto::SignedBigInteger(27182818284), power });
|
|
}));
|
|
constants_menu.add_action(GUI::Action::create("&Phi", TRY(Gfx::Bitmap::try_load_from_file("/res/icons/calculator/phi.png"sv)), [&](auto&) {
|
|
widget->set_entry(Crypto::BigFraction { Crypto::SignedBigInteger(16180339887), power });
|
|
}));
|
|
|
|
auto& help_menu = window->add_menu("&Help");
|
|
help_menu.add_action(GUI::CommonActions::make_about_action("Calculator", app_icon, window));
|
|
|
|
window->show();
|
|
|
|
return app->exec();
|
|
}
|