parent
5ab6aefa49
commit
ee60060dc6
@ -0,0 +1,65 @@ |
|||||||
|
[CCode (cheader_filename = "utils/array.h")] |
||||||
|
namespace Array |
||||||
|
{ |
||||||
|
void* get(void* array, size_t index); |
||||||
|
size_t count(void* array); |
||||||
|
} |
||||||
|
|
||||||
|
[CCode (cheader_filename = "device/device.h")] |
||||||
|
namespace Device |
||||||
|
{ |
||||||
|
// Obtain device array |
||||||
|
void* get_array(); |
||||||
|
|
||||||
|
[CCode (cname = "device_capacity_t", cprefix = "DEVICE_CAPACITY_", has_type_id = false)] |
||||||
|
public enum Capacity |
||||||
|
{ |
||||||
|
MOUSE = (1 << 0), |
||||||
|
KEYBOARD = (1 << 1), |
||||||
|
WIRELESS = (1 << 10) |
||||||
|
} |
||||||
|
|
||||||
|
// Handle a specific device |
||||||
|
unowned string get_name(void* device); |
||||||
|
string get_image(void* device); |
||||||
|
int get_capacity(void* device); |
||||||
|
unowned string get_manufacturer(void* device); |
||||||
|
|
||||||
|
[CCode (cname = "struct MOUSE", free_function = "", has_type_id = false)] |
||||||
|
public struct Mouse |
||||||
|
{ |
||||||
|
// DPI |
||||||
|
uint max_level_count; |
||||||
|
uint level_count; |
||||||
|
uint level_current; |
||||||
|
bool led_available; |
||||||
|
bool xy_available; |
||||||
|
uint dpi_x[8]; |
||||||
|
uchar r[8]; |
||||||
|
uchar g[8]; |
||||||
|
uchar b[8]; |
||||||
|
|
||||||
|
// Polling rate |
||||||
|
uint polling_rate_count; |
||||||
|
uint polling_rate_current; |
||||||
|
uint polling_rates[8]; |
||||||
|
|
||||||
|
// Features |
||||||
|
bool angle_snap; |
||||||
|
bool motion_sync; |
||||||
|
} |
||||||
|
|
||||||
|
public int mouse_get(void* device, Mouse* output); |
||||||
|
public int mouse_set(void* device, Mouse* input); |
||||||
|
|
||||||
|
[CCode (cname = "struct WIRELESS", free_function = "", has_type_id = false)] |
||||||
|
public struct Wireless |
||||||
|
{ |
||||||
|
int battery_level; |
||||||
|
bool charging; |
||||||
|
bool connection_wireless; |
||||||
|
} |
||||||
|
|
||||||
|
public int wireless_get(void* device, Wireless* output); |
||||||
|
public int wireless_set(void* device, Wireless* input); |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
public class GinputApplication : Adw.Application { |
||||||
|
|
||||||
|
public GinputApplication() { |
||||||
|
Object(application_id: "v.ginput", flags:ApplicationFlags.DEFAULT_FLAGS); |
||||||
|
} |
||||||
|
|
||||||
|
public override void activate() { |
||||||
|
var win = new MainWindow(this); |
||||||
|
win.present(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
using Device; |
||||||
|
|
||||||
|
[GtkTemplate (ui="/v/ginput/main-window.ui")] |
||||||
|
public class MainWindow : Adw.ApplicationWindow |
||||||
|
{ |
||||||
|
[GtkChild] |
||||||
|
protected unowned Gtk.ListBox device_list; |
||||||
|
[GtkChild] |
||||||
|
protected unowned Gtk.Stack stack; |
||||||
|
|
||||||
|
protected Panel active_panel; |
||||||
|
|
||||||
|
public MainWindow(Adw.Application app) |
||||||
|
{ |
||||||
|
Object(application:app, resizable:true, title:"Input devices", icon_name:"ginput-icon", show_menubar:false); |
||||||
|
} |
||||||
|
|
||||||
|
construct |
||||||
|
{ |
||||||
|
init_template(); |
||||||
|
set_default_size(1024, 768); |
||||||
|
device_list.row_selected.connect(select_device); |
||||||
|
} |
||||||
|
|
||||||
|
void activate_panel(Panel panel) |
||||||
|
{ |
||||||
|
var pname = panel.get_name(); |
||||||
|
if(stack.get_child_by_name(pname) == null) |
||||||
|
stack.add_named(panel, pname); |
||||||
|
stack.set_visible_child_name(pname); |
||||||
|
active_panel = panel; |
||||||
|
} |
||||||
|
|
||||||
|
void select_device(Gtk.ListBox list, Gtk.ListBoxRow? row) |
||||||
|
{ |
||||||
|
if(row == null) |
||||||
|
return; |
||||||
|
|
||||||
|
void* device = row.get_data("ginput_device"); |
||||||
|
var name = Device.get_name(device); |
||||||
|
|
||||||
|
Panel devpane; |
||||||
|
var capacity = Device.get_capacity(device); |
||||||
|
if((capacity & Device.Capacity.MOUSE) != 0) |
||||||
|
devpane = new MousePanel(name, device); |
||||||
|
else |
||||||
|
{ |
||||||
|
stderr.printf("Warning: selected device with unsupported capacity\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
activate_panel(devpane); |
||||||
|
} |
||||||
|
|
||||||
|
public void add_device(void* device) |
||||||
|
{ |
||||||
|
Gtk.ListBoxRow row = new Gtk.ListBoxRow(); |
||||||
|
Gtk.Label label = new Gtk.Label(Device.get_name(device)); |
||||||
|
label.add_css_class("body"); |
||||||
|
label.set_margin_top(7); |
||||||
|
label.set_margin_bottom(7); |
||||||
|
row.set_child(label); |
||||||
|
row.set_data("ginput_device", device); |
||||||
|
|
||||||
|
device_list.append(row); |
||||||
|
} |
||||||
|
|
||||||
|
public override void constructed() |
||||||
|
{ |
||||||
|
// Add all devices to the window |
||||||
|
var devices = Device.get_array(); |
||||||
|
for(size_t i = 0; i < Array.count(devices); i++) |
||||||
|
add_device(Array.get(devices, i)); |
||||||
|
|
||||||
|
// Activate empty panel by default |
||||||
|
activate_panel(new EmptyPanel()); |
||||||
|
|
||||||
|
base.constructed(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
[GtkTemplate (ui="/v/ginput/panel.ui")] |
||||||
|
public abstract class Panel : Adw.Bin, Gtk.Buildable |
||||||
|
{ |
||||||
|
[GtkChild] |
||||||
|
protected unowned Adw.Bin content_bin; |
||||||
|
[GtkChild] |
||||||
|
protected unowned Gtk.Box main_box; |
||||||
|
[GtkChild] |
||||||
|
protected unowned Adw.Bin titlebar_bin; |
||||||
|
[GtkChild] |
||||||
|
protected unowned Adw.HeaderBar titlebar; |
||||||
|
|
||||||
|
protected Adw.WindowTitle titlebar_title; |
||||||
|
|
||||||
|
protected Panel(string name) |
||||||
|
{ |
||||||
|
this.name = name; |
||||||
|
|
||||||
|
titlebar_title = new Adw.WindowTitle(this.name, ""); |
||||||
|
titlebar.set_title_widget(titlebar_title); |
||||||
|
} |
||||||
|
|
||||||
|
construct |
||||||
|
{ |
||||||
|
init_template(); |
||||||
|
} |
||||||
|
|
||||||
|
void add_child(Gtk.Builder builder, Object child, string? type) |
||||||
|
{ |
||||||
|
if(type != null && type == "content") |
||||||
|
{ |
||||||
|
content_bin.set_child(((Gtk.Widget) child)); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
base.add_child(builder, child, type); |
||||||
|
} |
||||||
|
} |
@ -1,87 +0,0 @@ |
|||||||
#include "ginput-application.h" |
|
||||||
#include "ui/main-window.h" |
|
||||||
|
|
||||||
struct _GinputApplication |
|
||||||
{ |
|
||||||
AdwApplication parent; |
|
||||||
|
|
||||||
MainWindow* window; |
|
||||||
}; |
|
||||||
|
|
||||||
G_DEFINE_TYPE(GinputApplication, ginput_application, ADW_TYPE_APPLICATION) |
|
||||||
|
|
||||||
/*
|
|
||||||
* Special 'activate' trigger of the application, called when the application is launched |
|
||||||
* This shows the main window |
|
||||||
*/ |
|
||||||
static void |
|
||||||
ginput_application_activate(GApplication* application) |
|
||||||
{ |
|
||||||
GinputApplication* self = GINPUT_APPLICATION(application); |
|
||||||
gtk_window_present(GTK_WINDOW(self->window)); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
ginput_application_startup(GApplication* application) |
|
||||||
{ |
|
||||||
GinputApplication* self = GINPUT_APPLICATION(application); |
|
||||||
|
|
||||||
G_APPLICATION_CLASS(ginput_application_parent_class)->startup(application); |
|
||||||
|
|
||||||
self->window = main_window_new(ADW_APPLICATION(application)); |
|
||||||
|
|
||||||
GtkCssProvider* provider = gtk_css_provider_new(); |
|
||||||
gtk_css_provider_load_from_resource(provider, "/v/ginput/style.css"); |
|
||||||
gtk_style_context_add_provider_for_display(gdk_display_get_default(), |
|
||||||
GTK_STYLE_PROVIDER(provider), |
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
ginput_application_finalize(GObject* object) |
|
||||||
{ |
|
||||||
G_OBJECT_CLASS(ginput_application_parent_class)->finalize(object); |
|
||||||
} |
|
||||||
|
|
||||||
static GObject* |
|
||||||
ginput_application_constructor(GType type, guint n_construct_params, GObjectConstructParam* construct_params) |
|
||||||
{ |
|
||||||
static GObject* self = NULL; |
|
||||||
|
|
||||||
if(self == NULL) |
|
||||||
{ |
|
||||||
self = G_OBJECT_CLASS(ginput_application_parent_class)->constructor(type, n_construct_params, construct_params); |
|
||||||
g_object_add_weak_pointer(self, (gpointer) &self); |
|
||||||
return self; |
|
||||||
} |
|
||||||
|
|
||||||
return g_object_ref(self); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
ginput_application_class_init(GinputApplicationClass* klass) |
|
||||||
{ |
|
||||||
GObjectClass* object_class = G_OBJECT_CLASS(klass); |
|
||||||
GApplicationClass* application_class = G_APPLICATION_CLASS(klass); |
|
||||||
|
|
||||||
object_class->finalize = ginput_application_finalize; |
|
||||||
object_class->constructor = ginput_application_constructor; |
|
||||||
application_class->activate = ginput_application_activate; |
|
||||||
application_class->startup = ginput_application_startup; |
|
||||||
// application_class->command_line = ginput_application_command_line;
|
|
||||||
// application_class->handle_local_options = ginput_application_handle_local_options;
|
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
ginput_application_init(GinputApplication* self) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
AdwApplication* |
|
||||||
ginput_application_new(void) |
|
||||||
{ |
|
||||||
return g_object_new(ginput_application_get_type(), |
|
||||||
"application-id", "v.ginput", |
|
||||||
"flags", G_APPLICATION_DEFAULT_FLAGS, |
|
||||||
NULL); |
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include <adwaita.h> |
|
||||||
|
|
||||||
G_BEGIN_DECLS |
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(GinputApplication, ginput_application, GINPUT, APPLICATION, AdwApplication) |
|
||||||
|
|
||||||
AdwApplication* ginput_application_new(void); |
|
||||||
|
|
||||||
G_END_DECLS |
|
@ -1,315 +0,0 @@ |
|||||||
#define G_LOG_DOMAIN "main-window" |
|
||||||
|
|
||||||
#include "main-window.h" |
|
||||||
#include "panels/empty-panel.h" |
|
||||||
#include "panels/mouse-panel.h" |
|
||||||
#include "device/device.h" |
|
||||||
|
|
||||||
#include <gtk/gtk.h> |
|
||||||
|
|
||||||
struct _MainWindow |
|
||||||
{ |
|
||||||
AdwApplicationWindow parent; |
|
||||||
|
|
||||||
AdwHeaderBar* header; |
|
||||||
AdwLeaflet* main_leaflet; |
|
||||||
GtkListBox *device_list; |
|
||||||
GtkBox* sidebar_box; |
|
||||||
AdwWindowTitle* sidebar_title_widget; |
|
||||||
GtkStack* stack; |
|
||||||
|
|
||||||
GtkWidget* current_panel; |
|
||||||
char* current_panel_id; |
|
||||||
|
|
||||||
GtkWidget* custom_titlebar; |
|
||||||
|
|
||||||
// CcShellModel *store;
|
|
||||||
|
|
||||||
Panel *active_panel; |
|
||||||
GSettings* settings; |
|
||||||
|
|
||||||
gboolean folded; |
|
||||||
|
|
||||||
// CcPanelListView previous_list_view;
|
|
||||||
}; |
|
||||||
|
|
||||||
G_DEFINE_TYPE(MainWindow, main_window, ADW_TYPE_APPLICATION_WINDOW) |
|
||||||
enum |
|
||||||
{ |
|
||||||
PROP_0, |
|
||||||
PROP_ACTIVE_PANEL, |
|
||||||
PROP_MODEL, |
|
||||||
PROP_FOLDED, |
|
||||||
}; |
|
||||||
|
|
||||||
static gboolean activate_panel(MainWindow* self, Panel* panel, const gchar* id) |
|
||||||
{ |
|
||||||
self->current_panel = GTK_WIDGET(panel); |
|
||||||
self->active_panel = panel; |
|
||||||
gtk_stack_add_named(self->stack, self->current_panel, id); |
|
||||||
gtk_stack_set_visible_child_name (self->stack, id); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GtkWidget |
|
||||||
*/ |
|
||||||
static void |
|
||||||
main_window_map(GtkWidget* widget) |
|
||||||
{ |
|
||||||
// MainWindow* self = (MainWindow*) widget;
|
|
||||||
GTK_WIDGET_CLASS(main_window_parent_class)->map(widget); |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GtkWidget |
|
||||||
*/ |
|
||||||
static void |
|
||||||
main_window_unmap(GtkWidget* widget) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(widget); |
|
||||||
gboolean maximized; |
|
||||||
gint height; |
|
||||||
gint width; |
|
||||||
|
|
||||||
maximized = gtk_window_is_maximized(GTK_WINDOW(self)); |
|
||||||
gtk_window_get_default_size(GTK_WINDOW(self), &width, &height); |
|
||||||
|
|
||||||
g_settings_set(self->settings, |
|
||||||
"window-state", |
|
||||||
"(iib)", |
|
||||||
width, |
|
||||||
height, |
|
||||||
maximized); |
|
||||||
|
|
||||||
GTK_WIDGET_CLASS(main_window_parent_class)->unmap(widget); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_get_property(GObject* object, guint property_id, GValue* value, GParamSpec* pspec) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(object); |
|
||||||
|
|
||||||
switch(property_id) |
|
||||||
{ |
|
||||||
case PROP_ACTIVE_PANEL: |
|
||||||
g_value_set_object (value, self->active_panel); |
|
||||||
break; |
|
||||||
|
|
||||||
// case PROP_MODEL:
|
|
||||||
// g_value_set_object (value, self->store);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case PROP_FOLDED: |
|
||||||
g_value_set_boolean(value, self->folded); |
|
||||||
break; |
|
||||||
|
|
||||||
default: |
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_set_property(GObject* object, |
|
||||||
guint property_id, |
|
||||||
const GValue* value, |
|
||||||
GParamSpec* pspec) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(object); |
|
||||||
|
|
||||||
switch(property_id) |
|
||||||
{ |
|
||||||
// case PROP_ACTIVE_PANEL:
|
|
||||||
// set_active_panel(self, g_value_get_object(value));
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case PROP_MODEL:
|
|
||||||
// g_assert(self->store == NULL);
|
|
||||||
// self->store = g_value_dup_object(value);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case PROP_FOLDED: |
|
||||||
self->folded = g_value_get_boolean(value); |
|
||||||
break; |
|
||||||
|
|
||||||
default: |
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
load_window_state(MainWindow* self) |
|
||||||
{ |
|
||||||
gint current_width = -1; |
|
||||||
gint current_height = -1; |
|
||||||
gboolean maximized = FALSE; |
|
||||||
|
|
||||||
g_settings_get(self->settings, |
|
||||||
"window-state", |
|
||||||
"(iib)", |
|
||||||
¤t_width, |
|
||||||
¤t_height, |
|
||||||
&maximized); |
|
||||||
|
|
||||||
if(current_width != -1 && current_height != -1) |
|
||||||
gtk_window_set_default_size(GTK_WINDOW(self), current_width, current_height); |
|
||||||
if(maximized) |
|
||||||
gtk_window_maximize(GTK_WINDOW(self)); |
|
||||||
} |
|
||||||
|
|
||||||
void main_window_add_all_devices(MainWindow* self) |
|
||||||
{ |
|
||||||
// Obtain devices, and iterate over the array to add them
|
|
||||||
array_t* devices = device_get_array(); |
|
||||||
for(size_t i = 0; i < array_count(devices); i++) |
|
||||||
main_window_add_device_to_list(self, array_get(devices, i)); |
|
||||||
} |
|
||||||
|
|
||||||
void main_window_device_selected(GtkListBox* self, GtkListBoxRow* row, gpointer user_data) |
|
||||||
{ |
|
||||||
MainWindow* main_window = (MainWindow*) gtk_widget_get_root(GTK_WIDGET(self)); |
|
||||||
|
|
||||||
// Selection cleared
|
|
||||||
if(!row) |
|
||||||
{ |
|
||||||
// TODO: set to empty panel ?
|
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
device_t* device = (device_t*) g_object_get_data(G_OBJECT(row), "ginput_device"); |
|
||||||
MousePanel* mp = (MousePanel*) mouse_panel_new(); |
|
||||||
mouse_panel_set_device(mp, device); |
|
||||||
|
|
||||||
// TODO : change and use already added child if possible
|
|
||||||
activate_panel(main_window, GINPUT_PANEL(mp), device_get_name(device)); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_constructed(GObject* object) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(object); |
|
||||||
|
|
||||||
load_window_state(self); |
|
||||||
|
|
||||||
main_window_add_all_devices(self); |
|
||||||
|
|
||||||
/* Add the panels */ |
|
||||||
// setup_model (self);
|
|
||||||
|
|
||||||
/* After everything is loaded, select the last used panel, if any,
|
|
||||||
* or the first visible panel. We do that in an idle handler so we |
|
||||||
* have a chance to skip it when another panel has been explicitly |
|
||||||
* activated from commandline parameter or from DBus method */ |
|
||||||
// g_idle_add_once ((GSourceOnceFunc) maybe_load_last_panel, self);
|
|
||||||
|
|
||||||
// g_signal_connect_swapped (self->panel_list,
|
|
||||||
// "notify::view",
|
|
||||||
// G_CALLBACK (update_headerbar_buttons),
|
|
||||||
// self);
|
|
||||||
|
|
||||||
// update_headerbar_buttons (self);
|
|
||||||
// adw_leaflet_set_visible_child (self->main_leaflet,
|
|
||||||
// GTK_WIDGET (self->sidebar_box));
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(main_window_parent_class)->constructed(object); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_dispose(GObject* object) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(object); |
|
||||||
|
|
||||||
g_clear_pointer(&self->current_panel_id, g_free); |
|
||||||
// g_clear_object (&self->store);
|
|
||||||
// g_clear_object (&self->active_panel);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(main_window_parent_class)->dispose(object); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_finalize(GObject* object) |
|
||||||
{ |
|
||||||
MainWindow* self = GINPUT_MAIN_WINDOW(object); |
|
||||||
|
|
||||||
g_clear_object(&self->settings); |
|
||||||
|
|
||||||
G_OBJECT_CLASS(main_window_parent_class)->finalize(object); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_class_init(MainWindowClass* klass) |
|
||||||
{ |
|
||||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); |
|
||||||
GObjectClass* object_class = G_OBJECT_CLASS(klass); |
|
||||||
|
|
||||||
object_class->get_property = main_window_get_property; |
|
||||||
object_class->set_property = main_window_set_property; |
|
||||||
object_class->constructed = main_window_constructed; |
|
||||||
object_class->dispose = main_window_dispose; |
|
||||||
object_class->finalize = main_window_finalize; |
|
||||||
|
|
||||||
widget_class->map = main_window_map; |
|
||||||
widget_class->unmap = main_window_unmap; |
|
||||||
|
|
||||||
g_object_class_install_property(object_class, PROP_FOLDED, |
|
||||||
g_param_spec_boolean("folded", "Folded", "Whether the window is foled", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource(widget_class, "/v/ginput/main-window.ui"); |
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, header); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, main_leaflet); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, device_list); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, sidebar_box); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, sidebar_title_widget); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MainWindow, stack); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
main_window_init(MainWindow* self) |
|
||||||
{ |
|
||||||
gtk_widget_init_template(GTK_WIDGET(self)); |
|
||||||
|
|
||||||
self->settings = g_settings_new("v.ginput"); |
|
||||||
|
|
||||||
g_object_bind_property(self->main_leaflet, |
|
||||||
"folded", |
|
||||||
self, |
|
||||||
"folded", |
|
||||||
G_BINDING_SYNC_CREATE); |
|
||||||
|
|
||||||
activate_panel(self, empty_panel_new(), "empty"); |
|
||||||
|
|
||||||
g_signal_connect(self->device_list, "row_selected", G_CALLBACK(main_window_device_selected), NULL); |
|
||||||
} |
|
||||||
|
|
||||||
// TODO use translation
|
|
||||||
#define _(x) x |
|
||||||
|
|
||||||
MainWindow* |
|
||||||
main_window_new(AdwApplication* application) |
|
||||||
{ |
|
||||||
g_return_val_if_fail(GTK_IS_APPLICATION(application), NULL); |
|
||||||
|
|
||||||
return g_object_new(main_window_get_type(), |
|
||||||
"application", application, |
|
||||||
"resizable", TRUE, |
|
||||||
"title", _("Input devices"), |
|
||||||
"icon-name", "input-devices", |
|
||||||
"show-menubar", FALSE, |
|
||||||
NULL); |
|
||||||
} |
|
||||||
|
|
||||||
void main_window_add_device_to_list(MainWindow* self, device_t* device) |
|
||||||
{ |
|
||||||
// Setup row
|
|
||||||
GtkListBoxRow* row = (GtkListBoxRow*) gtk_list_box_row_new(); |
|
||||||
GtkLabel* label = (GtkLabel*) gtk_label_new(device_get_name(device)); |
|
||||||
gtk_widget_add_css_class(GTK_WIDGET(label), "body"); |
|
||||||
gtk_widget_set_margin_top(GTK_WIDGET(label), 7); |
|
||||||
gtk_widget_set_margin_bottom(GTK_WIDGET(label), 7); |
|
||||||
gtk_list_box_row_set_child(row, GTK_WIDGET(label)); |
|
||||||
g_object_set_data(G_OBJECT(row), "ginput_device", device); |
|
||||||
|
|
||||||
// Add row to listbox
|
|
||||||
gtk_list_box_append(GTK_LIST_BOX(self->device_list), GTK_WIDGET(row)); |
|
||||||
} |
|
@ -1,14 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include <adwaita.h> |
|
||||||
#include "device/device.h" |
|
||||||
|
|
||||||
G_BEGIN_DECLS |
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(MainWindow, main_window, GINPUT, MAIN_WINDOW, AdwApplicationWindow) |
|
||||||
|
|
||||||
MainWindow* main_window_new(AdwApplication* application); |
|
||||||
|
|
||||||
void main_window_add_device_to_list(MainWindow* self, device_t* device); |
|
||||||
|
|
||||||
G_END_DECLS |
|
@ -1,206 +0,0 @@ |
|||||||
#include "panel.h" |
|
||||||
|
|
||||||
/*
|
|
||||||
* Abstract class representing a panel |
|
||||||
*/ |
|
||||||
|
|
||||||
typedef struct |
|
||||||
{ |
|
||||||
AdwBin* content_bin; |
|
||||||
GtkBox* main_box; |
|
||||||
AdwBin* titlebar_bin; |
|
||||||
AdwHeaderBar* titlebar; |
|
||||||
|
|
||||||
GCancellable* cancellable; |
|
||||||
gboolean folded; |
|
||||||
gchar* title; |
|
||||||
} PanelPrivate; |
|
||||||
|
|
||||||
static void panel_buildable_init(GtkBuildableIface* iface); |
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE(Panel, panel, ADW_TYPE_BIN, |
|
||||||
G_ADD_PRIVATE(Panel) |
|
||||||
G_IMPLEMENT_INTERFACE(GTK_TYPE_BUILDABLE, panel_buildable_init)) |
|
||||||
|
|
||||||
static GtkBuildableIface* parent_buildable_iface; |
|
||||||
|
|
||||||
enum |
|
||||||
{ |
|
||||||
PROP_0, |
|
||||||
PROP_PARAMETERS, |
|
||||||
PROP_FOLDED, |
|
||||||
PROP_TITLE, |
|
||||||
N_PROPS |
|
||||||
}; |
|
||||||
|
|
||||||
static GParamSpec* properties[N_PROPS]; |
|
||||||
|
|
||||||
static void |
|
||||||
panel_buildable_add_child(GtkBuildable* buildable, GtkBuilder* builder, GObject* child, const char* type) |
|
||||||
{ |
|
||||||
PanelPrivate* priv = panel_get_instance_private(GINPUT_PANEL(buildable)); |
|
||||||
|
|
||||||
if(GTK_IS_WIDGET(child) && !priv->main_box) |
|
||||||
{ |
|
||||||
adw_bin_set_child(ADW_BIN(buildable), GTK_WIDGET(child)); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if(g_strcmp0(type, "content") == 0) |
|
||||||
adw_bin_set_child(priv->content_bin, GTK_WIDGET(child)); |
|
||||||
else if(g_strcmp0(type, "titlebar-start") == 0) |
|
||||||
adw_header_bar_pack_start(priv->titlebar, GTK_WIDGET(child)); |
|
||||||
else if(g_strcmp0(type, "titlebar-end") == 0) |
|
||||||
adw_header_bar_pack_end(priv->titlebar, GTK_WIDGET(child)); |
|
||||||
else if(g_strcmp0(type, "titlebar") == 0) |
|
||||||
adw_bin_set_child(priv->titlebar_bin, GTK_WIDGET(child)); |
|
||||||
else |
|
||||||
parent_buildable_iface->add_child(buildable, builder, child, type); |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GtkBuildableIface |
|
||||||
*/ |
|
||||||
static void |
|
||||||
panel_buildable_init(GtkBuildableIface* iface) |
|
||||||
{ |
|
||||||
parent_buildable_iface = g_type_interface_peek_parent(iface); |
|
||||||
iface->add_child = panel_buildable_add_child; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GObject |
|
||||||
*/ |
|
||||||
static void |
|
||||||
panel_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) |
|
||||||
{ |
|
||||||
PanelPrivate* priv = panel_get_instance_private(GINPUT_PANEL(object)); |
|
||||||
|
|
||||||
switch(prop_id) |
|
||||||
{ |
|
||||||
case PROP_PARAMETERS: |
|
||||||
{ |
|
||||||
g_autoptr(GVariant) v = NULL; |
|
||||||
GVariant* parameters; |
|
||||||
gsize n_parameters; |
|
||||||
|
|
||||||
parameters = g_value_get_variant(value); |
|
||||||
|
|
||||||
if(parameters == NULL) |
|
||||||
return; |
|
||||||
|
|
||||||
n_parameters = g_variant_n_children(parameters); |
|
||||||
if(n_parameters == 0) |
|
||||||
return; |
|
||||||
|
|
||||||
g_variant_get_child(parameters, 0, "v", &v); |
|
||||||
|
|
||||||
if(!g_variant_is_of_type(v, G_VARIANT_TYPE_DICTIONARY)) |
|
||||||
g_warning("Wrong type for the first argument GVariant, expected 'a{sv}' but got '%s'", |
|
||||||
(gchar*) g_variant_get_type(v)); |
|
||||||
else if(g_variant_n_children(v) > 0) |
|
||||||
g_warning("Ignoring additional flags"); |
|
||||||
|
|
||||||
if(n_parameters > 1) |
|
||||||
g_warning("Ignoring additional parameters"); |
|
||||||
|
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
case PROP_TITLE: |
|
||||||
priv->title = g_value_dup_string(value); |
|
||||||
break; |
|
||||||
|
|
||||||
case PROP_FOLDED: |
|
||||||
default: |
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GObject |
|
||||||
*/ |
|
||||||
static void |
|
||||||
panel_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) |
|
||||||
{ |
|
||||||
PanelPrivate* priv = panel_get_instance_private(GINPUT_PANEL(object)); |
|
||||||
|
|
||||||
switch(prop_id) |
|
||||||
{ |
|
||||||
case PROP_FOLDED: |
|
||||||
g_value_set_boolean(value, priv->folded); |
|
||||||
break; |
|
||||||
|
|
||||||
case PROP_TITLE: |
|
||||||
g_value_set_string(value, priv->title); |
|
||||||
break; |
|
||||||
|
|
||||||
default: |
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* @Override from GObject |
|
||||||
*/ |
|
||||||
static void |
|
||||||
panel_finalize(GObject* object) |
|
||||||
{ |
|
||||||
PanelPrivate* priv = panel_get_instance_private(GINPUT_PANEL(object)); |
|
||||||
|
|
||||||
g_cancellable_cancel(priv->cancellable); |
|
||||||
g_clear_object(&priv->cancellable); |
|
||||||
|
|
||||||
g_clear_pointer(&priv->title, g_free); |
|
||||||
|
|
||||||
G_OBJECT_CLASS(panel_parent_class)->finalize(object); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
panel_class_init(PanelClass* klass) |
|
||||||
{ |
|
||||||
GObjectClass* object_class = G_OBJECT_CLASS(klass); |
|
||||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); |
|
||||||
|
|
||||||
object_class->get_property = panel_get_property; |
|
||||||
object_class->set_property = panel_set_property; |
|
||||||
object_class->finalize = panel_finalize; |
|
||||||
|
|
||||||
// signals[SIDEBAR_ACTIVATED] = g_signal_new ("sidebar-activated",
|
|
||||||
// G_TYPE_FROM_CLASS (object_class),
|
|
||||||
// G_SIGNAL_RUN_LAST,
|
|
||||||
// 0, NULL, NULL,
|
|
||||||
// g_cclosure_marshal_VOID__VOID,
|
|
||||||
// G_TYPE_NONE, 0);
|
|
||||||
|
|
||||||
properties[PROP_FOLDED] = g_param_spec_boolean("folded", NULL, NULL, |
|
||||||
FALSE, |
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); |
|
||||||
|
|
||||||
properties[PROP_PARAMETERS] = g_param_spec_variant("parameters", |
|
||||||
"Structured parameters", |
|
||||||
"Additional parameters passed externally (ie. command line, D-Bus activation)", |
|
||||||
G_VARIANT_TYPE("av"), |
|
||||||
NULL, |
|
||||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS); |
|
||||||
|
|
||||||
properties[PROP_TITLE] = g_param_spec_string("title", NULL, NULL, NULL, |
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); |
|
||||||
|
|
||||||
g_object_class_install_properties(object_class, N_PROPS, properties); |
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource(widget_class, "/v/ginput/panel.ui"); |
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child_private(widget_class, Panel, content_bin); |
|
||||||
gtk_widget_class_bind_template_child_private(widget_class, Panel, main_box); |
|
||||||
gtk_widget_class_bind_template_child_private(widget_class, Panel, titlebar_bin); |
|
||||||
gtk_widget_class_bind_template_child_private(widget_class, Panel, titlebar); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
panel_init(Panel* panel) |
|
||||||
{ |
|
||||||
gtk_widget_init_template(GTK_WIDGET(panel)); |
|
||||||
} |
|
@ -1,44 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include <adwaita.h> |
|
||||||
|
|
||||||
G_DECLARE_DERIVABLE_TYPE(Panel, panel, GINPUT, PANEL, AdwBin) |
|
||||||
|
|
||||||
G_BEGIN_DECLS |
|
||||||
|
|
||||||
/**
|
|
||||||
* PanelClass: |
|
||||||
* |
|
||||||
* The contents of this struct are private and should not be accessed directly. |
|
||||||
*/ |
|
||||||
struct _PanelClass |
|
||||||
{ |
|
||||||
/*< private >*/ |
|
||||||
AdwBinClass parent_class; |
|
||||||
|
|
||||||
const gchar* (*get_help_uri)(Panel* panel); |
|
||||||
|
|
||||||
GtkWidget* (*get_sidebar_widget)(Panel* panel); |
|
||||||
}; |
|
||||||
|
|
||||||
GPermission* panel_get_permission(Panel* panel); |
|
||||||
|
|
||||||
const gchar* panel_get_help_uri(Panel* panel); |
|
||||||
|
|
||||||
GtkWidget* panel_get_sidebar_widget(Panel* panel); |
|
||||||
|
|
||||||
GCancellable* panel_get_cancellable(Panel* panel); |
|
||||||
|
|
||||||
gboolean panel_get_folded(Panel* panel); |
|
||||||
|
|
||||||
GtkWidget* panel_get_content(Panel* panel); |
|
||||||
|
|
||||||
void panel_set_content(Panel* panel, GtkWidget* content); |
|
||||||
|
|
||||||
GtkWidget* panel_get_titlebar(Panel* panel); |
|
||||||
|
|
||||||
void panel_set_titlebar(Panel* panel, GtkWidget* titlebar); |
|
||||||
|
|
||||||
void panel_deactivate(Panel* panel); |
|
||||||
|
|
||||||
G_END_DECLS |
|
@ -0,0 +1,8 @@ |
|||||||
|
[GtkTemplate (ui="/v/ginput/panel-empty.ui")] |
||||||
|
public class EmptyPanel : Panel |
||||||
|
{ |
||||||
|
public EmptyPanel() |
||||||
|
{ |
||||||
|
base(""); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,122 @@ |
|||||||
|
using Device; |
||||||
|
|
||||||
|
[GtkTemplate (ui="/v/ginput/panel-mouse.ui")] |
||||||
|
public class MousePanel : Panel |
||||||
|
{ |
||||||
|
// Mouse presentation |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.Image mouse_image; |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.Label mouse_manufacturer; |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.Label mouse_name; |
||||||
|
|
||||||
|
// Wireless informations |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.PreferencesGroup wireless; |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.LevelBar battery_level; |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.Label battery_level_label; |
||||||
|
[GtkChild] |
||||||
|
private unowned Gtk.Label charging_state; |
||||||
|
|
||||||
|
// DPI |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.PreferencesGroup dpi_preference_group; |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.ButtonContent dpi_stage_add_button; |
||||||
|
|
||||||
|
// Features |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.SwitchRow motion_sync_switchrow; |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.SwitchRow angle_snap_switchrow; |
||||||
|
|
||||||
|
// Polling rate |
||||||
|
[GtkChild] |
||||||
|
private unowned Adw.ComboRow polling_rate_comborow; |
||||||
|
|
||||||
|
private void* device; |
||||||
|
|
||||||
|
public MousePanel(string name, void* device) |
||||||
|
{ |
||||||
|
base(name); |
||||||
|
this.device = device; |
||||||
|
|
||||||
|
refresh_device(); |
||||||
|
} |
||||||
|
|
||||||
|
public void refresh_device() |
||||||
|
{ |
||||||
|
// Obtain and fill basic information |
||||||
|
mouse_image.set_from_file(Device.get_image(this.device)); |
||||||
|
mouse_name.set_label(name); |
||||||
|
mouse_manufacturer.set_label(Device.get_manufacturer(this.device)); |
||||||
|
|
||||||
|
// Obtain mouse information |
||||||
|
Mouse mouse = Mouse(); |
||||||
|
Device.mouse_get(this.device, &mouse); |
||||||
|
|
||||||
|
/* Fill information */ |
||||||
|
|
||||||
|
// DPI stages |
||||||
|
string dpi_used_max = "%u/%u".printf(mouse.level_count, mouse.max_level_count); |
||||||
|
dpi_stage_add_button.set_label(dpi_used_max); |
||||||
|
|
||||||
|
// All dpi levels |
||||||
|
Gtk.CheckButton? group = null; |
||||||
|
for(size_t i = 0; i < mouse.level_count; i++) |
||||||
|
{ |
||||||
|
Adw.ActionRow row = new Adw.ActionRow(); |
||||||
|
|
||||||
|
// Add radiobutton |
||||||
|
if(mouse.level_count > 1) |
||||||
|
{ |
||||||
|
Gtk.CheckButton radio_button = new Gtk.CheckButton(); |
||||||
|
if(group == null) group = radio_button; |
||||||
|
else radio_button.set_group(group); |
||||||
|
|
||||||
|
if(mouse.level_current == i) |
||||||
|
radio_button.set_active(true); |
||||||
|
|
||||||
|
row.add_prefix(radio_button); |
||||||
|
} |
||||||
|
|
||||||
|
row.set_title("%u DPI".printf(mouse.dpi_x[i])); |
||||||
|
|
||||||
|
dpi_preference_group.add(row); |
||||||
|
} |
||||||
|
|
||||||
|
// Features |
||||||
|
motion_sync_switchrow.set_active(mouse.motion_sync); |
||||||
|
angle_snap_switchrow.set_active(mouse.angle_snap); |
||||||
|
|
||||||
|
// Polling rate |
||||||
|
var model = new Gtk.StringList(null); |
||||||
|
for(size_t i = 0; i < mouse.polling_rate_count; i++) |
||||||
|
{ |
||||||
|
model.append("%u Hz".printf(mouse.polling_rates[i])); |
||||||
|
} |
||||||
|
polling_rate_comborow.set_model(model); |
||||||
|
polling_rate_comborow.set_selected(mouse.polling_rate_current); |
||||||
|
|
||||||
|
// Wireless |
||||||
|
if((Device.get_capacity(this.device) & Device.Capacity.WIRELESS) != 0) |
||||||
|
{ |
||||||
|
Wireless wireless = Wireless(); |
||||||
|
Device.wireless_get(this.device, &wireless); |
||||||
|
|
||||||
|
battery_level.set_value(wireless.battery_level); |
||||||
|
battery_level_label.set_label("%u %%".printf(wireless.battery_level)); |
||||||
|
if(wireless.charging) |
||||||
|
charging_state.set_label("Charging"); |
||||||
|
else |
||||||
|
charging_state.set_label("Not charging"); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
wireless.hide(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,28 +0,0 @@ |
|||||||
#include "empty-panel.h" |
|
||||||
|
|
||||||
struct _EmptyPanel |
|
||||||
{ |
|
||||||
Panel parent_instance; |
|
||||||
}; |
|
||||||
|
|
||||||
G_DEFINE_TYPE (EmptyPanel, empty_panel, panel_get_type()) |
|
||||||
|
|
||||||
static void |
|
||||||
empty_panel_class_init(EmptyPanelClass* klass) |
|
||||||
{ |
|
||||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); |
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource(widget_class, "/v/ginput/panel-empty.ui"); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
empty_panel_init(EmptyPanel* self) |
|
||||||
{ |
|
||||||
gtk_widget_init_template(GTK_WIDGET(self)); |
|
||||||
} |
|
||||||
|
|
||||||
Panel* |
|
||||||
empty_panel_new(void) |
|
||||||
{ |
|
||||||
return g_object_new(empty_panel_get_type(), NULL); |
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include "ui/panel.h" |
|
||||||
|
|
||||||
G_BEGIN_DECLS |
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(EmptyPanel, empty_panel, GINPUT, EMPTY_PANEL, Panel) |
|
||||||
|
|
||||||
G_END_DECLS |
|
||||||
|
|
||||||
Panel* empty_panel_new(void); |
|
@ -1,156 +0,0 @@ |
|||||||
#include "mouse-panel.h" |
|
||||||
|
|
||||||
struct _MousePanel |
|
||||||
{ |
|
||||||
Panel parent_instance; |
|
||||||
|
|
||||||
// Mouse presentation
|
|
||||||
GtkImage* mouse_image; |
|
||||||
GtkLabel* mouse_manufacturer; |
|
||||||
GtkLabel* mouse_name; |
|
||||||
|
|
||||||
// Wireless informations
|
|
||||||
AdwPreferencesGroup* wireless; |
|
||||||
GtkLevelBar* battery_level; |
|
||||||
GtkLabel* battery_level_label; |
|
||||||
GtkLabel* charging_state; |
|
||||||
|
|
||||||
// DPI
|
|
||||||
AdwPreferencesGroup* dpi_preference_group; |
|
||||||
AdwButtonContent* dpi_stage_add_button; |
|
||||||
|
|
||||||
// Features
|
|
||||||
AdwSwitchRow* motion_sync_switchrow; |
|
||||||
AdwSwitchRow* angle_snap_switchrow; |
|
||||||
}; |
|
||||||
|
|
||||||
G_DEFINE_TYPE (MousePanel, mouse_panel, panel_get_type()) |
|
||||||
|
|
||||||
static void |
|
||||||
mouse_panel_class_init(MousePanelClass* klass) |
|
||||||
{ |
|
||||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); |
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource(widget_class, "/v/ginput/panel-mouse.ui"); |
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, mouse_image); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, mouse_manufacturer); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, mouse_name); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, wireless); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, battery_level); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, battery_level_label); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, charging_state); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, dpi_preference_group); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, dpi_stage_add_button); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, motion_sync_switchrow); |
|
||||||
gtk_widget_class_bind_template_child(widget_class, MousePanel, angle_snap_switchrow); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
mouse_panel_init(MousePanel* self) |
|
||||||
{ |
|
||||||
gtk_widget_init_template(GTK_WIDGET(self)); |
|
||||||
} |
|
||||||
|
|
||||||
Panel* |
|
||||||
mouse_panel_new(void) |
|
||||||
{ |
|
||||||
return g_object_new(mouse_panel_get_type(), NULL); |
|
||||||
} |
|
||||||
|
|
||||||
void mouse_panel_set_device(MousePanel* self, device_t* device) |
|
||||||
{ |
|
||||||
// Set device image
|
|
||||||
char* image = device_get_image(device); |
|
||||||
gtk_image_set_from_file(self->mouse_image, image); |
|
||||||
free(image); |
|
||||||
|
|
||||||
// Set device manufacturer
|
|
||||||
char* (*getmanufacturer_fn)(void*) = dlsym(device_driver(device), "driver_get_manufacturer"); |
|
||||||
gtk_label_set_label(self->mouse_manufacturer, getmanufacturer_fn(device_handle(device))); |
|
||||||
|
|
||||||
// Set device name
|
|
||||||
// TODO inner window title
|
|
||||||
char* device_name = device_get_name(device); |
|
||||||
gtk_label_set_label(self->mouse_name, device_name); |
|
||||||
|
|
||||||
// Set mouse wireless status
|
|
||||||
if(device_get_capacity(device) & DEVICE_CAPACITY_WIRELESS) |
|
||||||
{ |
|
||||||
int (*driver_wireless_battery_state_get)(void*, int*, bool*) = dlsym(device_driver(device), "driver_wireless_battery_state_get"); |
|
||||||
int battery_level; |
|
||||||
bool charging; |
|
||||||
int battery_res = driver_wireless_battery_state_get(device_handle(device), &battery_level, &charging); |
|
||||||
|
|
||||||
if(!battery_res) |
|
||||||
{ |
|
||||||
// Set battery level
|
|
||||||
gtk_level_bar_set_value(self->battery_level, (double) battery_level); |
|
||||||
char battery_level_str[10]; |
|
||||||
sprintf(battery_level_str, "%u %%", battery_level); |
|
||||||
gtk_label_set_label(self->battery_level_label, battery_level_str); |
|
||||||
|
|
||||||
// Set battery status
|
|
||||||
if(charging) |
|
||||||
gtk_label_set_label(self->charging_state, "Charging"); |
|
||||||
else |
|
||||||
gtk_label_set_label(self->charging_state, "Not charging"); |
|
||||||
} |
|
||||||
} |
|
||||||
else gtk_widget_set_visible(GTK_WIDGET(self->wireless), false); |
|
||||||
|
|
||||||
// Set mouse dpi
|
|
||||||
struct MOUSE_DPI_LEVELS dpi; |
|
||||||
int (*driver_mouse_dpi_get)(void*, void*) = dlsym(device_driver(device), "driver_mouse_dpi_get"); |
|
||||||
int dpi_res = driver_mouse_dpi_get(device_handle(device), &dpi); |
|
||||||
if(!dpi_res) |
|
||||||
{ |
|
||||||
// Set dpi used/max label in add button
|
|
||||||
char dpi_used_max[10]; |
|
||||||
sprintf(dpi_used_max, "%u/%u", dpi.level_count, dpi.max_level_count); |
|
||||||
adw_button_content_set_label(self->dpi_stage_add_button, dpi_used_max); |
|
||||||
|
|
||||||
GtkCheckButton* group = 0; |
|
||||||
// Set dpi list
|
|
||||||
for(size_t i = 0; i < dpi.level_count; i++) |
|
||||||
{ |
|
||||||
AdwActionRow* row = ADW_ACTION_ROW(adw_action_row_new()); |
|
||||||
|
|
||||||
// Add radiobutton
|
|
||||||
if(dpi.level_count > 1) |
|
||||||
{ |
|
||||||
GtkCheckButton* radio_button = GTK_CHECK_BUTTON(gtk_check_button_new()); |
|
||||||
if(!group) group = radio_button; |
|
||||||
else gtk_check_button_set_group(radio_button, group); |
|
||||||
|
|
||||||
if(dpi.level_current == i) |
|
||||||
gtk_check_button_set_active(radio_button, true); |
|
||||||
|
|
||||||
adw_action_row_add_prefix(row, GTK_WIDGET(radio_button)); |
|
||||||
} |
|
||||||
|
|
||||||
// Convert dpi int to string, and set it as title
|
|
||||||
char dpi_str[15]; |
|
||||||
sprintf(dpi_str, "%u DPI", dpi.level[i].dpi_x); |
|
||||||
adw_preferences_row_set_title(ADW_PREFERENCES_ROW(row), dpi_str); |
|
||||||
|
|
||||||
//gtk_list_box_row_set_activatable(GTK_LIST_BOX_ROW(row), false);
|
|
||||||
|
|
||||||
adw_preferences_group_add(self->dpi_preference_group, GTK_WIDGET(row)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Set mouse 'motion sync' feature
|
|
||||||
bool motion_sync = false; |
|
||||||
int (*driver_mouse_motion_sync_get)(void*, bool*) = dlsym(device_driver(device), "driver_mouse_motion_sync_get"); |
|
||||||
int motionsync_res = driver_mouse_motion_sync_get(device_handle(device), &motion_sync); |
|
||||||
if(!motionsync_res) |
|
||||||
adw_switch_row_set_active(self->motion_sync_switchrow, motion_sync); |
|
||||||
|
|
||||||
// Set mouse 'angle snap' feature
|
|
||||||
bool angle_snap = false; |
|
||||||
int (*driver_mouse_angle_snap_get)(void*, bool*) = dlsym(device_driver(device), "driver_mouse_angle_snap_get"); |
|
||||||
int anglesnap_res = driver_mouse_angle_snap_get(device_handle(device), &angle_snap); |
|
||||||
if(!anglesnap_res) |
|
||||||
adw_switch_row_set_active(self->angle_snap_switchrow, angle_snap); |
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include "ui/panel.h" |
|
||||||
#include "device/device.h" |
|
||||||
|
|
||||||
G_BEGIN_DECLS |
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(MousePanel, mouse_panel, GINPUT, MOUSE_PANEL, Panel) |
|
||||||
|
|
||||||
G_END_DECLS |
|
||||||
|
|
||||||
Panel* mouse_panel_new(void); |
|
||||||
|
|
||||||
void mouse_panel_set_device(MousePanel* self, device_t* device); |
|
||||||
|
|
Loading…
Reference in new issue