1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:57:44 +00:00

LibGUI+Calendar: Add new month and year views to Calendar

And overhaul resize and paint events to fix layout edge cases in
which Calendar wasn't filling its parent widget completely. Ensures
month views always display prior month days for click navigation.
Converts Calendar app layout to GML.
This commit is contained in:
thankyouverycool 2021-03-29 20:43:40 -04:00 committed by Andreas Kling
parent effb426757
commit 4465b37897
6 changed files with 865 additions and 420 deletions

View file

@ -25,7 +25,9 @@
*/
#include "AddEventDialog.h"
#include <Applications/Calendar/CalendarWindowGML.h>
#include <LibGUI/Action.h>
#include <LibGUI/ActionGroup.h>
#include <LibGUI/Application.h>
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Button.h>
@ -36,15 +38,10 @@
#include <LibGUI/ToolBar.h>
#include <LibGUI/ToolBarContainer.h>
#include <LibGUI/Window.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Color.h>
#include <LibGfx/FontDatabase.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
if (pledge("stdio recvfd sendfd rpath accept unix cpath fattr", nullptr) < 0) {
perror("pledge");
return 1;
@ -68,101 +65,92 @@ int main(int argc, char** argv)
auto window = GUI::Window::construct();
window->set_title("Calendar");
window->resize(600, 480);
window->set_minimum_size(171, 141);
window->set_icon(app_icon.bitmap_for_size(16));
auto& root_container = window->set_main_widget<GUI::Widget>();
root_container.set_fill_with_background_color(true);
root_container.set_layout<GUI::VerticalBoxLayout>();
auto& main_widget = window->set_main_widget<GUI::Widget>();
main_widget.load_from_gml(calendar_window_gml);
auto& toolbar_container = root_container.add<GUI::ToolBarContainer>();
auto& toolbar = toolbar_container.add<GUI::ToolBar>();
auto toolbar = main_widget.find_descendant_of_type_named<GUI::ToolBar>("toolbar");
auto calendar = main_widget.find_descendant_of_type_named<GUI::Calendar>("calendar");
auto& calendar_container = root_container.add<GUI::Frame>();
calendar_container.set_layout<GUI::VerticalBoxLayout>();
calendar_container.layout()->set_margins({ 2, 2, 2, 2 });
auto& calendar_widget = calendar_container.add<GUI::Calendar>(Core::DateTime::now());
RefPtr<GUI::Button> selected_calendar_button;
auto prev_date_action = GUI::Action::create("Previous date", { Mod_Alt, Key_Left }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-back.png"), [&](const GUI::Action&) {
unsigned int target_month = calendar_widget.selected_month();
unsigned int target_year = calendar_widget.selected_year();
if (calendar_widget.mode() == GUI::Calendar::Month) {
target_month--;
if (calendar_widget.selected_month() <= 1) {
target_month = 12;
target_year--;
auto prev_date_action = GUI::Action::create({}, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-back.png"), [&](const GUI::Action&) {
unsigned view_month = calendar->view_month();
unsigned view_year = calendar->view_year();
if (calendar->mode() == GUI::Calendar::Month) {
view_month--;
if (calendar->view_month() == 1) {
view_month = 12;
view_year--;
}
} else {
target_year--;
view_year--;
}
calendar_widget.update_tiles(target_year, target_month);
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
calendar->update_tiles(view_year, view_month);
});
auto next_date_action = GUI::Action::create("Next date", { Mod_Alt, Key_Right }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [&](const GUI::Action&) {
unsigned int target_month = calendar_widget.selected_month();
unsigned int target_year = calendar_widget.selected_year();
if (calendar_widget.mode() == GUI::Calendar::Month) {
target_month++;
if (calendar_widget.selected_month() >= 12) {
target_month = 1;
target_year++;
auto next_date_action = GUI::Action::create({}, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [&](const GUI::Action&) {
unsigned view_month = calendar->view_month();
unsigned view_year = calendar->view_year();
if (calendar->mode() == GUI::Calendar::Month) {
view_month++;
if (calendar->view_month() == 12) {
view_month = 1;
view_year++;
}
} else {
target_year++;
view_year++;
}
calendar_widget.update_tiles(target_year, target_month);
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
calendar->update_tiles(view_year, view_month);
});
auto add_event_action = GUI::Action::create("Add event", {}, Gfx::Bitmap::load_from_file("/res/icons/16x16/add-event.png"), [&](const GUI::Action&) {
AddEventDialog::show(calendar_widget.selected_date(), window);
AddEventDialog::show(calendar->selected_date(), window);
});
auto jump_to_action = GUI::Action::create("Jump to today", {}, Gfx::Bitmap::load_from_file("/res/icons/16x16/calendar-date.png"), [&](const GUI::Action&) {
if (calendar_widget.mode() == GUI::Calendar::Year)
calendar_widget.toggle_mode();
calendar_widget.set_selected_date(Core::DateTime::now());
calendar_widget.update_tiles(Core::DateTime::now().year(), Core::DateTime::now().month());
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
calendar->set_selected_date(Core::DateTime::now());
calendar->update_tiles(Core::DateTime::now().year(), Core::DateTime::now().month());
});
toolbar.add_action(prev_date_action);
selected_calendar_button = toolbar.add<GUI::Button>(calendar_widget.selected_calendar_text());
selected_calendar_button->set_fixed_width(70);
selected_calendar_button->set_button_style(Gfx::ButtonStyle::CoolBar);
selected_calendar_button->set_font(Gfx::FontDatabase::default_bold_fixed_width_font());
selected_calendar_button->on_click = [&](auto) {
calendar_widget.toggle_mode();
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
};
toolbar.add_action(next_date_action);
toolbar.add_separator();
toolbar.add_action(jump_to_action);
toolbar.add_action(add_event_action);
auto view_month_action = GUI::Action::create_checkable("Month view", { Mod_Ctrl, KeyCode::Key_1 }, Gfx::Bitmap::load_from_file("/res/icons/16x16/calendar-month-view.png"), [&](const GUI::Action&) {
if (calendar->mode() == GUI::Calendar::Year)
calendar->toggle_mode();
});
view_month_action->set_checked(true);
calendar_widget.on_calendar_tile_click = [&] {
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
auto view_year_action = GUI::Action::create_checkable("Year view", { Mod_Ctrl, KeyCode::Key_2 }, Gfx::Bitmap::load_from_file("/res/icons/16x16/icon-view.png"), [&](const GUI::Action&) {
if (calendar->mode() == GUI::Calendar::Month)
calendar->toggle_mode();
});
auto view_type_action_group = make<GUI::ActionGroup>();
view_type_action_group->set_exclusive(true);
view_type_action_group->add_action(*view_month_action);
view_type_action_group->add_action(*view_year_action);
toolbar->add_action(prev_date_action);
toolbar->add_action(next_date_action);
toolbar->add_separator();
toolbar->add_action(jump_to_action);
toolbar->add_action(add_event_action);
toolbar->add_separator();
toolbar->add_action(view_month_action);
toolbar->add_action(view_year_action);
calendar->on_tile_doubleclick = [&] {
AddEventDialog::show(calendar->selected_date(), window);
};
calendar_widget.on_calendar_tile_doubleclick = [&] {
AddEventDialog::show(calendar_widget.selected_date(), window);
};
calendar_widget.on_month_tile_click = [&] {
selected_calendar_button->set_text(calendar_widget.selected_calendar_text());
calendar->on_month_click = [&] {
view_month_action->set_checked(true);
};
auto menubar = GUI::MenuBar::construct();
auto& app_menu = menubar->add_menu("File");
app_menu.add_action(GUI::Action::create("Add Event", { Mod_Ctrl | Mod_Shift, Key_E }, Gfx::Bitmap::load_from_file("/res/icons/16x16/add-event.png"),
[&](const GUI::Action&) {
AddEventDialog::show(calendar_widget.selected_date(), window);
AddEventDialog::show(calendar->selected_date(), window);
return;
}));
@ -173,6 +161,10 @@ int main(int argc, char** argv)
return;
}));
auto& view_menu = menubar->add_menu("View");
view_menu.add_action(*view_month_action);
view_menu.add_action(*view_year_action);
auto& help_menu = menubar->add_menu("Help");
help_menu.add_action(GUI::CommonActions::make_about_action("Calendar", app_icon, window));