mirror of
https://github.com/rock88/moonlight-nx
synced 2024-11-22 11:33:11 +00:00
Work...
This commit is contained in:
parent
048fca0705
commit
93de3481e5
19 changed files with 225 additions and 103 deletions
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3602C3B7245D903000368900 /* HostButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3B5245D903000368900 /* HostButton.cpp */; };
|
||||
361F8A3A245CB44E00A8D9C0 /* moonlight_libretro_wrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 361F8A38245CB44E00A8D9C0 /* moonlight_libretro_wrapper.cpp */; };
|
||||
3652EFCD245B3B00001FABF3 /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF0F245B3B00001FABF3 /* widget.cpp */; };
|
||||
3652EFCE245B3B00001FABF3 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF10245B3B00001FABF3 /* common.cpp */; };
|
||||
|
@ -104,6 +105,8 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3602C3B5245D903000368900 /* HostButton.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = HostButton.cpp; sourceTree = "<group>"; };
|
||||
3602C3B6245D903000368900 /* HostButton.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = HostButton.hpp; sourceTree = "<group>"; };
|
||||
361F8A38245CB44E00A8D9C0 /* moonlight_libretro_wrapper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = moonlight_libretro_wrapper.cpp; sourceTree = "<group>"; };
|
||||
361F8A39245CB44E00A8D9C0 /* moonlight_libretro_wrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = moonlight_libretro_wrapper.h; sourceTree = "<group>"; };
|
||||
3652ECE8245B3AFF001FABF3 /* colorpicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colorpicker.h; sourceTree = "<group>"; };
|
||||
|
@ -547,13 +550,13 @@
|
|||
36DFE0D5245A1FEC00FC51CE /* glsym */,
|
||||
36DFE0CA2459FA3F00FC51CE /* nanogui_resources */,
|
||||
36DFDCF12459F79000FC51CE /* ui */,
|
||||
36B406962459F460005BD903 /* moonlight_glfw.cpp */,
|
||||
3652F003245C28C6001FABF3 /* Server.cpp */,
|
||||
3652F004245C28C6001FABF3 /* Server.hpp */,
|
||||
3652F084245C6CFC001FABF3 /* libretro.h */,
|
||||
3652F085245C6CFC001FABF3 /* moonlight_libretro.c */,
|
||||
361F8A39245CB44E00A8D9C0 /* moonlight_libretro_wrapper.h */,
|
||||
361F8A38245CB44E00A8D9C0 /* moonlight_libretro_wrapper.cpp */,
|
||||
3652F085245C6CFC001FABF3 /* moonlight_libretro.c */,
|
||||
36B406962459F460005BD903 /* moonlight_glfw.cpp */,
|
||||
);
|
||||
path = src;
|
||||
sourceTree = "<group>";
|
||||
|
@ -603,6 +606,8 @@
|
|||
3652F001245B6961001FABF3 /* AddHostWindow.hpp */,
|
||||
3652F081245C60D1001FABF3 /* LoadingOverlay.cpp */,
|
||||
3652F082245C60D1001FABF3 /* LoadingOverlay.hpp */,
|
||||
3602C3B5245D903000368900 /* HostButton.cpp */,
|
||||
3602C3B6245D903000368900 /* HostButton.hpp */,
|
||||
);
|
||||
path = ui;
|
||||
sourceTree = "<group>";
|
||||
|
@ -754,6 +759,7 @@
|
|||
3652EFDD245B3B00001FABF3 /* texture_gl.cpp in Sources */,
|
||||
3652F013245C2919001FABF3 /* http.c in Sources */,
|
||||
3652F069245C292B001FABF3 /* peer.c in Sources */,
|
||||
3602C3B7245D903000368900 /* HostButton.cpp in Sources */,
|
||||
3652EFD0245B3B00001FABF3 /* vscrollpanel.cpp in Sources */,
|
||||
3652F06D245C292B001FABF3 /* win32.c in Sources */,
|
||||
3652F012245C2919001FABF3 /* mkcert.c in Sources */,
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
enableAddressSanitizer = "YES"
|
||||
enableASanStackUseAfterReturn = "YES"
|
||||
enableUBSanitizer = "YES"
|
||||
launchStyle = "0"
|
||||
|
@ -43,11 +42,8 @@
|
|||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<PathRunnable
|
||||
runnableDebuggingMode = "0"
|
||||
FilePath = "/Applications/RetroArch.app">
|
||||
</PathRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "36DBDE8D2450BB7E0057C8D3"
|
||||
|
@ -55,7 +51,7 @@
|
|||
BlueprintName = "moonlight"
|
||||
ReferencedContainer = "container:moonlight.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-L /Users/rock88/Documents/Projects/RetroArch/moonlight-libretro/moonlight_libretro.dylib"
|
||||
|
|
|
@ -4,50 +4,95 @@
|
|||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nanogui/nanogui.h>
|
||||
|
||||
using Task = const std::function<void()>;
|
||||
using namespace std;
|
||||
|
||||
std::mutex m_task_mutex;
|
||||
std::vector<Task> m_tasks;
|
||||
std::thread m_task_thread;
|
||||
using Task = const function<void()>;
|
||||
|
||||
mutex m_task_mutex;
|
||||
vector<Task> m_tasks;
|
||||
thread m_task_thread;
|
||||
|
||||
void perform_load_task(Task &task) {
|
||||
std::lock_guard<std::mutex> guard(m_task_mutex);
|
||||
lock_guard<std::mutex> guard(m_task_mutex);
|
||||
m_tasks.push_back(task);
|
||||
}
|
||||
|
||||
Server::Server() {
|
||||
auto delay = std::chrono::microseconds((int64_t)(500'000));
|
||||
auto delay = chrono::microseconds((int64_t)(500'000));
|
||||
|
||||
m_task_thread = std::thread([delay]() {
|
||||
m_task_thread = thread([delay]() {
|
||||
while (true) {
|
||||
std::vector<Task> tasks; {
|
||||
std::lock_guard<std::mutex> guard(m_task_mutex);
|
||||
tasks = std::vector(m_tasks);
|
||||
vector<Task> tasks; {
|
||||
lock_guard<mutex> guard(m_task_mutex);
|
||||
tasks = vector(m_tasks);
|
||||
m_tasks.clear();
|
||||
}
|
||||
|
||||
for (auto task: tasks) {
|
||||
task();
|
||||
}
|
||||
std::this_thread::sleep_for(delay);
|
||||
this_thread::sleep_for(delay);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Server::connect(std::string address, ServerCallback<SERVER_DATA> &callback) {
|
||||
perform_load_task([address, callback] {
|
||||
void Server::add_host(string address) {
|
||||
if (find(m_hosts.begin(), m_hosts.end(), address) == m_hosts.end()) {
|
||||
m_hosts.push_back(address);
|
||||
}
|
||||
|
||||
ofstream file(m_working_dir + "/hosts.txt");
|
||||
|
||||
for (auto host: m_hosts) {
|
||||
file << host << endl;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
vector<string> Server::hosts() {
|
||||
if (!m_hosts.empty()) {
|
||||
return m_hosts;
|
||||
}
|
||||
|
||||
ifstream in(m_working_dir + "/hosts.txt");
|
||||
|
||||
if (!in) {
|
||||
return {};
|
||||
}
|
||||
|
||||
string str;
|
||||
while (getline(in, str)) {
|
||||
if (str.size() > 0)
|
||||
m_hosts.push_back(str);
|
||||
}
|
||||
in.close();
|
||||
return m_hosts;
|
||||
}
|
||||
|
||||
void Server::connect(string address, ServerCallback<SERVER_DATA> &callback) {
|
||||
perform_load_task([this, address, callback] {
|
||||
SERVER_DATA data;
|
||||
|
||||
int status = gs_init(&data, (char *)address.c_str(), "/Users/rock88/Documents/Projects/RetroArch/moonlight-libretro/key", 0, false);
|
||||
int status = gs_init(&data, (char *)address.c_str(), (m_working_dir + "/key").c_str(), 0, false);
|
||||
|
||||
nanogui::async([address, callback, data, status] {
|
||||
SERVER_DATA copy(data);
|
||||
|
||||
nanogui::async([address, callback, &data, status] {
|
||||
if (status == GS_OK) {
|
||||
callback(Result<SERVER_DATA>::success(&data));
|
||||
callback(Result<SERVER_DATA>::success(©));
|
||||
//free(data);
|
||||
} else {
|
||||
if (gs_error != NULL) {
|
||||
callback(Result<SERVER_DATA>::failure(gs_error));
|
||||
} else {
|
||||
callback(Result<SERVER_DATA>::failure("Unknown error..."));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include "client.h"
|
||||
|
@ -48,16 +49,23 @@ template<class T> using ServerCallback = const std::function<void(Result<T>)>;
|
|||
|
||||
class Server {
|
||||
public:
|
||||
static Server server() {
|
||||
static Server* server = NULL;
|
||||
if (server == NULL) {
|
||||
server = new Server();
|
||||
static Server* server() {
|
||||
static Server server;
|
||||
return &server;
|
||||
}
|
||||
return *server;
|
||||
|
||||
void set_working_dir(const std::string &dir) {
|
||||
m_working_dir = std::string(dir + "/moonlight");
|
||||
}
|
||||
|
||||
void add_host(std::string address);
|
||||
std::vector<std::string> hosts();
|
||||
|
||||
void connect(std::string address, ServerCallback<SERVER_DATA> &callback);
|
||||
|
||||
private:
|
||||
Server();
|
||||
|
||||
std::string m_working_dir;
|
||||
std::vector<std::string> m_hosts;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <GLFW/glfw3.h>
|
||||
#include "glsym/glsym.h"
|
||||
#include "Application.hpp"
|
||||
#include "Server.hpp"
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
glfwInit();
|
||||
|
@ -33,26 +34,22 @@ int main(int argc, const char * argv[]) {
|
|||
glfwGetWindowSize(window, &width, &height);
|
||||
glfwGetFramebufferSize(window, &fb_width, &fb_height);
|
||||
|
||||
Server::server()->set_working_dir("/Users/rock88/Documents/RetroArch/system");
|
||||
|
||||
nanogui::init();
|
||||
nanogui::ref<Application> app = new Application(Size(width, height), Size(fb_width, fb_height));
|
||||
|
||||
nanogui::setup(1.0 / 60.0);
|
||||
nanogui::setup(1.0 / 60.0 * 1000);
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwPollEvents();
|
||||
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
nanogui::draw();
|
||||
|
||||
//glfwGetWindowSize(win, &width, &height);
|
||||
//glViewport(0, 0, width, height);
|
||||
//glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
//glfwWaitEvents();
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -133,39 +133,28 @@ void retro_run(void) {
|
|||
|
||||
double mouse_x = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
|
||||
double mouse_y = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
|
||||
double pointer_x = 0;
|
||||
double pointer_y = 0;
|
||||
|
||||
// if (mouse_x == 0 && mouse_y == 0) {
|
||||
// int pointer_x = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
||||
// int pointer_y = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
|
||||
//
|
||||
// if (pointer_x != 0 && pointer_y != 0) {
|
||||
// mouse_x = (pointer_x / 32768.0f + 1) / 2 * width;
|
||||
// mouse_y = (pointer_y / 32768.0f + 1) / 2 * height;
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO: Pointers in MacBook currently work incorrectly...
|
||||
if (input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED)) {
|
||||
int p_x = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
||||
int p_y = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
|
||||
|
||||
//int px=(int)((float)retro.width/854.0*(float)p_x);
|
||||
//int py=(int)((float)retro.height/480.0*(float)p_y);
|
||||
mouse_x=(int)((p_x+0x7fff)*width/0xffff);
|
||||
mouse_y=(int)((p_y+0x7fff)*height/0xffff);
|
||||
pointer_x = (p_x + 0x7fff) * width / 0xffff;
|
||||
pointer_y = (p_y + 0x7fff) * height / 0xffff;
|
||||
}
|
||||
|
||||
if (mouse_x != 0 && mouse_y != 0) {
|
||||
moonlight_libretro_wrapper_handle_mouse_move(mouse_x, mouse_y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
|
||||
static bool mouse_l_pressed = false;
|
||||
|
||||
if (input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) && !mouse_l_pressed) {
|
||||
if (pointer_x != 0 && pointer_y != 0) {
|
||||
moonlight_libretro_wrapper_handle_mouse_move(pointer_x, pointer_y);
|
||||
}
|
||||
|
||||
mouse_l_pressed = true;
|
||||
moonlight_libretro_wrapper_handle_mouse_button(0, 1, 0);
|
||||
} else if (!input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) && mouse_l_pressed) {
|
||||
|
@ -177,7 +166,6 @@ void retro_run(void) {
|
|||
glBindFramebuffer(RARCH_GL_FRAMEBUFFER, hw_render.get_current_framebuffer());
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
moonlight_libretro_wrapper_draw();
|
||||
|
||||
video_cb(RETRO_HW_FRAME_BUFFER_VALID, width, height, 0);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "moonlight_libretro_wrapper.h"
|
||||
#include "Application.hpp"
|
||||
#include "Server.hpp"
|
||||
#include <openssl/ssl.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@ -23,17 +24,15 @@ void moonlight_libretro_wrapper_init(int width, int height) {
|
|||
nanogui::setup(1.0 / 60.0);
|
||||
}
|
||||
|
||||
void moonlight_libretro_wrapper_set_working_dir(char* dir) {
|
||||
|
||||
void moonlight_libretro_wrapper_set_working_dir(const char* dir) {
|
||||
Server::server()->set_working_dir(dir);
|
||||
}
|
||||
|
||||
void moonlight_libretro_wrapper_handle_mouse_move(double x, double y) {
|
||||
//printf("mouse_move: %fx%f\n", x, y);
|
||||
nanogui::cursor_pos_callback_event(x, y);
|
||||
}
|
||||
|
||||
void moonlight_libretro_wrapper_handle_mouse_button(int button, int action, int modifiers) {
|
||||
//printf("mouse_button: %i x %i\n", button, action);
|
||||
nanogui::mouse_button_callback_event(button, action, modifiers);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#endif
|
||||
|
||||
EXTERN void moonlight_libretro_wrapper_init(int width, int height);
|
||||
EXTERN void moonlight_libretro_wrapper_set_working_dir(char* dir);
|
||||
EXTERN void moonlight_libretro_wrapper_set_working_dir(const char* dir);
|
||||
EXTERN void moonlight_libretro_wrapper_handle_mouse_move(double x, double y);
|
||||
EXTERN void moonlight_libretro_wrapper_handle_mouse_button(int button, int action, int modifiers);
|
||||
EXTERN void moonlight_libretro_wrapper_draw();
|
||||
|
|
|
@ -37,6 +37,7 @@ AddHostWindow::AddHostWindow(Widget *parent): ContentWindow(parent, "Add Host")
|
|||
|
||||
auto backspace = other_buttons_container->add<Button>("");
|
||||
backspace->set_icon(FA_BACKSPACE);
|
||||
backspace->set_icon_extra_scale(2);
|
||||
backspace->set_fixed_size(Size(210, 100));
|
||||
backspace->set_callback([text] {
|
||||
if (text->value().size() > 0) {
|
||||
|
@ -52,14 +53,14 @@ AddHostWindow::AddHostWindow(Widget *parent): ContentWindow(parent, "Add Host")
|
|||
if (text->value().size() > 0) {
|
||||
auto loader = add<LoadingOverlay>();
|
||||
|
||||
Server::server().connect(text->value(), [this, loader](auto result) {
|
||||
Server::server()->connect(text->value(), [this, loader](auto result) {
|
||||
loader->dispose();
|
||||
|
||||
if (result.isSuccess()) {
|
||||
printf("Pair: %i\n", result.value()->paired);
|
||||
Server::server()->add_host(result.value()->serverInfo.address);
|
||||
m_host_added_callback(*result.value());
|
||||
} else {
|
||||
screen()->add<MessageDialog>(MessageDialog::Type::Information, "Error", result.error());
|
||||
printf("Error: %s\n", result.error().c_str());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,24 +5,10 @@
|
|||
using namespace nanogui;
|
||||
|
||||
Application::Application(Vector2f size, Vector2f framebuffer_size): Screen(size, framebuffer_size) {
|
||||
auto main = push_window<MainWindow>();
|
||||
main->set_add_host_callback([this] {
|
||||
this->push_window<AddHostWindow>();
|
||||
});
|
||||
}
|
||||
theme()->m_button_font_size = 24;
|
||||
theme()->m_text_box_font_size = 34;
|
||||
|
||||
template<typename WidgetClass, typename... Args>
|
||||
WidgetClass* Application::push_window(const Args&... args) {
|
||||
for (auto window: m_windows) {
|
||||
window->set_visible(false);
|
||||
}
|
||||
|
||||
auto window = new WidgetClass(this, args...);
|
||||
window->set_size(size());
|
||||
window->set_fixed_size(size());
|
||||
m_windows.push_back(window);
|
||||
perform_layout();
|
||||
return window;
|
||||
push_window<MainWindow>();
|
||||
}
|
||||
|
||||
void Application::pop_window() {
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
#include <nanogui/nanogui.h>
|
||||
#include "ContentWindow.hpp"
|
||||
#pragma once
|
||||
|
||||
#define Size(x, y) (nanogui::Vector2f((x), (y)))
|
||||
|
||||
class Application: public nanogui::Screen {
|
||||
public:
|
||||
Application(nanogui::Vector2f size, nanogui::Vector2f framebuffer_size);
|
||||
|
||||
template<typename WidgetClass, typename... Args>
|
||||
WidgetClass* push_window(const Args&... args);
|
||||
WidgetClass* push_window(const Args&... args) {
|
||||
for (auto window: m_windows) {
|
||||
window->set_visible(false);
|
||||
}
|
||||
|
||||
auto window = new WidgetClass(this, args...);
|
||||
window->set_size(size());
|
||||
window->set_fixed_size(size());
|
||||
m_windows.push_back(window);
|
||||
perform_layout();
|
||||
return window;
|
||||
}
|
||||
|
||||
void pop_window();
|
||||
|
||||
private:
|
||||
std::vector<ContentWindow *> m_windows;
|
||||
std::vector<Widget *> m_windows;
|
||||
};
|
||||
|
|
|
@ -60,6 +60,5 @@ void ContentWindow::set_left_title_button(int icon, const std::function<void()>
|
|||
}
|
||||
|
||||
void ContentWindow::pop() {
|
||||
auto app = static_cast<Application *>(screen());
|
||||
app->pop_window();
|
||||
application()->pop_window();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include <nanogui/nanogui.h>
|
||||
#include "Application.hpp"
|
||||
#pragma once
|
||||
|
||||
#define Size(x, y) (nanogui::Vector2f((x), (y)))
|
||||
|
||||
class ContentWindow: public nanogui::Widget {
|
||||
public:
|
||||
ContentWindow(Widget *parent, const std::string& title);
|
||||
|
@ -22,7 +21,12 @@ public:
|
|||
return m_container;
|
||||
}
|
||||
|
||||
void set_box_layout(nanogui::Orientation orientation, nanogui::Alignment alignment = nanogui::Alignment::Middle, int margin = 0, int spacing = 0) {
|
||||
Application* application() {
|
||||
auto application = static_cast<Application *>(screen());
|
||||
return application;
|
||||
}
|
||||
|
||||
void set_box_layout(nanogui::Orientation orientation, nanogui::Alignment alignment = nanogui::Alignment::Middle, int margin = 10, int spacing = 10) {
|
||||
m_container->set_layout(new nanogui::BoxLayout(orientation, alignment, margin, spacing));
|
||||
}
|
||||
|
||||
|
|
32
src/ui/HostButton.cpp
Normal file
32
src/ui/HostButton.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "HostButton.hpp"
|
||||
#include "Server.hpp"
|
||||
|
||||
using namespace nanogui;
|
||||
|
||||
HostButton::HostButton(Widget* parent, const std::string &host): Button(parent, "", FA_QUESTION) {
|
||||
m_host = host;
|
||||
m_data.paired = false;
|
||||
set_icon_extra_scale(2);
|
||||
set_icon_position(IconPosition::LeftCentered);
|
||||
|
||||
set_layout(new BoxLayout(Orientation::Vertical, Alignment::Middle));
|
||||
add<Widget>()->set_fixed_height(80);
|
||||
add<Label>(host);
|
||||
|
||||
Server::server()->connect(host, [this](auto result) {
|
||||
if (result.isSuccess()) {
|
||||
m_data = *result.value();
|
||||
|
||||
if (m_data.paired) {
|
||||
set_icon(FA_CHECK);
|
||||
} else {
|
||||
set_icon(FA_EXCLAMATION);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HostButton::draw(NVGcontext *ctx) {
|
||||
Button::draw(ctx);
|
||||
Widget::draw(ctx);
|
||||
}
|
18
src/ui/HostButton.hpp
Normal file
18
src/ui/HostButton.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <nanogui/nanogui.h>
|
||||
#include "Server.hpp"
|
||||
#pragma once
|
||||
|
||||
class HostButton: public nanogui::Button {
|
||||
public:
|
||||
HostButton(Widget* parent, const std::string &host);
|
||||
|
||||
SERVER_DATA server_data() {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void draw(NVGcontext *ctx) override;
|
||||
|
||||
private:
|
||||
std::string m_host;
|
||||
SERVER_DATA m_data;
|
||||
};
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
using namespace nanogui;
|
||||
|
||||
LoadingOverlay::LoadingOverlay(Widget* parent): Widget(parent->screen()) {
|
||||
LoadingOverlay::LoadingOverlay(Widget* parent, const std::string &caption): Widget(parent->screen()) {
|
||||
set_fixed_size(parent->screen()->size());
|
||||
set_layout(new BoxLayout(Orientation::Vertical, Alignment::Middle));
|
||||
add<Widget>()->set_fixed_height(fixed_height() / 2 - 60);
|
||||
add<Label>(caption)->set_font_size(24);
|
||||
|
||||
m_icon = FA_SPINNER;
|
||||
screen()->perform_layout();
|
||||
|
@ -33,6 +36,8 @@ void LoadingOverlay::draw(NVGcontext *ctx) {
|
|||
nvgText(ctx, 0, 0, utf8(m_icon).data(), NULL);
|
||||
|
||||
nvgRestore(ctx);
|
||||
|
||||
Widget::draw(ctx);
|
||||
}
|
||||
|
||||
bool LoadingOverlay::mouse_enter_event(const nanogui::Vector2i &p, bool enter) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
class LoadingOverlay: public nanogui::Widget {
|
||||
public:
|
||||
LoadingOverlay(nanogui::Widget* parent);
|
||||
LoadingOverlay(nanogui::Widget* parent, const std::string &caption = "");
|
||||
|
||||
void draw(NVGcontext *ctx) override;
|
||||
|
||||
|
|
|
@ -1,13 +1,41 @@
|
|||
#include "MainWindow.hpp"
|
||||
#include "AddHostWindow.hpp"
|
||||
#include "HostButton.hpp"
|
||||
#include "Server.hpp"
|
||||
#include "LoadingOverlay.hpp"
|
||||
|
||||
using namespace nanogui;
|
||||
|
||||
MainWindow::MainWindow(Widget *parent): ContentWindow(parent, "Moonlight") {
|
||||
set_box_layout(Orientation::Horizontal, Alignment::Minimum, 10, 10);
|
||||
set_box_layout(Orientation::Horizontal, Alignment::Minimum);
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
void MainWindow::reload() {
|
||||
for (auto child: container()->children()) {
|
||||
container()->remove_child(child);
|
||||
}
|
||||
|
||||
for (auto host: Server::server()->hosts()) {
|
||||
auto button = container()->add<HostButton>(host);
|
||||
button->set_fixed_size(Size(100, 100));
|
||||
button->set_callback([this, button] {
|
||||
if (button->server_data().paired) {
|
||||
|
||||
} else {
|
||||
add<LoadingOverlay>("Pairing...");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
auto button = container()->add<Button>("Add Host");
|
||||
button->set_fixed_size(Size(100, 100));
|
||||
button->set_callback([this] {
|
||||
this->m_add_host_callback();
|
||||
auto add_host = application()->push_window<AddHostWindow>();
|
||||
add_host->set_host_added_callback([this](auto _) {
|
||||
this->reload();
|
||||
this->application()->pop_window();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,8 +5,5 @@ class MainWindow: public ContentWindow {
|
|||
public:
|
||||
MainWindow(Widget *parent);
|
||||
|
||||
void set_add_host_callback(const std::function<void()> &callback) { m_add_host_callback = callback; }
|
||||
|
||||
private:
|
||||
std::function<void()> m_add_host_callback;
|
||||
void reload();
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue