Add gui binary

This commit is contained in:
Melon 2021-04-24 11:19:26 +01:00
parent 9ed779b8ae
commit 9b4e4f7b64
2 changed files with 223 additions and 0 deletions

134
src/impl/gui/main.c Normal file
View File

@ -0,0 +1,134 @@
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libappindicator/app-indicator.h>
#include "states.h"
#include "statusicon.h"
#include "magic_code.h"
GtkApplication *app;
GdkPixbuf *appicon;
char *statusiconoff;
char *statusiconon;
States currentstate;
void update_state(States state) {
currentstate = state;
if(currentstate == CONNECTED) {
status_icon_set_state(APP_INDICATOR_STATUS_ATTENTION);
} else if(currentstate == DISCONNECTED) {
status_icon_set_state(APP_INDICATOR_STATUS_PASSIVE);
} else {
status_icon_set_state(APP_INDICATOR_STATUS_ACTIVE);
}
}
void open_about(GtkApplication* app) {
GtkWidget *about = gtk_about_dialog_new();
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),"Melon VPN");
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),"v1.0.0");
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),"Copyright OnPointCoding");
gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(about),GTK_LICENSE_UNKNOWN);
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),"https://software.onpointcoding.net");
gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),"OnPointCoding.net");
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),appicon);
const char *authors[2] = {"MrMelon54",NULL};
gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),authors);
const char *artists[2] = {"MrMelon54",NULL};
gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about),artists);
gtk_widget_show_all(about);
}
void open_paint_btn(GtkButton *button) {
update_state((currentstate + 1) % 3);
}
void open_about_btn(GtkButton *button) {
open_about(app);
}
void activate(GtkApplication* app) {
GtkWidget *window;
GtkWidget *box;
GtkWidget *button;
GtkWidget *button2;
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window),"Melon VPN");
gtk_window_set_default_size(GTK_WINDOW(window),400,400);
// Setup status icon now window is available
status_icon_create(window,statusiconoff,statusiconon);
status_icon_set_state(APP_INDICATOR_STATUS_PASSIVE);
gtk_container_set_border_width(GTK_CONTAINER(window),8);
button = gtk_button_new_with_label("Start");
g_signal_connect(button,"clicked",G_CALLBACK(open_paint_btn),NULL);
button2 = gtk_button_new_with_label("About");
g_signal_connect(button2,"clicked",G_CALLBACK(open_about_btn),NULL);
box = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window),box);
gtk_fixed_put(GTK_FIXED(box),button,5,5);
gtk_fixed_put(GTK_FIXED(box),button2,100,60);
gtk_widget_show_all(window);
}
void get_magic_code(int *a, int *b) {
*a = MAGIC_CODE_A;
*b = MAGIC_CODE_B;
}
int run_gui(int argc, char **argv) {
int status;
statusiconoff = "";
statusiconon = "";
if(access("melonvpn.png",R_OK) == 0) {
appicon = gdk_pixbuf_new_from_file("melonvpn.png",NULL);
} else if(access("/usr/lib/melonvpn/melonvpn.png",R_OK) == 0) {
appicon = gdk_pixbuf_new_from_file("/usr/lib/melonvpn/melonvpn.png",NULL);
}
if(access("/usr/lib/melonvpn/statusmelonoff.png",R_OK) == 0) {
statusiconoff = "/usr/lib/melonvpn/statusmelonoff.png";
} else {
fprintf(stderr,"WARN: Unable to find statusmelonoff.png\n");
}
if(access("/usr/lib/melonvpn/statusmelonon.png",R_OK) == 0) {
statusiconon = "/usr/lib/melonvpn/statusmelonon.png";
} else {
fprintf(stderr,"WARN: Unable to find statusmelonon.png\n");
}
if(appicon == NULL) {
fprintf(stderr,"ERROR: Failed to load program logo\n");
return 1;
}
if(statusiconoff == NULL) {
fprintf(stderr,"ERROR: Failed to load status off icon\n");
return 1;
}
if(statusiconon == NULL) {
fprintf(stderr,"ERROR: Failed to load status on icon\n");
return 1;
}
currentstate = DISCONNECTED;
app = gtk_application_new("net.onpointcoding.melonvpn",G_APPLICATION_FLAGS_NONE);
g_signal_connect(app,"activate",G_CALLBACK(activate),NULL);
status = g_application_run(G_APPLICATION(app),argc,argv);
g_object_unref(app);
return status;
}

89
src/impl/gui/statusicon.c Normal file
View File

@ -0,0 +1,89 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libappindicator/app-indicator.h>
#include "states.h"
#include "statusicon.h"
GtkWidget *mainwindow;
AppIndicator *indicator;
States status_icon_currentstate;
static void activate_action (GtkAction *action);
static GtkActionEntry entries[] = {
{"FileMenu",NULL,"_File"},
{"New","document-new","_New","<control>N","Create a new file",G_CALLBACK(activate_action)},
{"Open","document-open","_Open","<control>O","Open a file",G_CALLBACK(activate_action)},
{"Save","document-save","_Save","<control>S","Save file",G_CALLBACK(activate_action)},
{"Close","window-close","_Close","<control>W","Close the window",G_CALLBACK(activate_action)},
{"Quit","application-exit","_Quit","<control>Q","Exit the application",G_CALLBACK(activate_action)},
};
static guint n_entries = G_N_ELEMENTS (entries);
static const gchar *ui_info =
"<ui>"
" <menubar name='MenuBar'>"
" <menu action='FileMenu'>"
" <menuitem action='New'/>"
" <menuitem action='Open'/>"
" <menuitem action='Save'/>"
" <separator/>"
" <menuitem action='Close'/>"
" <menuitem action='Quit'/>"
" </menu>"
" </menubar>"
" <popup name='IndicatorPopup'>"
" <menuitem action='New' />"
" <menuitem action='Open' />"
" <menuitem action='Save' />"
" <menuitem action='Close' />"
" <menuitem action='Quit' />"
" </popup>"
"</ui>";
static void activate_action(GtkAction *action) {
const gchar *name = gtk_action_get_name(action);
if(strcmp(name,"Quit") == 0 || strcmp(name,"Close") == 0) {
if(mainwindow != NULL) {
gtk_window_close(GTK_WINDOW(mainwindow));
return;
}
}
GtkWidget *dialog;
dialog = gtk_message_dialog_new(NULL,GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_INFO,GTK_BUTTONS_CLOSE,"You activated action: \"%s\"",name);
g_signal_connect(dialog,"response",G_CALLBACK(gtk_widget_destroy),NULL);
gtk_widget_show(dialog);
}
void status_icon_create(GtkWidget *window, char *statusoff, char *statuson) {
if(indicator == NULL) {
mainwindow = window;
GtkUIManager *uim;
GError *error = NULL;
GtkWidget *indicator_menu;
GtkActionGroup *action_group;
action_group = gtk_action_group_new("AppActions");
gtk_action_group_add_actions(action_group,entries,n_entries,window);
uim = gtk_ui_manager_new();
g_object_set_data_full(G_OBJECT(window),"ui-manager",uim,g_object_unref);
gtk_ui_manager_insert_action_group(uim,action_group,0);
gtk_window_add_accel_group(GTK_WINDOW(window),gtk_ui_manager_get_accel_group(uim));
if (!gtk_ui_manager_add_ui_from_string(uim,ui_info,-1,&error)) {
g_message("Failed to build menus: %s\n",error->message);
g_error_free(error);
error = NULL;
}
indicator = app_indicator_new("melonvpn",statusoff,APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
indicator_menu = gtk_ui_manager_get_widget(uim,"/ui/IndicatorPopup");
app_indicator_set_status(indicator,APP_INDICATOR_STATUS_PASSIVE);
app_indicator_set_attention_icon(indicator,statuson);
app_indicator_set_menu(indicator,GTK_MENU(indicator_menu));
}
}
void status_icon_set_state(AppIndicatorStatus status) {
app_indicator_set_status(APP_INDICATOR(indicator),status);
}