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 abf969e
Show file tree
Hide file tree
Showing 7 changed files with 147 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);
55 changes: 55 additions & 0 deletions system/ui/raylib/wifi_manager/wifi_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

#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_) {
dispalyInputDialog();
return;
}

// Handle scrollable panel for displaying Wi-Fi networks
Vector2 scroll_offset = {0, 0};
GuiScrollPanel(rect, nullptr, rect, &scroll_offset, nullptr);

// Draw Wi-Fi networks inside the scrollable area
for (int i = 0; i < wifi_networks_.size(); ++i) {
float yPos = i * item_height_ - scroll_offset.y;
if (yPos >= rect.height || yPos + item_height_ < 0) continue; // Skip drawing out of visible area

// Draw network SSID and buttons for each network
GuiLabel((Rectangle){20, yPos, 500, item_height_}, wifi_networks_[i].ssid.c_str());
if (GuiButton((Rectangle){550, yPos, 80, 30}, "Connect")) {
selected_network_index_ = i;
memset(password_input_, 0, sizeof(password_input_));
is_connecting_ = true;
}
if (GuiButton((Rectangle){670, yPos, 80, item_height_}, "Forget")) {
if (forget_wifi(wifi_networks_[i].ssid)) {
wifi_networks_ = list_wifi_networks(); // Refresh the list
}
}
}
}

void WifiManager::dispalyInputDialog() {
// TODO: Replace with a keyboard widget for password input.
GuiLabel((Rectangle){230, 180, 200, 30}, "Enter Wi-Fi Password:");
GuiTextBox((Rectangle){230, 220, 340, 30}, password_input_, 128, true);

if (GuiButton((Rectangle){230, 270, 160, 30}, "Submit")) {
connect_to_wifi(wifi_networks_[selected_network_index_].ssid, password_input_);
is_connecting_ = false; // Close the dialog
} else if (GuiButton((Rectangle){410, 270, 160, 30}, "Cancel")) {
is_connecting_ = false;
}
}
22 changes: 22 additions & 0 deletions system/ui/raylib/wifi_manager/wifi_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#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 dispalyInputDialog();

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

0 comments on commit abf969e

Please sign in to comment.