From 14a99bb22d70b184d7535270eb450b807790fe50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Fri, 26 May 2023 21:32:20 +0200 Subject: [PATCH] Calendar: Use new GML compiler --- .../Tools/CodeGenerators/GMLCompiler/main.cpp | 6 +- .../Applications/Calendar/AddEventDialog.cpp | 143 ++--------------- .../Applications/Calendar/AddEventDialog.gml | 2 +- .../Applications/Calendar/AddEventDialog.h | 20 +-- .../Applications/Calendar/AddEventWidget.cpp | 148 ++++++++++++++++++ .../Applications/Calendar/AddEventWidget.h | 46 ++++++ Userland/Applications/Calendar/CMakeLists.txt | 11 +- .../Applications/Calendar/CalendarWidget.cpp | 4 +- ...{CalendarWindow.gml => CalendarWidget.gml} | 4 +- .../Applications/Calendar/CalendarWidget.h | 4 + 10 files changed, 223 insertions(+), 165 deletions(-) create mode 100644 Userland/Applications/Calendar/AddEventWidget.cpp create mode 100644 Userland/Applications/Calendar/AddEventWidget.h rename Userland/Applications/Calendar/{CalendarWindow.gml => CalendarWidget.gml} (80%) diff --git a/Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp b/Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp index bc6a6b66d0..c06adea9c3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/GMLCompiler/main.cpp @@ -179,7 +179,9 @@ static ErrorOr> generate_enum_initializer_for(StringView proper { "button_style"sv, "Gfx::ButtonStyle"sv }, { "opportunistic_resizee"sv, "GUI::Splitter::OpportunisticResizee"sv }, { "checkbox_position"sv, "GUI::CheckBox::CheckBoxPosition"sv }, - { "button_style"sv, "Gfx::ButtonStyle"sv } + { "button_style"sv, "Gfx::ButtonStyle"sv }, + { "mode"sv, "GUI::TextEditor::Mode"sv }, + { "font_weight"sv, "Gfx::FontWeight"sv }, }; auto const& enum_type_name = enum_properties.get(property_name); @@ -352,6 +354,8 @@ static ErrorOr generate_cpp(NonnullRefPtr gml, Lexica // For Gfx::ColorRole TRY(String::from_utf8(""sv)), TRY(String::from_utf8(""sv)), + // For Gfx::FontWeight + TRY(String::from_utf8(""sv)), }; TRY(necessary_includes.try_set_from(always_necessary_includes)); for (auto const& include : necessary_includes) diff --git a/Userland/Applications/Calendar/AddEventDialog.cpp b/Userland/Applications/Calendar/AddEventDialog.cpp index 0609815cc8..c26eeb8284 100644 --- a/Userland/Applications/Calendar/AddEventDialog.cpp +++ b/Userland/Applications/Calendar/AddEventDialog.cpp @@ -7,7 +7,7 @@ */ #include "AddEventDialog.h" -#include +#include "AddEventWidget.h" #include #include #include @@ -25,12 +25,8 @@ namespace Calendar { -static constexpr StringView DATE_FORMAT = "%Y-%m-%d"sv; - AddEventDialog::AddEventDialog(Core::DateTime date_time, EventManager& event_manager, Window* parent_window) : Dialog(parent_window) - , m_start_date_time(Core::DateTime::create(date_time.year(), date_time.month(), date_time.day(), 12, 0)) - , m_end_date_time(Core::DateTime::from_timestamp(m_start_date_time.timestamp() + (15 * 60))) , m_event_manager(event_manager) { resize(360, 140); @@ -38,113 +34,16 @@ AddEventDialog::AddEventDialog(Core::DateTime date_time, EventManager& event_man set_resizable(false); set_icon(parent_window->icon()); - dbgln("start time: {}", m_start_date_time.to_string().release_value_but_fixme_should_propagate_errors()); - dbgln("end time: {}", m_end_date_time.to_string().release_value_but_fixme_should_propagate_errors()); + auto start_date_time = Core::DateTime::create(date_time.year(), date_time.month(), date_time.day(), 12, 0); + auto main_widget = MUST(AddEventWidget::create(this, + start_date_time, Core::DateTime::from_timestamp(start_date_time.timestamp() + (15 * 60)))); - auto widget = set_main_widget(); - widget->load_from_gml(add_event_dialog_gml).release_value_but_fixme_should_propagate_errors(); - - auto& event_title_textbox = *widget->find_descendant_of_type_named("event_title_textbox"); - event_title_textbox.set_focus(true); - - m_start_date_box = *widget->find_descendant_of_type_named("start_date"); - - auto calendar_date_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/calendar-date.png"sv).release_value_but_fixme_should_propagate_errors(); - - auto& pick_start_date_button = *widget->find_descendant_of_type_named("pick_start_date"); - pick_start_date_button.set_icon(calendar_date_icon); - pick_start_date_button.on_click = [&](auto) { - if (auto new_date = GUI::DatePicker::show(this, "Pick Start Date"_string, m_start_date_time); new_date.has_value()) { - m_start_date_time.set_date(new_date.value()); - if (m_end_date_time < m_start_date_time) { - m_end_date_time.set_date(new_date.value()); - update_end_date(); - } - update_duration(); - - m_start_date_box->set_text(MUST(m_start_date_time.to_string(DATE_FORMAT))); - } - }; - - m_start_hour_box = *widget->find_descendant_of_type_named("start_hour"); - m_start_minute_box = *widget->find_descendant_of_type_named("start_minute"); - - m_end_date_box = *widget->find_descendant_of_type_named("end_date"); - - auto& pick_end_date_button = *widget->find_descendant_of_type_named("pick_end_date"); - pick_end_date_button.set_icon(calendar_date_icon); - pick_end_date_button.on_click = [&](auto) { - if (auto new_date = GUI::DatePicker::show(this, "Pick End Date"_string, m_end_date_time); new_date.has_value()) { - m_end_date_time.set_date(new_date.value()); - if (m_end_date_time < m_start_date_time) { - m_start_date_time.set_date(new_date.value()); - update_start_date(); - } - update_duration(); - - m_end_date_box->set_text(MUST(m_end_date_time.to_string(DATE_FORMAT))); - } - }; - - m_end_hour_box = *widget->find_descendant_of_type_named("end_hour"); - m_end_minute_box = *widget->find_descendant_of_type_named("end_minute"); - - m_duration_hour_box = *widget->find_descendant_of_type_named("duration_hour"); - m_duration_minute_box = *widget->find_descendant_of_type_named("duration_minute"); - - auto& ok_button = *widget->find_descendant_of_type_named("ok_button"); - ok_button.on_click = [&](auto) { - auto successful = add_event_to_calendar().release_value_but_fixme_should_propagate_errors(); - if (!successful) - return; - done(ExecResult::OK); - }; - - auto& cancel_button = *widget->find_descendant_of_type_named("cancel_button"); - cancel_button.on_click = [&](auto) { done(ExecResult::Cancel); }; - - auto update_starting_input_values = [&, this]() { - auto hour = m_start_hour_box->value(); - auto minute = m_start_minute_box->value(); - m_start_date_time.set_time_only(hour, minute); - if (m_end_date_time < m_start_date_time) { - m_end_date_time.set_time_only(hour, minute); - update_end_date(); - } - update_duration(); - }; - auto update_ending_input_values = [&, this]() { - auto hour = m_end_hour_box->value(); - auto minute = m_end_minute_box->value(); - m_end_date_time.set_time_only(hour, minute); - if (m_end_date_time < m_start_date_time) { - m_start_date_time.set_time_only(hour, minute); - update_start_date(); - } - update_duration(); - }; - auto update_duration_input_values = [&, this]() { - auto hour = m_duration_hour_box->value(); - auto minute = m_duration_minute_box->value(); - m_end_date_time = Core::DateTime::from_timestamp(m_start_date_time.timestamp() + (hour * 60 + minute) * 60); - update_end_date(); - }; - - m_start_hour_box->on_change = [update_starting_input_values](auto) { update_starting_input_values(); }; - m_start_minute_box->on_change = [update_starting_input_values](auto) { update_starting_input_values(); }; - m_end_hour_box->on_change = [update_ending_input_values](auto) { update_ending_input_values(); }; - m_end_minute_box->on_change = [update_ending_input_values](auto) { update_ending_input_values(); }; - m_duration_hour_box->on_change = [update_duration_input_values](auto) { update_duration_input_values(); }; - m_duration_minute_box->on_change = [update_duration_input_values](auto) { update_duration_input_values(); }; - - update_start_date(); - update_end_date(); - update_duration(); + set_main_widget(main_widget); } -ErrorOr AddEventDialog::add_event_to_calendar() +ErrorOr AddEventDialog::add_event_to_calendar(Core::DateTime start_date_time, Core::DateTime end_date_time) { - if (m_end_date_time < m_start_date_time) { + if (end_date_time < start_date_time) { GUI::MessageBox::show_error(this, "The end date has to be after the start date."sv); return false; } @@ -152,35 +51,11 @@ ErrorOr AddEventDialog::add_event_to_calendar() auto summary = find_descendant_of_type_named("event_title_textbox")->get_text(); m_event_manager.add_event(Event { .summary = TRY(String::from_byte_string(summary)), - .start = m_start_date_time, - .end = m_end_date_time, + .start = start_date_time, + .end = end_date_time, }); return true; } -void AddEventDialog::update_start_date() -{ - m_start_date_box->set_text(MUST(m_start_date_time.to_string(DATE_FORMAT))); - m_start_hour_box->set_value(m_start_date_time.hour(), GUI::AllowCallback::No); - m_start_minute_box->set_value(m_start_date_time.minute(), GUI::AllowCallback::No); -} - -void AddEventDialog::update_end_date() -{ - m_end_date_box->set_text(MUST(m_end_date_time.to_string(DATE_FORMAT))); - m_end_hour_box->set_value(m_end_date_time.hour(), GUI::AllowCallback::No); - m_end_minute_box->set_value(m_end_date_time.minute(), GUI::AllowCallback::No); -} - -void AddEventDialog::update_duration() -{ - auto difference_in_seconds = m_end_date_time.timestamp() - m_start_date_time.timestamp(); - auto hours = difference_in_seconds / (60 * 60); - auto minutes = (difference_in_seconds - hours * (60 * 60)) / 60; - - m_duration_hour_box->set_value(hours, GUI::AllowCallback::No); - m_duration_minute_box->set_value(minutes, GUI::AllowCallback::No); -} - } diff --git a/Userland/Applications/Calendar/AddEventDialog.gml b/Userland/Applications/Calendar/AddEventDialog.gml index a0b11f2c9c..08519475c4 100644 --- a/Userland/Applications/Calendar/AddEventDialog.gml +++ b/Userland/Applications/Calendar/AddEventDialog.gml @@ -1,4 +1,4 @@ -@GUI::Widget { +@Calendar::AddEventWidget { fill_with_background_color: true layout: @GUI::VerticalBoxLayout { margins: [4] diff --git a/Userland/Applications/Calendar/AddEventDialog.h b/Userland/Applications/Calendar/AddEventDialog.h index 2989471e1e..8cc971b3ff 100644 --- a/Userland/Applications/Calendar/AddEventDialog.h +++ b/Userland/Applications/Calendar/AddEventDialog.h @@ -11,7 +11,6 @@ #include "EventManager.h" #include #include -#include #include namespace Calendar { @@ -27,27 +26,12 @@ public: dialog->exec(); } + ErrorOr add_event_to_calendar(Core::DateTime start_date_time, Core::DateTime end_date_time); + private: AddEventDialog(Core::DateTime date_time, EventManager& event_manager, Window* parent_window = nullptr); - ErrorOr add_event_to_calendar(); - - void update_start_date(); - void update_end_date(); - void update_duration(); - - Core::DateTime m_start_date_time; - Core::DateTime m_end_date_time; EventManager& m_event_manager; - - RefPtr m_start_date_box; - RefPtr m_end_date_box; - RefPtr m_start_hour_box; - RefPtr m_start_minute_box; - RefPtr m_end_hour_box; - RefPtr m_end_minute_box; - RefPtr m_duration_hour_box; - RefPtr m_duration_minute_box; }; } diff --git a/Userland/Applications/Calendar/AddEventWidget.cpp b/Userland/Applications/Calendar/AddEventWidget.cpp new file mode 100644 index 0000000000..9c2c22b5a5 --- /dev/null +++ b/Userland/Applications/Calendar/AddEventWidget.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2024, kleines Filmröllchen + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "AddEventWidget.h" +#include +#include +#include +#include +#include + +namespace Calendar { + +static constexpr StringView DATE_FORMAT = "%Y-%m-%d"sv; + +ErrorOr> AddEventWidget::create(AddEventDialog* window, Core::DateTime start_time, Core::DateTime end_time) +{ + auto widget = TRY(try_create()); + widget->m_start_date_time = start_time; + widget->m_end_date_time = end_time; + + auto& event_title_textbox = *widget->find_descendant_of_type_named("event_title_textbox"); + event_title_textbox.set_focus(true); + + widget->m_start_date_box = *widget->find_descendant_of_type_named("start_date"); + + auto calendar_date_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/calendar-date.png"sv).release_value_but_fixme_should_propagate_errors(); + + auto& pick_start_date_button = *widget->find_descendant_of_type_named("pick_start_date"); + pick_start_date_button.set_icon(calendar_date_icon); + pick_start_date_button.on_click = [widget = widget, window = window](auto) { + if (auto new_date = GUI::DatePicker::show(window, "Pick Start Date"_string, widget->m_start_date_time); new_date.has_value()) { + widget->m_start_date_time.set_date(new_date.value()); + if (widget->m_end_date_time < widget->m_start_date_time) { + widget->m_end_date_time.set_date(new_date.value()); + widget->update_end_date(); + } + widget->update_duration(); + + widget->m_start_date_box->set_text(MUST(widget->m_start_date_time.to_string(DATE_FORMAT))); + } + }; + + widget->m_start_hour_box = *widget->find_descendant_of_type_named("start_hour"); + widget->m_start_minute_box = *widget->find_descendant_of_type_named("start_minute"); + + widget->m_end_date_box = *widget->find_descendant_of_type_named("end_date"); + + auto& pick_end_date_button = *widget->find_descendant_of_type_named("pick_end_date"); + pick_end_date_button.set_icon(calendar_date_icon); + pick_end_date_button.on_click = [widget = widget, window = window](auto) { + if (auto new_date = GUI::DatePicker::show(window, "Pick End Date"_string, widget->m_end_date_time); new_date.has_value()) { + widget->m_end_date_time.set_date(new_date.value()); + if (widget->m_end_date_time < widget->m_start_date_time) { + widget->m_start_date_time.set_date(new_date.value()); + widget->update_start_date(); + } + widget->update_duration(); + + widget->m_end_date_box->set_text(MUST(widget->m_end_date_time.to_string(DATE_FORMAT))); + } + }; + + widget->m_end_hour_box = *widget->find_descendant_of_type_named("end_hour"); + widget->m_end_minute_box = *widget->find_descendant_of_type_named("end_minute"); + + widget->m_duration_hour_box = *widget->find_descendant_of_type_named("duration_hour"); + widget->m_duration_minute_box = *widget->find_descendant_of_type_named("duration_minute"); + + auto& ok_button = *widget->find_descendant_of_type_named("ok_button"); + ok_button.on_click = [widget = widget, window = window](auto) { + auto successful = window->add_event_to_calendar(widget->m_start_date_time, widget->m_end_date_time).release_value_but_fixme_should_propagate_errors(); + if (!successful) + return; + window->done(GUI::Dialog::ExecResult::OK); + }; + + auto& cancel_button = *widget->find_descendant_of_type_named("cancel_button"); + cancel_button.on_click = [window = window](auto) { window->done(GUI::Dialog::ExecResult::Cancel); }; + + auto update_starting_input_values = [widget = widget]() { + auto hour = widget->m_start_hour_box->value(); + auto minute = widget->m_start_minute_box->value(); + widget->m_start_date_time.set_time_only(hour, minute); + if (widget->m_end_date_time < widget->m_start_date_time) { + widget->m_end_date_time.set_time_only(hour, minute); + widget->update_end_date(); + } + widget->update_duration(); + }; + auto update_ending_input_values = [widget = widget]() { + auto hour = widget->m_end_hour_box->value(); + auto minute = widget->m_end_minute_box->value(); + widget->m_end_date_time.set_time_only(hour, minute); + if (widget->m_end_date_time < widget->m_start_date_time) { + widget->m_start_date_time.set_time_only(hour, minute); + widget->update_start_date(); + } + widget->update_duration(); + }; + auto update_duration_input_values = [widget]() { + auto hour = widget->m_duration_hour_box->value(); + auto minute = widget->m_duration_minute_box->value(); + widget->m_end_date_time = Core::DateTime::from_timestamp(widget->m_start_date_time.timestamp() + (hour * 60 + minute) * 60); + widget->update_end_date(); + }; + + widget->m_start_hour_box->on_change = [update_starting_input_values](auto) { update_starting_input_values(); }; + widget->m_start_minute_box->on_change = [update_starting_input_values](auto) { update_starting_input_values(); }; + widget->m_end_hour_box->on_change = [update_ending_input_values](auto) { update_ending_input_values(); }; + widget->m_end_minute_box->on_change = [update_ending_input_values](auto) { update_ending_input_values(); }; + widget->m_duration_hour_box->on_change = [update_duration_input_values](auto) { update_duration_input_values(); }; + widget->m_duration_minute_box->on_change = [update_duration_input_values](auto) { update_duration_input_values(); }; + + widget->update_start_date(); + widget->update_end_date(); + widget->update_duration(); + + return widget; +} + +void AddEventWidget::update_start_date() +{ + m_start_date_box->set_text(MUST(m_start_date_time.to_string(DATE_FORMAT))); + m_start_hour_box->set_value(m_start_date_time.hour(), GUI::AllowCallback::No); + m_start_minute_box->set_value(m_start_date_time.minute(), GUI::AllowCallback::No); +} + +void AddEventWidget::update_end_date() +{ + m_end_date_box->set_text(MUST(m_end_date_time.to_string(DATE_FORMAT))); + m_end_hour_box->set_value(m_end_date_time.hour(), GUI::AllowCallback::No); + m_end_minute_box->set_value(m_end_date_time.minute(), GUI::AllowCallback::No); +} + +void AddEventWidget::update_duration() +{ + auto difference_in_seconds = m_end_date_time.timestamp() - m_start_date_time.timestamp(); + auto hours = difference_in_seconds / (60 * 60); + auto minutes = (difference_in_seconds - hours * (60 * 60)) / 60; + + m_duration_hour_box->set_value(hours, GUI::AllowCallback::No); + m_duration_minute_box->set_value(minutes, GUI::AllowCallback::No); +} + +} diff --git a/Userland/Applications/Calendar/AddEventWidget.h b/Userland/Applications/Calendar/AddEventWidget.h new file mode 100644 index 0000000000..c360473a47 --- /dev/null +++ b/Userland/Applications/Calendar/AddEventWidget.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, kleines Filmröllchen + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "AddEventDialog.h" +#include "EventManager.h" +#include +#include +#include +#include + +namespace Calendar { + +class AddEventWidget final : public GUI::Widget { + C_OBJECT(AddEventWidget); + +public: + static ErrorOr> create(AddEventDialog*, Core::DateTime start_time, Core::DateTime end_time); + virtual ~AddEventWidget() override = default; + +private: + AddEventWidget() = default; + static ErrorOr> try_create(); + + void update_start_date(); + void update_end_date(); + void update_duration(); + + Core::DateTime m_start_date_time; + Core::DateTime m_end_date_time; + + RefPtr m_start_date_box; + RefPtr m_end_date_box; + RefPtr m_start_hour_box; + RefPtr m_start_minute_box; + RefPtr m_end_hour_box; + RefPtr m_end_minute_box; + RefPtr m_duration_hour_box; + RefPtr m_duration_minute_box; +}; + +} diff --git a/Userland/Applications/Calendar/CMakeLists.txt b/Userland/Applications/Calendar/CMakeLists.txt index 75cf0bec4b..7abf3da547 100644 --- a/Userland/Applications/Calendar/CMakeLists.txt +++ b/Userland/Applications/Calendar/CMakeLists.txt @@ -3,20 +3,19 @@ serenity_component( TARGETS Calendar ) -stringify_gml(CalendarWindow.gml CalendarWindowGML.h calendar_window_gml) -stringify_gml(AddEventDialog.gml AddEventDialogGML.h add_event_dialog_gml) +compile_gml(CalendarWidget.gml CalendarWidgetGML.cpp) +compile_gml(AddEventDialog.gml AddEventDialogGML.cpp) set(SOURCES AddEventDialog.cpp + AddEventDialogGML.cpp + AddEventWidget.cpp CalendarWidget.cpp + CalendarWidgetGML.cpp EventCalendar.cpp EventManager.cpp main.cpp ) -set(GENERATED_SOURCES - CalendarWindowGML.h AddEventDialogGML.h -) - serenity_app(Calendar ICON app-calendar) target_link_libraries(Calendar PRIVATE LibConfig LibCore LibFileSystem LibFileSystemAccessClient LibGfx LibGUI LibMain LibDesktop) diff --git a/Userland/Applications/Calendar/CalendarWidget.cpp b/Userland/Applications/Calendar/CalendarWidget.cpp index cde18d9dd6..ada723d75a 100644 --- a/Userland/Applications/Calendar/CalendarWidget.cpp +++ b/Userland/Applications/Calendar/CalendarWidget.cpp @@ -9,7 +9,6 @@ #include "AddEventDialog.h" #include #include -#include #include #include #include @@ -31,8 +30,7 @@ namespace Calendar { ErrorOr> CalendarWidget::create(GUI::Window* parent_window) { - auto widget = TRY(AK::adopt_nonnull_ref_or_enomem(new (nothrow) CalendarWidget)); - TRY(widget->load_from_gml(calendar_window_gml)); + auto widget = TRY(CalendarWidget::try_create()); widget->m_event_calendar = widget->find_descendant_of_type_named("calendar"); widget->create_on_events_change(); diff --git a/Userland/Applications/Calendar/CalendarWindow.gml b/Userland/Applications/Calendar/CalendarWidget.gml similarity index 80% rename from Userland/Applications/Calendar/CalendarWindow.gml rename to Userland/Applications/Calendar/CalendarWidget.gml index 1989ebfb14..1dba99c0e6 100644 --- a/Userland/Applications/Calendar/CalendarWindow.gml +++ b/Userland/Applications/Calendar/CalendarWidget.gml @@ -1,4 +1,4 @@ -@GUI::Widget { +@Calendar::CalendarWidget { fill_with_background_color: true layout: @GUI::VerticalBoxLayout {} @@ -10,7 +10,7 @@ } } - @::Calendar::EventCalendar { + @Calendar::EventCalendar { name: "calendar" } } diff --git a/Userland/Applications/Calendar/CalendarWidget.h b/Userland/Applications/Calendar/CalendarWidget.h index 9b67efafd6..fdf184ff6f 100644 --- a/Userland/Applications/Calendar/CalendarWidget.h +++ b/Userland/Applications/Calendar/CalendarWidget.h @@ -10,6 +10,7 @@ #include "EventCalendar.h" #include #include +#include #include #include @@ -28,6 +29,9 @@ public: bool request_close(); private: + CalendarWidget() = default; + static ErrorOr> try_create(); + void create_on_tile_doubleclick(); String const& current_filename() const { return m_event_calendar->event_manager().current_filename(); }