#include "Bar.h" #include "System.h" #include "Common.h" #include "Config.h" namespace Bar { static int32_t monitorID; namespace DynCtx { constexpr uint32_t updateTime = 1000; constexpr uint32_t updateTimeFast = 100; static Revealer* powerBoxRevealer; static void PowerBoxEvent(EventBox&, bool hovered) { powerBoxRevealer->SetRevealed(hovered); } static Text* cpuText; static TimerResult UpdateCPU(CairoSensor& sensor) { double usage = System::GetCPUUsage(); double temp = System::GetCPUTemp(); cpuText->SetText("CPU: " + Utils::ToStringPrecision(usage * 100, "%0.1f") + "% " + Utils::ToStringPrecision(temp, "%0.1f") + "°C"); sensor.SetValue(usage); return TimerResult::Ok; } static Text* batteryText; static TimerResult UpdateBattery(CairoSensor& sensor) { double percentage = System::GetBatteryPercentage(); batteryText->SetText("Battery: " + Utils::ToStringPrecision(percentage * 100, "%0.1f") + "%"); sensor.SetValue(percentage); return TimerResult::Ok; } static Text* ramText; static TimerResult UpdateRAM(CairoSensor& sensor) { System::RAMInfo info = System::GetRAMInfo(); double used = info.totalGiB - info.freeGiB; double usedPercent = used / info.totalGiB; ramText->SetText("RAM: " + Utils::ToStringPrecision(used, "%0.2f") + "GiB/" + Utils::ToStringPrecision(info.totalGiB, "%0.2f") + "GiB"); sensor.SetValue(usedPercent); return TimerResult::Ok; } #ifdef WITH_NVIDIA static Text* gpuText; static TimerResult UpdateGPU(CairoSensor& sensor) { System::GPUInfo info = System::GetGPUInfo(); gpuText->SetText("GPU: " + Utils::ToStringPrecision(info.utilisation, "%0.1f") + "% " + Utils::ToStringPrecision(info.coreTemp, "%0.1f") + "°C"); sensor.SetValue(info.utilisation / 100); return TimerResult::Ok; } static Text* vramText; static TimerResult UpdateVRAM(CairoSensor& sensor) { System::VRAMInfo info = System::GetVRAMInfo(); vramText->SetText("VRAM: " + Utils::ToStringPrecision(info.usedGiB, "%0.2f") + "GiB/" + Utils::ToStringPrecision(info.totalGiB, "%0.2f") + "GiB"); sensor.SetValue(info.usedGiB / info.totalGiB); return TimerResult::Ok; } #endif static Text* diskText; static TimerResult UpdateDisk(CairoSensor& sensor) { System::DiskInfo info = System::GetDiskInfo(); diskText->SetText("Disk: " + Utils::ToStringPrecision(info.usedGiB, "%0.2f") + "GiB/" + Utils::ToStringPrecision(info.totalGiB, "%0.2f") + "GiB"); sensor.SetValue(info.usedGiB / info.totalGiB); return TimerResult::Ok; } #ifdef WITH_BLUEZ static Button* btIconText; static Text* btDevText; static TimerResult UpdateBluetooth(Box&) { System::BluetoothInfo info = System::GetBluetoothInfo(); if (info.defaultController.empty()) { btIconText->SetClass("bt-label-off"); btIconText->SetText(""); btDevText->SetText(""); } else if (info.devices.empty()) { btIconText->SetClass("bt-label-on"); btIconText->SetText(""); btDevText->SetText(""); } else { btIconText->SetClass("bt-label-connected"); btIconText->SetText(""); std::string btDev; std::string tooltip; for (auto& dev : info.devices) { if (!dev.connected) continue; std::string ico = System::BTTypeToIcon(dev); tooltip += dev.name + " & "; btDev += ico; } // Delete last delim if (tooltip.size()) tooltip.erase(tooltip.end() - 3, tooltip.end()); btDevText->SetTooltip(tooltip); btDevText->SetText(std::move(btDev)); } return TimerResult::Ok; } void OnBTClick(Button&) { System::OpenBTWidget(); } #endif void OnChangeVolume(Slider&, double value) { System::SetVolume(value); } Text* audioIcon; TimerResult UpdateAudio(Slider& slider) { System::AudioInfo info = System::GetAudioInfo(); slider.SetValue(info.volume); if (info.muted) { audioIcon->SetText("ﱝ"); } else { audioIcon->SetText("墳"); } return TimerResult::Ok; } TimerResult UpdateTime(Text& text) { text.SetText(System::GetTime()); return TimerResult::Ok; } #ifdef WITH_HYPRLAND static std::array workspaces; TimerResult UpdateWorkspaces(Box&) { for (size_t i = 0; i < workspaces.size(); i++) { switch (System::GetWorkspaceStatus((uint32_t)monitorID, i + 1)) { case System::WorkspaceStatus::Dead: workspaces[i]->SetClass("ws-dead"); break; case System::WorkspaceStatus::Inactive: workspaces[i]->SetClass("ws-inactive"); break; case System::WorkspaceStatus::Visible: workspaces[i]->SetClass("ws-visible"); break; case System::WorkspaceStatus::Current: workspaces[i]->SetClass("ws-current"); break; case System::WorkspaceStatus::Active: workspaces[i]->SetClass("ws-active"); break; } workspaces[i]->SetText(System::GetWorkspaceSymbol(i)); } return TimerResult::Ok; } #endif } void Sensor(Widget& parent, TimerCallback&& callback, const std::string& sensorClass, const std::string& textClass, Text*& textPtr) { auto eventBox = Widget::Create(); { auto box = Widget::Create(); box->SetSpacing({0, false}); box->SetHorizontalTransform({-1, true, Alignment::Right}); { auto revealer = Widget::Create(); revealer->SetTransition({TransitionType::SlideLeft, 500}); // Add event to eventbox for the revealer to open eventBox->SetEventFn( [textRevealer = revealer.get()](EventBox&, bool hovered) { textRevealer->SetRevealed(hovered); }); { auto text = Widget::Create(); text->SetClass(textClass); textPtr = text.get(); revealer->AddChild(std::move(text)); } auto cairoSensor = Widget::Create(); cairoSensor->SetClass(sensorClass); cairoSensor->AddTimer(std::move(callback), DynCtx::updateTime); cairoSensor->SetHorizontalTransform({24, true, Alignment::Fill}); box->AddChild(std::move(revealer)); box->AddChild(std::move(cairoSensor)); } eventBox->AddChild(std::move(box)); } parent.AddChild(std::move(eventBox)); } void WidgetAudio(Widget& parent) { auto box = Widget::Create(); box->SetSpacing({8, false}); box->SetHorizontalTransform({-1, false, Alignment::Right}); { auto icon = Widget::Create(); icon->SetClass("audio-icon"); icon->SetText("墳"); DynCtx::audioIcon = icon.get(); auto slider = Widget::Create(); slider->SetOrientation(Orientation::Horizontal); slider->SetHorizontalTransform({100, true, Alignment::Fill}); slider->SetInverted(true); slider->SetClass("audio-volume"); slider->AddTimer(DynCtx::UpdateAudio, DynCtx::updateTimeFast); slider->OnValueChange(DynCtx::OnChangeVolume); slider->SetRange({0, 1, 0.01}); box->AddChild(std::move(slider)); box->AddChild(std::move(icon)); } parent.AddChild(std::move(box)); } #ifdef WITH_BLUEZ void WidgetBluetooth(Widget& parent) { auto box = Widget::Create(); box->SetSpacing({0, false}); { auto devText = Widget::Create(); DynCtx::btDevText = devText.get(); devText->SetClass("bt-num"); auto iconText = Widget::Create