diff --git a/flake.lock b/flake.lock index 7bae913..c6a51bc 100644 --- a/flake.lock +++ b/flake.lock @@ -263,11 +263,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1737937590, - "narHash": "sha256-DLkqOLlEaS9xdGzSimNQcMlhjbbY6APSxwc0ukJRmCU=", + "lastModified": 1738012240, + "narHash": "sha256-4wmhkSSdgkVR02zG7nP4MTUpA2oih7E+9AWu4zEqP+k=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a7a2612e4ad654e7573ea0b988019f91b8d0df10", + "rev": "0542e87760a8f611f089dcf38862f783c8c8f890", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index ed9e2e7..6f7548f 100644 --- a/flake.nix +++ b/flake.nix @@ -67,6 +67,7 @@ tomlplusplus yyjson reflect-cpp + ftxui ] ++ linuxPkgs ++ darwinPkgs; @@ -92,6 +93,7 @@ src = self; nativeBuildInputs = [ + cmake meson ninja pkg-config diff --git a/meson.build b/meson.build index c44659e..77052dc 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( 'cpp_std=c++20', 'default_library=static', 'warning_level=everything', - 'buildtype=debug', + 'buildtype=debugoptimized' ] ) @@ -85,6 +85,7 @@ deps = [ dependency('libcurl'), dependency('tomlplusplus'), dependency('yyjson'), + dependency('ftxui'), dependency('reflectcpp') ] diff --git a/src/main.cpp b/src/main.cpp index fe7f5ea..560ead1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include "config/config.h" @@ -26,67 +28,127 @@ struct fmt::formatter : fmt::formatter { } }; -fn GetDate() -> std::string { - // Get current local time - std::time_t now = std::time(nullptr); - std::tm localTime = *std::localtime(&now); +namespace { - // Format the date using fmt::format - std::string date = fmt::format("{:%e}", localTime); + fn GetDate() -> std::string { + // Get current local time + std::time_t now = std::time(nullptr); + std::tm localTime = *std::localtime(&now); - // Remove leading whitespace - if (!date.empty() && std::isspace(date.front())) - date.erase(date.begin()); + // Format the date using fmt::format + std::string date = fmt::format("{:%e}", localTime); - // Append appropriate suffix for the date - if (date == "1" || date == "21" || date == "31") - date += "st"; - else if (date == "2" || date == "22") - date += "nd"; - else if (date == "3" || date == "23") - date += "rd"; - else - date += "th"; + // Remove leading whitespace + if (!date.empty() && std::isspace(date.front())) + date.erase(date.begin()); - return fmt::format("{:%B} {}", localTime, date); + // Append appropriate suffix for the date + if (date == "1" || date == "21" || date == "31") + date += "st"; + else if (date == "2" || date == "22") + date += "nd"; + else if (date == "3" || date == "23") + date += "rd"; + else + date += "th"; + + return fmt::format("{:%B} {}", localTime, date); + } + + using namespace ftxui; + + fn CreateColorCircles() -> Element { + Elements circles; + for (int i = 0; i < 16; ++i) { + circles.push_back(text("◍") | color(Color::Palette256(i))); + circles.push_back(text(" ")); + } + return hbox(circles); + } + + fn SystemInfoBox(const Config& config) -> Element { + // Fetch data + std::string date = GetDate(); + u64 memInfo = GetMemInfo(); + std::string osVersion = GetOSVersion(); + Weather weather = config.weather.get(); + bool nowPlayingEnabled = config.now_playing.get().enabled; + std::string nowPlaying = nowPlayingEnabled ? GetNowPlaying() : ""; + const std::string& name = config.general.get().name.get(); + + // Icon constants (using Nerd Font v3) + constexpr const char* calendarIcon = "  "; + constexpr const char* memoryIcon = "  "; + constexpr const char* osIcon = "  "; + constexpr const char* weatherIcon = " 󰖐 "; + constexpr const char* musicIcon = "  "; + const auto labelColor = Color::Yellow; + const auto valueColor = Color::White; + const auto borderColor = Color::GrayLight; + const auto iconColor = Color::RGB(100, 200, 255); // Bright cyan + + Elements content; + content.push_back(text("  Hello " + name + "! ") | bold | color(Color::Cyan)); + content.push_back(separator() | color(borderColor)); + + // Helper function for aligned rows + auto createRow = + [&](const std::string& emoji, const std::string& label, const std::string& value) { + return hbox({ text(emoji), + text(label) | color(labelColor), + filler(), + text(value), + text(" ") | color(valueColor) }); + }; + + // System info rows + content.push_back(createRow(calendarIcon, "Date ", date)); + content.push_back(createRow(memoryIcon, "RAM ", fmt::format("{:.2f}", BytesToGiB { memInfo }))); + content.push_back(createRow(osIcon, "OS ", osVersion)); + + // Weather row + if (weather.enabled) { + auto weatherInfo = weather.getWeatherInfo(); + content.push_back(separator() | color(borderColor)); + content.push_back(hbox( + { text(weatherIcon), + text("Weather ") | color(labelColor), + filler(), + hbox({ text(fmt::format("{}°F ", std::lround(weatherInfo.main.temp))) | color(Color::Red), + text("in "), + text(weatherInfo.name), + text(" ") }) | + color(valueColor) } + )); + } + + // Now Playing row + if (nowPlayingEnabled) { + content.push_back(separator() | color(borderColor)); + content.push_back(hbox({ text(musicIcon), + text("Now Playing ") | color(labelColor), + filler(), + text(!nowPlaying.empty() ? nowPlaying : "No song playing"), + text(" ") | color(Color::Magenta) })); + } + + // Color circles section + content.push_back(filler()); + content.push_back(separator() | color(borderColor)); + content.push_back(hbox({ text("  ") | color(iconColor), // Palette icon + CreateColorCircles() })); + return vbox(content) | borderRounded | color(Color::White); + } } fn main() -> i32 { const Config& config = Config::getInstance(); - // Fetching weather information - Weather weather = config.weather.get(); - WeatherOutput weatherInfo = weather.getWeatherInfo(); + auto document = hbox({ SystemInfoBox(config), filler() }); - // Fetching OS version - std::string osVersion = GetOSVersion(); - - // Checking if now playing is enabled - bool nowPlayingEnabled = config.now_playing.get().enabled; - - // Fetching current date - std::string date = GetDate(); - - // Fetching memory info - u64 memInfo = GetMemInfo(); - - const std::string& name = config.general.get().name.get(); - - fmt::println("Hello {}!", name); - fmt::println("Today is: {}", date); - fmt::println("Installed RAM: {:.2f}", BytesToGiB(memInfo)); - fmt::println("OS: {}", osVersion); - - if (weather.enabled) - fmt::println("It is {}°F in {}", std::lround(weatherInfo.main.temp), weatherInfo.name); - - if (nowPlayingEnabled) { - const string nowPlaying = GetNowPlaying(); - if (!nowPlaying.empty()) - fmt::println("{}", nowPlaying); - else - fmt::println("No song playing"); - } + auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); + Render(screen, document); + screen.Print(); return 0; }