join_menu.c: Update serial/IPv4 GUI menus
This commit is contained in:
parent
6f5058c584
commit
eed4687120
|
@ -1,13 +1,14 @@
|
||||||
#include <menu.h>
|
#include <menu.h>
|
||||||
#include <menu_private.h>
|
#include <menu_private.h>
|
||||||
#include <game.h>
|
|
||||||
#include <gui.h>
|
#include <gui.h>
|
||||||
#include <gui/button.h>
|
#include <gui/button.h>
|
||||||
#include <gui/container.h>
|
#include <gui/container.h>
|
||||||
|
#include <gui/checkbox.h>
|
||||||
#include <gui/label.h>
|
#include <gui/label.h>
|
||||||
#include <gui/line_edit.h>
|
#include <gui/line_edit.h>
|
||||||
#include <gui/rounded_rect.h>
|
#include <gui/rounded_rect.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
#include <net/serial.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -16,8 +17,8 @@
|
||||||
struct join_menu
|
struct join_menu
|
||||||
{
|
{
|
||||||
struct gui_container cnt, bcnt;
|
struct gui_container cnt, bcnt;
|
||||||
struct gui_label type_label, address, port, connecting;
|
struct gui_label type_label, address_device, port, connecting, speed;
|
||||||
struct gui_button type_btn, back, connect;
|
struct gui_button type_btn, back, connect, device_btn, speed_btn;
|
||||||
struct gui_line_edit address_le, port_le;
|
struct gui_line_edit address_le, port_le;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -30,7 +31,8 @@ struct join_menu
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
struct net_socket *socket;
|
struct net_socket *socket;
|
||||||
size_t domain_i;
|
size_t domain_i, speed_i, device_i, n_devices;
|
||||||
|
const char *const *devices;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const enum net_domain domains[] =
|
static const enum net_domain domains[] =
|
||||||
|
@ -39,22 +41,22 @@ static const enum net_domain domains[] =
|
||||||
NET_DOMAIN_SERIAL
|
NET_DOMAIN_SERIAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *const speeds[] =
|
||||||
|
{
|
||||||
|
"19200", "38400", "57600", "115200"
|
||||||
|
};
|
||||||
|
|
||||||
static void on_connected(void *const arg)
|
static void on_connected(void *const arg)
|
||||||
{
|
{
|
||||||
struct join_menu *const m = arg;
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
if (m->state == IDLE)
|
m->state = CONNECTED;
|
||||||
{
|
|
||||||
m->state = CONNECT;
|
|
||||||
m->connecting.text = "Connecting...";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_disconnected(void *const arg)
|
static void on_disconnected(void *const arg)
|
||||||
{
|
{
|
||||||
struct join_menu *const m = arg;
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
m->connecting.text = "Failed to connect";
|
|
||||||
m->state = CONNECT_FAILED;
|
m->state = CONNECT_FAILED;
|
||||||
m->socket = NULL;
|
m->socket = NULL;
|
||||||
}
|
}
|
||||||
|
@ -83,10 +85,13 @@ static int on_connect(struct join_menu *const m)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
const unsigned long port = strtoul(m->port_le.text, NULL, 0);
|
const unsigned long port = strtoul(m->port_le.text, NULL, 10);
|
||||||
|
|
||||||
if (errno)
|
if (errno)
|
||||||
|
{
|
||||||
|
m->connecting.text = "Invalid port";
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
c.ipv4.addr = m->address_le.text;
|
c.ipv4.addr = m->address_le.text;
|
||||||
c.ipv4.port = port;
|
c.ipv4.port = port;
|
||||||
|
@ -100,6 +105,7 @@ static int on_connect(struct join_menu *const m)
|
||||||
if (!(m->socket = net_connect(&c)))
|
if (!(m->socket = net_connect(&c)))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: net_connect failed\n", __func__);
|
fprintf(stderr, "%s: net_connect failed\n", __func__);
|
||||||
|
on_disconnected(m);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,17 +129,20 @@ static int update(struct menu_common *const c, void *const arg)
|
||||||
{
|
{
|
||||||
case CONNECT:
|
case CONNECT:
|
||||||
if (on_connect(m))
|
if (on_connect(m))
|
||||||
return -1;
|
{
|
||||||
|
m->state = CONNECT_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m->state = CONNECTING;
|
m->state = CONNECTING;
|
||||||
|
m->connecting.text = "Connecting...";
|
||||||
if (!m->connecting.common.parent)
|
m->connecting.common.hidden = false;
|
||||||
gui_add_child(&m->cnt.common, &m->connecting.common);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONNECT_FAILED:
|
case CONNECT_FAILED:
|
||||||
net_close(m->socket);
|
net_close(m->socket);
|
||||||
|
m->connecting.text = "Failed to connect";
|
||||||
|
m->connecting.common.hidden = false;
|
||||||
m->socket = NULL;
|
m->socket = NULL;
|
||||||
m->state = IDLE;
|
m->state = IDLE;
|
||||||
break;
|
break;
|
||||||
|
@ -156,21 +165,80 @@ static int render(const struct menu_common *const c, void *const arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int update_domain(struct join_menu *const m)
|
||||||
|
{
|
||||||
|
switch (domains[m->domain_i])
|
||||||
|
{
|
||||||
|
case NET_DOMAIN_IPV4:
|
||||||
|
m->port.common.hidden = false;
|
||||||
|
m->port_le.common.hidden = false;
|
||||||
|
m->address_le.common.hidden = false;
|
||||||
|
m->device_btn.common.hidden = true;
|
||||||
|
m->speed.common.hidden = true;
|
||||||
|
m->speed_btn.common.hidden = true;
|
||||||
|
m->address_device.text = "Address:";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NET_DOMAIN_SERIAL:
|
||||||
|
m->port.common.hidden = true;
|
||||||
|
m->port_le.common.hidden = true;
|
||||||
|
m->address_le.common.hidden = true;
|
||||||
|
m->device_btn.common.hidden = false;
|
||||||
|
m->speed.common.hidden = false;
|
||||||
|
m->speed_btn.common.hidden = false;
|
||||||
|
m->address_device.text = "Device:";
|
||||||
|
m->speed_btn.u.type1.label.text = speeds[m->speed_i = 0];
|
||||||
|
m->devices = net_serial_devices(&m->n_devices);
|
||||||
|
|
||||||
|
if (!m->devices)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
m->device_btn.u.type1.label.text = m->devices[m->device_i = 0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void on_type_pressed(void *const arg)
|
static void on_type_pressed(void *const arg)
|
||||||
{
|
{
|
||||||
struct join_menu *const m = arg;
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
if (++m->domain_i >= sizeof domains / sizeof *domains)
|
do
|
||||||
m->domain_i = 0;
|
if (++m->domain_i >= sizeof domains / sizeof *domains)
|
||||||
|
m->domain_i = 0;
|
||||||
|
while (!net_available(domains[m->domain_i]));
|
||||||
|
|
||||||
m->type_btn.u.type1.label.text = net_domain_str(domains[m->domain_i]);
|
m->type_btn.u.type1.label.text = net_domain_str(domains[m->domain_i]);
|
||||||
|
update_domain(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_device_pressed(void *const arg)
|
||||||
|
{
|
||||||
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
|
if (++m->device_i >= m->n_devices)
|
||||||
|
m->device_i = 0;
|
||||||
|
|
||||||
|
m->device_btn.u.type1.label.text = m->devices[m->device_i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_speed_pressed(void *const arg)
|
||||||
|
{
|
||||||
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
|
if (++m->speed_i >= sizeof speeds / sizeof *speeds)
|
||||||
|
m->speed_i = 0;
|
||||||
|
|
||||||
|
m->speed_btn.u.type1.label.text = speeds[m->speed_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_connect_pressed(void *const arg)
|
static void on_connect_pressed(void *const arg)
|
||||||
{
|
{
|
||||||
struct join_menu *const m = arg;
|
struct join_menu *const m = arg;
|
||||||
|
|
||||||
m->state = CONNECT;
|
if (m->state == IDLE)
|
||||||
|
m->state = CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int menu_join(struct menu_common *const c)
|
int menu_join(struct menu_common *const c)
|
||||||
|
@ -191,18 +259,28 @@ int menu_join(struct menu_common *const c)
|
||||||
m.type_label.text = "Type:";
|
m.type_label.text = "Type:";
|
||||||
gui_add_child(&m.cnt.common, &m.type_label.common);
|
gui_add_child(&m.cnt.common, &m.type_label.common);
|
||||||
|
|
||||||
|
while (!net_available(domains[m.domain_i]))
|
||||||
|
if (++m.domain_i >= sizeof domains / sizeof *domains)
|
||||||
|
return -1;
|
||||||
|
|
||||||
gui_button_init(&m.type_btn, GUI_BUTTON_TYPE_1);
|
gui_button_init(&m.type_btn, GUI_BUTTON_TYPE_1);
|
||||||
m.type_btn.arg = &m;
|
m.type_btn.arg = &m;
|
||||||
m.type_btn.u.type1.w = 140;
|
m.type_btn.u.type1.w = 140;
|
||||||
m.type_btn.common.hcentered = true;
|
m.type_btn.common.hcentered = true;
|
||||||
m.type_btn.on_pressed = on_type_pressed;
|
m.type_btn.on_pressed = on_type_pressed;
|
||||||
m.type_btn.u.type1.label.text = net_domain_str(*domains);
|
m.type_btn.u.type1.label.text = net_domain_str(domains[m.domain_i]);
|
||||||
gui_add_child(&m.cnt.common, &m.type_btn.common);
|
gui_add_child(&m.cnt.common, &m.type_btn.common);
|
||||||
|
|
||||||
gui_label_init(&m.address);
|
gui_label_init(&m.address_device);
|
||||||
m.address.common.hcentered = true;
|
m.address_device.common.hcentered = true;
|
||||||
m.address.text = "Address:";
|
gui_add_child(&m.cnt.common, &m.address_device.common);
|
||||||
gui_add_child(&m.cnt.common, &m.address.common);
|
|
||||||
|
gui_button_init(&m.device_btn, GUI_BUTTON_TYPE_1);
|
||||||
|
m.device_btn.common.hcentered = true;
|
||||||
|
m.device_btn.on_pressed = on_device_pressed;
|
||||||
|
m.device_btn.arg = &m;
|
||||||
|
m.device_btn.u.type1.w = 140;
|
||||||
|
gui_add_child(&m.cnt.common, &m.device_btn.common);
|
||||||
|
|
||||||
char address[sizeof "255.255.255.255"];
|
char address[sizeof "255.255.255.255"];
|
||||||
gui_line_edit_init(&m.address_le, address, sizeof address);
|
gui_line_edit_init(&m.address_le, address, sizeof address);
|
||||||
|
@ -221,8 +299,22 @@ int menu_join(struct menu_common *const c)
|
||||||
m.port_le.common.hcentered = true;
|
m.port_le.common.hcentered = true;
|
||||||
gui_add_child(&m.cnt.common, &m.port_le.common);
|
gui_add_child(&m.cnt.common, &m.port_le.common);
|
||||||
|
|
||||||
|
gui_label_init(&m.speed);
|
||||||
|
m.speed.font = FONT;
|
||||||
|
m.speed.text = "Baud rate:";
|
||||||
|
m.speed.common.hcentered = true;
|
||||||
|
gui_add_child(&m.cnt.common, &m.speed.common);
|
||||||
|
|
||||||
|
gui_button_init(&m.speed_btn, GUI_BUTTON_TYPE_1);
|
||||||
|
m.speed_btn.arg = &m;
|
||||||
|
m.speed_btn.on_pressed = on_speed_pressed;
|
||||||
|
m.speed_btn.u.type1.w = 140;
|
||||||
|
gui_add_child(&m.cnt.common, &m.speed_btn.common);
|
||||||
|
|
||||||
gui_label_init(&m.connecting);
|
gui_label_init(&m.connecting);
|
||||||
m.connecting.common.hcentered = true;
|
m.connecting.common.hcentered = true;
|
||||||
|
m.connecting.common.hidden = true;
|
||||||
|
gui_add_child(&m.cnt.common, &m.connecting.common);
|
||||||
|
|
||||||
gui_container_init(&m.bcnt);
|
gui_container_init(&m.bcnt);
|
||||||
m.bcnt.common.hcentered = true;
|
m.bcnt.common.hcentered = true;
|
||||||
|
@ -246,6 +338,9 @@ int menu_join(struct menu_common *const c)
|
||||||
m.back.common.vcentered = true;
|
m.back.common.vcentered = true;
|
||||||
gui_add_child(&m.bcnt.common, &m.back.common);
|
gui_add_child(&m.bcnt.common, &m.back.common);
|
||||||
|
|
||||||
|
if (update_domain(&m))
|
||||||
|
return -1;
|
||||||
|
|
||||||
while (!back && !c->p.common.exit && !connect)
|
while (!back && !c->p.common.exit && !connect)
|
||||||
{
|
{
|
||||||
if (menu_update(c, update, render, &m))
|
if (menu_update(c, update, render, &m))
|
||||||
|
|
Loading…
Reference in New Issue