Skip to content

Commit

Permalink
Demo Wi-Fi Manager Implementation using Raygui and nmcli
Browse files Browse the repository at this point in the history
  • Loading branch information
deanlee committed Jan 12, 2025
1 parent 0877994 commit 95ed4f8
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions system/ui/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
spinner
wifi_demo
1 change: 1 addition & 0 deletions system/ui/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ if not UBUNTU_FOCAL:

if arch != 'aarch64':
renv.Program("spinner", ["raylib/spinner.cc"], LIBS=linked_libs, FRAMEWORKS=mac_frameworks)
renv.Program("wifi_demo", ["raylib/wifi_manager/wifi_manager.cc", "raylib/wifi_manager/nmcli_backend.cc", "raylib/wifi_manager/main.cc"], LIBS=linked_libs, FRAMEWORKS=mac_frameworks)
17 changes: 17 additions & 0 deletions system/ui/raylib/wifi_manager/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "system/ui/raylib/util.h"
#include "system/ui/raylib/wifi_manager/wifi_manager.h"

int main() {
initApp("Wi-Fi Manager", 30);

WifiManager wifi_manager;
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(RAYLIB_BLACK);
wifi_manager.draw({0, 0, (float)GetScreenWidth(), (float)GetScreenHeight()});
EndDrawing();
}

CloseWindow();
return 0;
}
38 changes: 38 additions & 0 deletions system/ui/raylib/wifi_manager/nmcli_backend.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "system/ui/raylib/wifi_manager/nmcli_backend.h"

#include "common/util.h"

std::vector<std::string> split(std::string_view source, char delimiter) {
std::vector<std::string> fields;
size_t last = 0;
for (size_t i = 0; i < source.length(); ++i) {
if (source[i] == delimiter) {
fields.emplace_back(source.substr(last, i - last));
last = i + 1;
}
}
fields.emplace_back(source.substr(last));
return fields;
}

std::vector<Network> list_wifi_networks() {
std::vector<Network> networks;
std::string output = util::check_output("nmcli -t -f IN-USE,SSID --colors no device wifi list");
for (const auto& line : split(output, '\n')) {
auto items = split(line, ':');
if (items.size() != 2 || items[1].empty()) continue;

networks.emplace_back(Network{items[0] == "*", items[1]});
}
return networks;
}

bool connect_to_wifi(const std::string& ssid, const std::string& password) {
std::string command = "nmcli device wifi connect '" + ssid + "' password '" + password + "'";
return system(command.c_str()) == 0;
}

bool forget_wifi(const std::string& ssid) {
std::string command = "nmcli connection delete id '" + ssid + "'";
return system(command.c_str()) == 0;
}
13 changes: 13 additions & 0 deletions system/ui/raylib/wifi_manager/nmcli_backend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <string>
#include <vector>

struct Network {
bool connected;
std::string ssid;
};

std::vector<Network> list_wifi_networks();
bool connect_to_wifi(const std::string& ssid, const std::string& password);
bool forget_wifi(const std::string& ssid);
53 changes: 53 additions & 0 deletions system/ui/raylib/wifi_manager/wifi_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

#include "system/ui/raylib/wifi_manager/wifi_manager.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Raylib's GUI extension
#include "system/ui/raylib/util.h"

WifiManager::WifiManager() {
auto font = getFont();
font.baseSize = 50;
GuiSetFont(font);
wifi_networks_ = list_wifi_networks();
}

void WifiManager::draw(const Rectangle& rect) {
if (is_connecting_) {
showPasswordDialog();
return;
}

// Handle scrollable panel for displaying Wi-Fi networks
Rectangle content_rect = {0, 0, rect.width - 20, wifi_networks_.size() * item_height_};
Rectangle scissor = {0};
GuiScrollPanel(rect, nullptr, content_rect, &scroll_offset_, &scissor);

BeginScissorMode(scissor.x, scissor.y, scissor.width, scissor.height);
// Draw Wi-Fi networks inside the scrollable area
for (int i = 0; i < wifi_networks_.size(); ++i) {
// Draw network SSID and buttons for each network
float yPos = i * item_height_ + scroll_offset_.y;
GuiLabel((Rectangle){20, yPos, 500, item_height_}, wifi_networks_[i].ssid.c_str());
if (GuiButton((Rectangle){550, yPos + 2, 80, item_height_ - 4}, "Connect")) {
selected_network_index_ = i;
memset(password_input_, 0, sizeof(password_input_));
is_connecting_ = true;
}
if (GuiButton((Rectangle){670, yPos + 2, 80, item_height_ - 4}, "Forget")) {
forget_wifi(wifi_networks_[i].ssid)
wifi_networks_ = list_wifi_networks(); // Refresh the list
}
}
EndScissorMode();
}

void WifiManager::showPasswordDialog() {
const auto& ssid = wifi_networks_[selected_network_index_].ssid;
int result = GuiTextInputBox(
(Rectangle){GetScreenWidth() / 2.0f - 120, GetScreenHeight() / 2.0f - 60, 240, 140},
("Connect to " + ssid).c_str(), "Password:", "Ok;Cancel", password_input_, 128, NULL);
is_connecting_ = (result < 0);
if (result == 1) {
connect_to_wifi(ssid, password_input_);
}
}
23 changes: 23 additions & 0 deletions system/ui/raylib/wifi_manager/wifi_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <string>
#include <vector>

#include "system/ui/raylib/raylib.h"
#include "system/ui/raylib/wifi_manager/nmcli_backend.h"

class WifiManager {
public:
WifiManager();
void draw(const Rectangle &rect);

protected:
void showPasswordDialog();

std::vector<Network> wifi_networks_;
Vector2 scroll_offset_ = {0, 0};
int selected_network_index_ = 0;
const float item_height_ = 40;
bool is_connecting_ = false;
char password_input_[128] = {};
};

0 comments on commit 95ed4f8

Please sign in to comment.