diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f21b8f..a6995a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,17 +21,23 @@ target_sources(bar_lib PUBLIC src/app.cpp src/bar/bar.cpp + src/widgets/clock.cpp src/widgets/date.cpp src/widgets/workspaceIndicator.cpp src/widgets/volumeWidget.cpp src/widgets/webWidget.cpp + + src/services/todo.cpp src/services/hyprland.cpp src/services/tray.cpp src/services/notifications.cpp + src/widgets/tray.cpp - src/widgets/todo.cpp + src/widgets/todoPopover.cpp + src/components/popover.cpp + src/components/todoEntry.cpp ) include_directories(bar_lib PRIVATE include diff --git a/include/bar/bar.hpp b/include/bar/bar.hpp index b5623ad..abd71bd 100644 --- a/include/bar/bar.hpp +++ b/include/bar/bar.hpp @@ -8,13 +8,13 @@ #include "widgets/clock.hpp" #include "widgets/date.hpp" #include "widgets/tray.hpp" +#include "widgets/volumeWidget.hpp" #include "widgets/webWidget.hpp" #include "widgets/workspaceIndicator.hpp" class Bar : public Gtk::Window { public: - Bar(GdkMonitor *monitor, HyprlandService &hyprlandService, - TrayService &trayService, int monitorId); + Bar(GdkMonitor *monitor, HyprlandService &hyprlandService, TrayService &trayService, int monitorId); protected: Gtk::CenterBox main_box{}; @@ -23,16 +23,18 @@ class Bar : public Gtk::Window { Gtk::Box right_box{Gtk::Orientation::HORIZONTAL}; private: + int monitorId; + Clock clock; Date date; - WebWidget homeAssistant{ICON_HOME, "Home Assistant", - "https://home.rivercry.com"}; - TrayService &trayService; - HyprlandService &hyprlandService; - int monitorId; + WebWidget homeAssistant{ICON_HOME, "Home Assistant", "https://home.rivercry.com"}; + WorkspaceIndicator *workspaceIndicator = nullptr; TrayWidget *trayWidget = nullptr; - class VolumeWidget *volumeWidget = nullptr; + VolumeWidget *volumeWidget = nullptr; + + TrayService &trayService; + HyprlandService &hyprlandService; void setup_ui(); void setup_left_box(); diff --git a/include/components/todoEntry.hpp b/include/components/todoEntry.hpp new file mode 100644 index 0000000..8357968 --- /dev/null +++ b/include/components/todoEntry.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "gtkmm/box.h" +#include + + +class TodoEntry : public Gtk::Box { +public: + TodoEntry(int id, std::string text, sigc::signal signal_dismissed); + ~TodoEntry() override; + + int get_id() const { return id; } +private: + int id; + sigc::signal signal_dismissed; + + void on_dismiss_clicked(); +}; \ No newline at end of file diff --git a/include/services/todo.hpp b/include/services/todo.hpp new file mode 100644 index 0000000..2aab7b7 --- /dev/null +++ b/include/services/todo.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "components/todoEntry.hpp" +#include +#include + +class TodoService { + public: + TodoService(sigc::signal refreshSignal); + ~TodoService(); + + std::map getTodos(); + void init(); + void removeTodo(int id); + TodoEntry *addTodo(std::string text, bool emitSignal = true); + void updateTodo(int id, std::string text); + + private: + int nextId = 1; + std::map todos; + sigc::signal refreshSignal; +}; \ No newline at end of file diff --git a/include/widgets/todo.hpp b/include/widgets/todo.hpp deleted file mode 100644 index d9cedc3..0000000 --- a/include/widgets/todo.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "components/popover.hpp" - -class Todo : public Popover { -public: - Todo(std::string icon, std::string title); -}; \ No newline at end of file diff --git a/include/widgets/todoPopover.hpp b/include/widgets/todoPopover.hpp new file mode 100644 index 0000000..434f17e --- /dev/null +++ b/include/widgets/todoPopover.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "components/popover.hpp" +#include "services/todo.hpp" +#include + +class TodoPopover : public Popover { + +public: + TodoPopover(std::string icon, std::string title); + + void update(); +private: + std::string name; + TodoService* todoService = nullptr; + Gtk::Box container; + Gtk::Box inputArea; + Gtk::Box* todoList = nullptr; +}; \ No newline at end of file diff --git a/resources/bar.css b/resources/bar.css index 91f15a3..e7e5687 100644 --- a/resources/bar.css +++ b/resources/bar.css @@ -108,4 +108,22 @@ tooltip { .icon-label { font-family: "Material Icons, Font Awesome 7 Brands, Hack Nerd Font Mono"; font-size: 19px; +} + +.todo-popover-container { + padding: 10px; + background-color: #1e1e1e; + border-radius: 6px; +} + +.todo-input-area { + margin-bottom: 10px; +} + +.todo-input { + padding: 5px; + border-radius: 4px; + border: 1px solid #555555; + background-color: #222222; + color: #ffffff; } \ No newline at end of file diff --git a/src/bar/bar.cpp b/src/bar/bar.cpp index 9ed79b7..fee9ac3 100644 --- a/src/bar/bar.cpp +++ b/src/bar/bar.cpp @@ -4,7 +4,7 @@ #include "widgets/date.hpp" #include "widgets/spacer.hpp" -#include "widgets/todo.hpp" +#include "widgets/todoPopover.hpp" #include "widgets/volumeWidget.hpp" #include "widgets/workspaceIndicator.hpp" @@ -40,8 +40,8 @@ Bar::Bar(GdkMonitor *monitor, HyprlandService &hyprlandService, set_child(main_box); this->volumeWidget = Gtk::make_managed(); - workspaceIndicator = Gtk::make_managed(hyprlandService, monitorId); - trayWidget = Gtk::make_managed(trayService); + this->workspaceIndicator = Gtk::make_managed(hyprlandService, monitorId); + this->trayWidget = Gtk::make_managed(trayService); load_css(); setup_ui(); @@ -73,7 +73,7 @@ void Bar::setup_left_box() { void Bar::setup_center_box() { center_box.set_hexpand(false); - center_box.append(*(new Todo("\uf23a", "To-Do"))); + center_box.append(*(new TodoPopover("\uf23a", "To-Do"))); center_box.append(*(new Spacer())); center_box.append(this->date); center_box.append(*(new Spacer())); diff --git a/src/components/todoEntry.cpp b/src/components/todoEntry.cpp new file mode 100644 index 0000000..f7978c2 --- /dev/null +++ b/src/components/todoEntry.cpp @@ -0,0 +1,45 @@ +#include "components/todoEntry.hpp" + +#include + +#include "gtkmm/button.h" + +TodoEntry::TodoEntry(int id, std::string text, sigc::signal signal_dismissed) + : Gtk::Box(Gtk::Orientation::HORIZONTAL) { + this->id = id; + this->signal_dismissed = signal_dismissed; + + + auto box = Gtk::make_managed(Gtk::Orientation::HORIZONTAL); + box->set_hexpand(true); + box->set_halign(Gtk::Align::START); + box->set_valign(Gtk::Align::CENTER); + box->set_name("todo-entry-box"); + box->add_css_class("todo-entry-box"); + append(*box); + + auto label = Gtk::make_managed(text); + label->set_halign(Gtk::Align::START); + label->set_valign(Gtk::Align::CENTER); + box->append(*label); + + auto buttonBox = Gtk::make_managed(Gtk::Orientation::HORIZONTAL); + buttonBox->set_halign(Gtk::Align::END); + buttonBox->set_valign(Gtk::Align::CENTER); + append(*buttonBox); + + auto dismissButton = Gtk::make_managed("\uf00d"); + dismissButton->set_valign(Gtk::Align::CENTER); + dismissButton->set_tooltip_text("Dismiss"); + + dismissButton->signal_clicked().connect(sigc::mem_fun(*this, &TodoEntry::on_dismiss_clicked)); + + buttonBox->append(*dismissButton); +} + +TodoEntry::~TodoEntry() { +} + +void TodoEntry::on_dismiss_clicked() { + this->signal_dismissed.emit(this->id); +} \ No newline at end of file diff --git a/src/services/todo.cpp b/src/services/todo.cpp new file mode 100644 index 0000000..fc66d84 --- /dev/null +++ b/src/services/todo.cpp @@ -0,0 +1,56 @@ +#include "services/todo.hpp" +#include "components/todoEntry.hpp" +#include "gtkmm/object.h" +#include +#include + +TodoService::TodoService(sigc::signal refreshSignal) { + this->refreshSignal = refreshSignal; + this->init(); +} + +TodoService::~TodoService() {} + +std::map TodoService::getTodos() { + return this->todos; +} + +void TodoService::init() { + std::vector items = { + "Buy groceries", + "Finish the report", + "Call Alice", + "Schedule dentist appointment"}; + + for (auto item : items) { + this->addTodo(item, false); + } +} + +void TodoService::removeTodo(int id) { + if (todos.find(id) == todos.end()) { + std::cerr << "Todo with id " << id << " not found!" << std::endl; + assert(false); + } + + todos.erase(id); + + this->refreshSignal.emit(); +} + +TodoEntry *TodoService::addTodo(std::string text, bool emitSignal) { + auto signal = sigc::signal(); + signal.connect(sigc::mem_fun(*this, &TodoService::removeTodo)); + TodoEntry *todo = Gtk::make_managed(nextId, text, signal); + + todos[nextId] = todo; + + nextId++; + + if (emitSignal) { + this->refreshSignal.emit(); + } + return todo; +} + +void TodoService::updateTodo(int id, std::string text) {} diff --git a/src/widgets/todo.cpp b/src/widgets/todo.cpp deleted file mode 100644 index 0aa2e47..0000000 --- a/src/widgets/todo.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include - -#include "widgets/todo.hpp" - -Todo::Todo(std::string icon, std::string title) : Popover(icon, title) { - auto label = Gtk::make_managed(title); - label->add_css_class("todo-label"); - this->set_popover_child(*label); -} \ No newline at end of file diff --git a/src/widgets/todoPopover.cpp b/src/widgets/todoPopover.cpp new file mode 100644 index 0000000..c680aa0 --- /dev/null +++ b/src/widgets/todoPopover.cpp @@ -0,0 +1,78 @@ +#include "widgets/todoPopover.hpp" + +#include +#include +#include + +TodoPopover::TodoPopover(std::string icon, std::string title) : Popover(icon, title) { + this->name = title; + this->popover->set_size_request(300, -1); + + container.set_orientation(Gtk::Orientation::VERTICAL); + container.set_spacing(10); + container.add_css_class("todo-popover-container"); + + + auto entry = Gtk::make_managed(); + entry->set_placeholder_text("Enter your to-do item..."); + entry->add_css_class("todo-input"); + entry->set_hexpand(true); + entry->set_halign(Gtk::Align::FILL); + entry->set_valign(Gtk::Align::START); + + inputArea.append(*entry); + inputArea.add_css_class("todo-input-area"); + inputArea.set_hexpand(true); + inputArea.set_halign(Gtk::Align::FILL); + + entry->signal_activate().connect([this, entry]() { + std::string text = entry->get_text(); + if (!text.empty()) { + this->todoService->addTodo(text); + } + }); + + container.append(inputArea); + + this->todoList = Gtk::make_managed(Gtk::Orientation::VERTICAL); + container.append(*todoList); + todoList->add_css_class("todo-list"); + + auto signal = sigc::signal(); + this->todoService = new TodoService(signal); + + signal.connect(sigc::mem_fun(*this, &TodoPopover::update)); + + this->set_popover_child(this->container); + this->update(); +} + +void TodoPopover::update() { + auto todos = this->todoService->getTodos(); + + Gtk::Widget* child = todoList->get_first_child(); + + while (child) { + Gtk::Widget* next = child->get_next_sibling(); + + bool found = false; + for (auto& [id, todo] : todos) { + if (child == todo) { + found = true; + break; + } + } + + if (!found) { + todoList->remove(*child); + } + + child = next; + } + + for (auto &[id, todo] : todos) { + if (todo->get_parent() == nullptr) { + todoList->append(*todo); + } + } +} \ No newline at end of file diff --git a/src/widgets/webWidget.cpp b/src/widgets/webWidget.cpp index c497c0e..726bc34 100644 --- a/src/widgets/webWidget.cpp +++ b/src/widgets/webWidget.cpp @@ -1,5 +1,4 @@ #include "widgets/webWidget.hpp" -#include #include #include