Enhancement: Fixes #379, explorer - toggle buttons for sidebars

This commit is contained in:
Rory Fewell
2024-11-26 00:21:15 +00:00
parent 3d9ab28916
commit b057d92578
27 changed files with 1229 additions and 271 deletions

View File

@@ -192,6 +192,8 @@ static void wintc_cpl_view_printers_refresh_items(
{
WINTC_LOG_DEBUG("%s", "cpl-prntrs: refresh printers view");
_wintc_ishext_view_refreshing(view);
// Emit the FPO printer for now
// TODO: Implement this!
//

View File

@@ -51,10 +51,14 @@ add_executable(
wintc-explorer
src/application.c
src/application.h
src/loader.c
src/loader.h
src/main.c
src/resources.c
src/sidebar.c
src/sidebar.h
src/sidebars/favside.c
src/sidebars/favside.h
src/sidebars/fldrside.c
src/sidebars/fldrside.h
src/sidebars/srchside.c

View File

@@ -7,6 +7,7 @@
#include <wintc/shellext.h>
#include "application.h"
#include "loader.h"
#include "window.h"
//
@@ -23,7 +24,8 @@ struct _WinTCExplorerApplication
// Application state
//
WinTCShextHost* shext_host;
WinTCExplorerLoader* exp_loader;
WinTCShextHost* shext_host;
};
//
@@ -130,6 +132,7 @@ static void wintc_explorer_application_dispose(
WINTC_EXPLORER_APPLICATION(object);
g_clear_object(&(explorer_app->shext_host));
g_clear_object(&(explorer_app->exp_loader));
(G_OBJECT_CLASS(wintc_explorer_application_parent_class))
->dispose(object);
@@ -146,6 +149,7 @@ static void wintc_explorer_application_activate(
wintc_explorer_window_new(
explorer_app,
explorer_app->shext_host,
explorer_app->exp_loader,
NULL
);
@@ -233,6 +237,7 @@ static void wintc_explorer_application_open(
GtkWidget* wnd = wintc_explorer_window_new(
explorer_app,
explorer_app->shext_host,
explorer_app->exp_loader,
uri
);
@@ -256,6 +261,14 @@ static void wintc_explorer_application_startup(
//
wintc_ctl_install_default_styles();
// Init sidebars/toolbars
//
explorer_app->exp_loader = wintc_explorer_loader_new();
wintc_explorer_loader_load_extensions(
explorer_app->exp_loader
);
// Create shext host instance
//
explorer_app->shext_host = wintc_shext_host_new();

View File

@@ -25,6 +25,10 @@ GType wintc_explorer_application_get_type(void) G_GNUC_CONST;
//
WinTCExplorerApplication* wintc_explorer_application_new(void);
GType wintc_explorer_application_lookup_sidebar_type(
WinTCExplorerApplication* explorer_app,
const gchar* sidebar_id
);
GdkPixbuf* wintc_explorer_application_get_throbber_pixbuf(void);
#endif

176
shell/explorer/src/loader.c Normal file
View File

@@ -0,0 +1,176 @@
#include <glib.h>
#include <wintc/comgtk.h>
#include "loader.h"
#include "sidebars/favside.h"
#include "sidebars/fldrside.h"
#include "sidebars/srchside.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCExplorerLoaderClass
{
GObjectClass __parent__;
};
struct _WinTCExplorerLoader
{
GObject __parent__;
// State
//
GHashTable* map_sidebar_id_to_type;
};
//
// FORWARD DECLARATIONS
//
static void wintc_explorer_loader_dispose(
GObject* object
);
static void map_sidebar_type(
WinTCExplorerLoader* loader,
const gchar* sidebar_id,
GType type
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCExplorerLoader,
wintc_explorer_loader,
G_TYPE_OBJECT
)
static void wintc_explorer_loader_class_init(
WinTCExplorerLoaderClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->dispose = wintc_explorer_loader_dispose;
}
static void wintc_explorer_loader_init(
WINTC_UNUSED(WinTCExplorerLoader* self)
) {}
//
// CLASS VIRTUAL METHODS
//
static void wintc_explorer_loader_dispose(
GObject* object
)
{
WinTCExplorerLoader* loader = WINTC_EXPLORER_LOADER(object);
g_hash_table_unref(g_steal_pointer(&(loader->map_sidebar_id_to_type)));
(G_OBJECT_CLASS(wintc_explorer_loader_parent_class))->dispose(object);
}
//
// PUBLIC FUNCTIONS
//
WinTCExplorerLoader* wintc_explorer_loader_new(void)
{
return WINTC_EXPLORER_LOADER(
g_object_new(WINTC_TYPE_EXPLORER_LOADER, NULL)
);
}
void wintc_explorer_loader_load_extensions(
WinTCExplorerLoader* loader
)
{
if (loader->map_sidebar_id_to_type)
{
g_critical("explorer: attempt to load extensions twice");
return;
}
loader->map_sidebar_id_to_type =
g_hash_table_new_full(
g_str_hash,
g_str_equal,
g_free,
g_free
);
// Insert the built-in sidebars
//
map_sidebar_type(
loader,
WINTC_EXPLORER_SIDEBAR_ID_FAVORITES,
WINTC_TYPE_EXP_FAVORITES_SIDEBAR
);
map_sidebar_type(
loader,
WINTC_EXPLORER_SIDEBAR_ID_FOLDERS,
WINTC_TYPE_EXP_FOLDERS_SIDEBAR
);
map_sidebar_type(
loader,
WINTC_EXPLORER_SIDEBAR_ID_SEARCH,
WINTC_TYPE_EXP_SEARCH_SIDEBAR
);
//
// TODO: Load sidebars from external libs
//
}
GType wintc_explorer_loader_lookup_sidebar_type(
WinTCExplorerLoader* loader,
const gchar* sidebar_id
)
{
if (!sidebar_id)
{
return 0;
}
GType* sidebar_type =
g_hash_table_lookup(
loader->map_sidebar_id_to_type,
sidebar_id
);
if (!sidebar_type)
{
g_critical("explorer: no sidebar found for %s", sidebar_id);
return 0;
}
return *sidebar_type;
}
//
// PRIVATE FUNCTIONS
//
static void map_sidebar_type(
WinTCExplorerLoader* loader,
const gchar* sidebar_id,
GType type
)
{
// This might be crap, but GHashTable operates with pointers - the
// X_TO_POINTER macros aren't gonna help with GType because it's too large
// so actually allocating them here!!
//
// I say 'might' be crap, in all honesty it IS crap but I'm not sure I
// really give a monkeys anyway
//
GType* alloc_type = g_malloc(sizeof(GType));
memcpy(alloc_type, &type, sizeof(sizeof(GType)));
g_hash_table_insert(
loader->map_sidebar_id_to_type,
g_strdup(sidebar_id),
alloc_type
);
}

View File

@@ -0,0 +1,34 @@
#ifndef __LOADER_H__
#define __LOADER_H__
#include <glib.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCExplorerLoaderClass WinTCExplorerLoaderClass;
typedef struct _WinTCExplorerLoader WinTCExplorerLoader;
#define WINTC_TYPE_EXPLORER_LOADER (wintc_explorer_loader_get_type())
#define WINTC_EXPLORER_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_EXPLORER_LOADER, WinTCExplorerLoader))
#define WINTC_EXPLORER_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_EXPLORER_LOADER, WinTCExplorerLoaderClass))
#define IS_WINTC_EXPLORER_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_EXPLORER_LOADER))
#define IS_WINTC_EXPLORER_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_EXPLORER_LOADER))
#define WINTC_EXPLORER_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_EXPLORER_LOADER, WinTCExploerLoader))
GType wintc_explorer_loader_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCExplorerLoader* wintc_explorer_loader_new(void);
void wintc_explorer_loader_load_extensions(
WinTCExplorerLoader* loader
);
GType wintc_explorer_loader_lookup_sidebar_type(
WinTCExplorerLoader* loader,
const gchar* sidebar_id
);
#endif

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkBox" id="main-box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="no">Favorites</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="label">X</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>

View File

@@ -6,6 +6,7 @@
<file>flag38.png</file>
<!-- SIDEBARS -->
<file>favside.ui</file>
<file>fldrside.ui</file>
<file>srchside.ui</file>

View File

@@ -70,6 +70,7 @@ static void wintc_explorer_sidebar_dispose(
WinTCExplorerSidebar* sidebar = WINTC_EXPLORER_SIDEBAR(object);
g_clear_object(&(sidebar->owner_explorer_wnd));
g_clear_object(&(sidebar->root_widget));
(G_OBJECT_CLASS(wintc_explorer_sidebar_parent_class))->dispose(object);
}

View File

@@ -0,0 +1,94 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include "../sidebar.h"
#include "../window.h"
#include "favside.h"
//
// PUBLIC CONSTANTS
//
const gchar* WINTC_EXPLORER_SIDEBAR_ID_FAVORITES = "favorites";
//
// FORWARD DECLARATIONS
//
static void wintc_exp_favorites_sidebar_constructed(
GObject* object
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCExpFavoritesSidebarClass
{
WinTCExplorerSidebarClass __parent__;
};
struct _WinTCExpFavoritesSidebar
{
WinTCExplorerSidebar __parent__;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCExpFavoritesSidebar,
wintc_exp_favorites_sidebar,
WINTC_TYPE_EXPLORER_SIDEBAR
)
static void wintc_exp_favorites_sidebar_class_init(
WinTCExpFavoritesSidebarClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->constructed = wintc_exp_favorites_sidebar_constructed;
}
static void wintc_exp_favorites_sidebar_init(
WinTCExpFavoritesSidebar* self
)
{
WinTCExplorerSidebar* sidebar = WINTC_EXPLORER_SIDEBAR(self);
GtkBuilder* builder =
gtk_builder_new_from_resource(
"/uk/oddmatics/wintc/explorer/favside.ui"
);
sidebar->root_widget =
GTK_WIDGET(
g_object_ref(
gtk_builder_get_object(builder, "main-box")
)
);
g_object_unref(builder);
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_exp_favorites_sidebar_constructed(
WINTC_UNUSED(GObject* object)
) {}
//
// PUBLIC FUNCTIONS
//
WinTCExplorerSidebar* wintc_exp_favorites_sidebar_new(
WinTCExplorerWindow* wnd
)
{
return WINTC_EXPLORER_SIDEBAR(
g_object_new(
WINTC_TYPE_EXP_FAVORITES_SIDEBAR,
"owner-explorer", wnd,
NULL
)
);
}

View File

@@ -0,0 +1,38 @@
#ifndef __FAVSIDE_H__
#define __FAVSIDE_H__
#include <glib.h>
#include <gtk/gtk.h>
#include "../sidebar.h"
#include "../toolbar.h"
#include "../window.h"
//
// PUBLIC CONSTANTS
//
extern const gchar* WINTC_EXPLORER_SIDEBAR_ID_FAVORITES;
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCExpFavoritesSidebarClass WinTCExpFavoritesSidebarClass;
typedef struct _WinTCExpFavoritesSidebar WinTCExpFavoritesSidebar;
#define WINTC_TYPE_EXP_FAVORITES_SIDEBAR (wintc_exp_favorites_sidebar_get_type())
#define WINTC_EXP_FAVORITES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_EXP_FAVORITES_SIDEBAR, WinTCExpFavoritesSidebar))
#define WINTC_EXP_FAVORITES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_EXP_FAVORITES_SIDEBAR, WinTCExpFavoritesSidebarClass))
#define IS_WINTC_EXP_FAVORITES_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_EXP_FAVORITES_SIDEBAR))
#define IS_WINTC_EXP_FAVORITES_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_EXP_FAVORITES_SIDEBAR))
#define WINTC_EXP_FAVORITES_SIDEBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_EXP_FAVORITES_SIDEBAR, WinTCExpFavoritesSidebar))
GType wintc_exp_favorites_sidebar_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
WinTCExplorerSidebar* wintc_exp_favorites_sidebar_new(
WinTCExplorerWindow* wnd
);
#endif

View File

@@ -7,6 +7,11 @@
#include "../window.h"
#include "fldrside.h"
//
// PUBLIC CONSTANTS
//
const gchar* WINTC_EXPLORER_SIDEBAR_ID_FOLDERS = "folders";
//
// FORWARD DECLARATIONS
//
@@ -75,18 +80,15 @@ static void wintc_exp_folders_sidebar_init(
sidebar->root_widget =
GTK_WIDGET(
g_object_ref(
gtk_builder_get_object(builder, "main-box")
)
gtk_builder_get_object(builder, "main-box")
);
self->tree_view =
GTK_WIDGET(
g_object_ref(
gtk_builder_get_object(builder, "tree-view")
)
gtk_builder_get_object(builder, "tree-view")
);
g_object_ref(sidebar->root_widget);
g_object_unref(builder);
}
@@ -121,11 +123,12 @@ static void wintc_exp_folders_sidebar_constructed(
}
else
{
g_signal_connect(
g_signal_connect_object(
sidebar->owner_explorer_wnd,
"mode-changed",
G_CALLBACK(on_explorer_window_mode_changed),
object
object,
G_CONNECT_DEFAULT
);
}

View File

@@ -4,9 +4,15 @@
#include <glib.h>
#include <gtk/gtk.h>
#include "../sidebar.h"
#include "../toolbar.h"
#include "../window.h"
//
// PUBLIC CONSTANTS
//
extern const gchar* WINTC_EXPLORER_SIDEBAR_ID_FOLDERS;
//
// GTK OOP BOILERPLATE
//

View File

@@ -6,10 +6,16 @@
#include "../window.h"
#include "srchside.h"
//
// PUBLIC CONSTANTS
//
const gchar* WINTC_EXPLORER_SIDEBAR_ID_SEARCH = "search";
//
// FORWARD DECLARATIONS
//
static void wintc_exp_search_sidebar_constructed(
GObject* object
);
//

View File

@@ -4,9 +4,15 @@
#include <glib.h>
#include <gtk/gtk.h>
#include "../sidebar.h"
#include "../toolbar.h"
#include "../window.h"
//
// PUBLIC CONSTANTS
//
extern const gchar* WINTC_EXPLORER_SIDEBAR_ID_SEARCH;
//
// GTK OOP BOILERPLATE
//

View File

@@ -2,6 +2,9 @@
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include "../sidebars/favside.h"
#include "../sidebars/fldrside.h"
#include "../sidebars/srchside.h"
#include "../toolbar.h"
#include "../window.h"
#include "stdbar.h"
@@ -13,27 +16,56 @@ static void wintc_exp_standard_toolbar_constructed(
GObject* object
);
GtkToolItem* create_toolbar_button(
static GtkToolItem* create_toolbar_item_from_char(
WinTCExpStandardToolbar* toolbar_std,
gchar c
);
static GtkToolItem* find_toolbar_item(
WinTCExpStandardToolbar* toolbar_std,
gchar c
);
static void populate_toolbar(
WinTCExpStandardToolbar* toolbar_std,
const gchar* config_str
);
static void repopulate_toolbar(
WinTCExpStandardToolbar* toolbar_std
);
static void setup_toolbar_button(
GtkToolItem* tool_button,
gboolean is_important,
gboolean is_menu_button,
const gchar* label,
const gchar* icon_name
);
GtkToolItem* create_toolbar_item_from_char(
gchar c
);
void populate_toolbar(
GtkWidget* toolbar,
const gchar* config_str
);
void repopulate_toolbar(
static void sync_sidebar_buttons(
WinTCExpStandardToolbar* toolbar_std
);
static void toggle_sidebar(
WinTCExpStandardToolbar* toolbar_std,
const gchar* sidebar_id
);
static void on_owner_explorer_wnd_notify_active_sidebar(
GObject* self,
GParamSpec* pspec,
gpointer user_data
);
static void on_owner_explorer_wnd_mode_changed(
GtkWidget* self,
gpointer user_data
);
static void on_toolbar_button_favorites_toggled(
GtkToggleToolButton* self,
gpointer user_data
);
static void on_toolbar_button_folders_toggled(
GtkToggleToolButton* self,
gpointer user_data
);
static void on_toolbar_button_search_toggled(
GtkToggleToolButton* self,
gpointer user_data
);
static void on_toolbar_style_updated(
GtkWidget* self,
gpointer user_data
@@ -58,6 +90,10 @@ struct _WinTCExpStandardToolbarClass
struct _WinTCExpStandardToolbar
{
WinTCExplorerToolbar __parent__;
// State
//
gboolean synchronizing;
};
//
@@ -112,6 +148,12 @@ static void wintc_exp_standard_toolbar_constructed(
G_CALLBACK(on_owner_explorer_wnd_mode_changed),
object
);
g_signal_connect(
toolbar->owner_explorer_wnd,
"notify::active-sidebar",
G_CALLBACK(on_owner_explorer_wnd_notify_active_sidebar),
object
);
(G_OBJECT_CLASS(wintc_exp_standard_toolbar_parent_class))
->constructed(object);
@@ -136,51 +178,9 @@ WinTCExplorerToolbar* wintc_exp_standard_toolbar_new(
//
// PRIVATE FUNCTIONS
//
GtkToolItem* create_toolbar_button(
gboolean is_important,
gboolean is_menu_button,
const gchar* label,
const gchar* icon_name
)
{
GtkToolItem* tb;
if (is_menu_button)
{
tb = gtk_menu_tool_button_new(NULL, NULL);
}
else
{
tb = gtk_tool_button_new(NULL, NULL);
}
if (icon_name)
{
gtk_tool_button_set_icon_name(
GTK_TOOL_BUTTON(tb),
icon_name
);
}
if (label)
{
gtk_tool_button_set_label(
GTK_TOOL_BUTTON(tb),
label
);
gtk_widget_set_tooltip_text(
GTK_WIDGET(tb),
label
);
}
gtk_tool_item_set_is_important(tb, is_important);
return tb;
}
GtkToolItem* create_toolbar_item_from_char(
gchar c
static GtkToolItem* create_toolbar_item_from_char(
WinTCExpStandardToolbar* toolbar_std,
gchar c
)
{
GtkToolItem* ret = NULL;
@@ -197,82 +197,106 @@ GtkToolItem* create_toolbar_item_from_char(
// TODO: The tooltip for the back button should be the first
// item in the history
//
ret =
create_toolbar_button(
TRUE,
TRUE,
"Back",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-previous",
"history-back",
NULL
)
);
ret = gtk_menu_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
TRUE,
"Back",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-previous",
"history-back",
NULL
)
);
break;
// TODO: Implement this
//
case 'C':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Messenger",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"face-wink",
"windows-messenger",
"internet-group-chat",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Messenger",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"face-wink",
"windows-messenger",
"internet-group-chat",
NULL
)
);
break;
// TODO: Implement this
//
case 'd':
ret =
create_toolbar_button(
TRUE,
FALSE,
"Folders",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"inode-directory",
"folders",
NULL
)
);
ret = gtk_toggle_tool_button_new();
setup_toolbar_button(
ret,
TRUE,
"Folders",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"inode-directory",
"folders",
NULL
)
);
g_signal_connect(
ret,
"toggled",
G_CALLBACK(on_toolbar_button_folders_toggled),
toolbar_std
);
break;
// TODO: Implement this
//
case 'E':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Edit with Notepad", // FIXME: Might not always be notepad?
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"document-properties",
"document-open-ide",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Edit with Notepad", // FIXME: Might not always be notepad?
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"document-properties",
"document-open-ide",
NULL
)
);
break;
// TODO: Implement this
//
case 'F':
ret =
create_toolbar_button(
TRUE,
FALSE,
"Favorites",
"emblem-favorite"
);
ret = gtk_toggle_tool_button_new();
setup_toolbar_button(
ret,
TRUE,
"Favorites",
"emblem-favorite"
);
g_signal_connect(
ret,
"toggled",
G_CALLBACK(on_toolbar_button_favorites_toggled),
toolbar_std
);
break;
// TODO: Implement this
@@ -280,142 +304,166 @@ GtkToolItem* create_toolbar_item_from_char(
case 'f':
// TODO: See back button tooltip about history, but for Forward,
// since it has no label, the tooltip defaults to Forward
ret =
create_toolbar_button(
FALSE,
FALSE,
"Forward",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-next",
"history-forward",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Forward",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-next",
"history-forward",
NULL
)
);
break;
// TODO: Implement this
//
case 'H':
ret =
create_toolbar_button(
FALSE,
FALSE,
"History",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"media-seek-backward",
"history",
NULL
)
);
ret = gtk_toggle_tool_button_new();
setup_toolbar_button(
ret,
FALSE,
"History",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"media-seek-backward",
"history",
NULL
)
);
break;
// TODO: Implement this
//
case 'h':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Home",
"go-home"
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Home",
"go-home"
);
break;
// TODO: Implement this
//
case 'M':
ret =
create_toolbar_button(
FALSE,
TRUE,
"Mail",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"emblem-mail",
"internet-mail",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Mail",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"emblem-mail",
"internet-mail",
NULL
)
);
break;
// TODO: Implement this
//
case 'P':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Print",
"printer"
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Print",
"printer"
);
break;
// TODO: Implement this
//
case 'R':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Refresh",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"view-refresh",
"document-refresh",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Refresh",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"view-refresh",
"document-refresh",
NULL
)
);
break;
// TODO: Implement this
//
case 'S':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Stop",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"process-stop",
"document-stop",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Stop",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"process-stop",
"document-stop",
NULL
)
);
break;
// TODO: Implement this
//
case 's':
ret =
create_toolbar_button(
TRUE,
FALSE,
"Search",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"system-search",
"search",
NULL
)
);
ret = gtk_toggle_tool_button_new();
setup_toolbar_button(
ret,
TRUE,
"Search",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"system-search",
"search",
NULL
)
);
g_signal_connect(
ret,
"toggled",
G_CALLBACK(on_toolbar_button_search_toggled),
toolbar_std
);
break;
case 'u':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Up",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-up",
"go-parent-directory",
NULL
)
);
ret = gtk_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Up",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"go-up",
"go-parent-directory",
NULL
)
);
gtk_actionable_set_action_name(
GTK_ACTIONABLE(ret),
@@ -427,18 +475,20 @@ GtkToolItem* create_toolbar_item_from_char(
// TODO: Implement this
//
case 'v':
ret =
create_toolbar_button(
FALSE,
FALSE,
"Views",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"video-display",
"views",
NULL
)
);
ret = gtk_menu_tool_button_new(NULL, NULL);
setup_toolbar_button(
ret,
FALSE,
"Views",
wintc_icon_name_first_available(
S_TOOLBAR_ICON_SIZE,
"video-display",
"views",
NULL
)
);
break;
case '|':
@@ -459,11 +509,63 @@ GtkToolItem* create_toolbar_item_from_char(
return ret;
}
void populate_toolbar(
GtkWidget* toolbar,
const gchar* config_str
static GtkToolItem* find_toolbar_item(
WinTCExpStandardToolbar* toolbar_std,
gchar c
)
{
WinTCExplorerToolbar* toolbar = WINTC_EXPLORER_TOOLBAR(toolbar_std);
// We locate the button based on its position in the toolbar string
//
gint pos = -1;
WinTCExplorerWindowMode mode =
wintc_explorer_window_get_mode(
WINTC_EXPLORER_WINDOW(toolbar->owner_explorer_wnd)
);
switch (mode)
{
case WINTC_EXPLORER_WINDOW_MODE_LOCAL:
pos = strchr(S_LAYOUT_LOCAL, c) - S_LAYOUT_LOCAL;
break;
case WINTC_EXPLORER_WINDOW_MODE_INTERNET:
pos = strchr(S_LAYOUT_INTERNET, c) - S_LAYOUT_INTERNET;
break;
default:
g_critical("explorer: stdbar unknown explorer mode %d", mode);
break;
}
if (pos < 0)
{
return NULL;
}
// Grab the toolbar widget
//
GList* children = gtk_container_get_children(
GTK_CONTAINER(toolbar->toolbar)
);
GtkToolItem* found = GTK_TOOL_ITEM(
g_list_nth_data(children, (guint) pos)
);
g_list_free(children);
return found;
}
static void populate_toolbar(
WinTCExpStandardToolbar* toolbar_std,
const gchar* config_str
)
{
GtkWidget* toolbar = (WINTC_EXPLORER_TOOLBAR(toolbar_std))->toolbar;
wintc_container_clear(GTK_CONTAINER(toolbar));
WINTC_LOG_DEBUG("explorer: populating std toolbar with %s", config_str);
@@ -472,7 +574,7 @@ void populate_toolbar(
{
gtk_toolbar_insert(
GTK_TOOLBAR(toolbar),
create_toolbar_item_from_char(*p),
create_toolbar_item_from_char(toolbar_std, *p),
-1
);
}
@@ -480,7 +582,7 @@ void populate_toolbar(
gtk_widget_show_all(toolbar);
}
void repopulate_toolbar(
static void repopulate_toolbar(
WinTCExpStandardToolbar* toolbar_std
)
{
@@ -496,22 +598,158 @@ void repopulate_toolbar(
switch (mode)
{
case WINTC_EXPLORER_WINDOW_MODE_LOCAL:
populate_toolbar(GTK_WIDGET(toolbar->toolbar), S_LAYOUT_LOCAL);
populate_toolbar(toolbar_std, S_LAYOUT_LOCAL);
break;
case WINTC_EXPLORER_WINDOW_MODE_INTERNET:
populate_toolbar(GTK_WIDGET(toolbar->toolbar), S_LAYOUT_INTERNET);
populate_toolbar(toolbar_std, S_LAYOUT_INTERNET);
break;
default:
g_critical("explorer: stdbar unknown explorer mode %d", mode);
break;
}
sync_sidebar_buttons(toolbar_std);
}
static void setup_toolbar_button(
GtkToolItem* tool_button,
gboolean is_important,
const gchar* label,
const gchar* icon_name
)
{
if (icon_name)
{
gtk_tool_button_set_icon_name(
GTK_TOOL_BUTTON(tool_button),
icon_name
);
}
if (label)
{
gtk_tool_button_set_label(
GTK_TOOL_BUTTON(tool_button),
label
);
gtk_widget_set_tooltip_text(
GTK_WIDGET(tool_button),
label
);
}
gtk_tool_item_set_is_important(tool_button, is_important);
}
static void sync_sidebar_buttons(
WinTCExpStandardToolbar* toolbar_std
)
{
WinTCExplorerToolbar* toolbar = WINTC_EXPLORER_TOOLBAR(toolbar_std);
toolbar_std->synchronizing = TRUE;
// Identify the corresponding toolbar button, if any
//
gchar* active_sidebar_id;
GtkToolItem* to_activate = NULL;
g_object_get(
toolbar->owner_explorer_wnd,
"active-sidebar", &active_sidebar_id,
NULL
);
if (
g_strcmp0(active_sidebar_id, WINTC_EXPLORER_SIDEBAR_ID_FAVORITES) == 0
)
{
to_activate = find_toolbar_item(toolbar_std, 'F');
}
else if (
g_strcmp0(active_sidebar_id, WINTC_EXPLORER_SIDEBAR_ID_FOLDERS) == 0
)
{
to_activate = find_toolbar_item(toolbar_std, 'd');
}
else if (
g_strcmp0(active_sidebar_id, WINTC_EXPLORER_SIDEBAR_ID_SEARCH) == 0
)
{
to_activate = find_toolbar_item(toolbar_std, 's');
}
g_free(active_sidebar_id);
// Iterate over the toolbar items to sync the toggle buttons
//
GList* children =
gtk_container_get_children(GTK_CONTAINER(toolbar->toolbar));
for (GList* iter = children; iter; iter = iter->next)
{
if (iter->data == to_activate)
{
continue;
}
if (GTK_IS_TOGGLE_TOOL_BUTTON(iter->data))
{
gtk_toggle_tool_button_set_active(
GTK_TOGGLE_TOOL_BUTTON(iter->data),
FALSE
);
}
}
g_list_free(children);
if (to_activate)
{
gtk_toggle_tool_button_set_active(
GTK_TOGGLE_TOOL_BUTTON(to_activate),
TRUE
);
}
toolbar_std->synchronizing = FALSE;
}
static void toggle_sidebar(
WinTCExpStandardToolbar* toolbar_std,
const gchar* sidebar_id
)
{
WinTCExplorerToolbar* toolbar = WINTC_EXPLORER_TOOLBAR(toolbar_std);
if (toolbar_std->synchronizing)
{
return;
}
wintc_explorer_window_toggle_sidebar(
WINTC_EXPLORER_WINDOW(toolbar->owner_explorer_wnd),
sidebar_id
);
}
//
// CALLBACKS
//
static void on_owner_explorer_wnd_notify_active_sidebar(
WINTC_UNUSED(GObject* self),
WINTC_UNUSED(GParamSpec* pspec),
gpointer user_data
)
{
WinTCExpStandardToolbar* toolbar_std =
WINTC_EXP_STANDARD_TOOLBAR(user_data);
sync_sidebar_buttons(toolbar_std);
}
static void on_owner_explorer_wnd_mode_changed(
WINTC_UNUSED(GtkWidget* self),
gpointer user_data
@@ -522,6 +760,39 @@ static void on_owner_explorer_wnd_mode_changed(
repopulate_toolbar(WINTC_EXP_STANDARD_TOOLBAR(user_data));
}
static void on_toolbar_button_favorites_toggled(
WINTC_UNUSED(GtkToggleToolButton* self),
gpointer user_data
)
{
WinTCExpStandardToolbar* toolbar_std =
WINTC_EXP_STANDARD_TOOLBAR(user_data);
toggle_sidebar(toolbar_std, WINTC_EXPLORER_SIDEBAR_ID_FAVORITES);
}
static void on_toolbar_button_folders_toggled(
WINTC_UNUSED(GtkToggleToolButton* self),
gpointer user_data
)
{
WinTCExpStandardToolbar* toolbar_std =
WINTC_EXP_STANDARD_TOOLBAR(user_data);
toggle_sidebar(toolbar_std, WINTC_EXPLORER_SIDEBAR_ID_FOLDERS);
}
static void on_toolbar_button_search_toggled(
WINTC_UNUSED(GtkToggleToolButton* self),
gpointer user_data
)
{
WinTCExpStandardToolbar* toolbar_std =
WINTC_EXP_STANDARD_TOOLBAR(user_data);
toggle_sidebar(toolbar_std, WINTC_EXPLORER_SIDEBAR_ID_SEARCH);
}
static void on_toolbar_style_updated(
WINTC_UNUSED(GtkWidget* self),
gpointer user_data

View File

@@ -10,6 +10,7 @@
#include <wintc/shlang.h>
#include "application.h"
#include "loader.h"
#include "sidebar.h"
#include "sidebars/fldrside.h"
#include "toolbar.h"
@@ -23,7 +24,9 @@
enum
{
PROP_SHEXT_HOST = 1,
PROP_INITIAL_PATH
PROP_EXPLORER_LOADER,
PROP_INITIAL_PATH,
PROP_ACTIVE_SIDEBAR
};
enum
@@ -45,6 +48,12 @@ static void wintc_explorer_window_dispose(
static void wintc_explorer_window_finalize(
GObject* object
);
static void wintc_explorer_window_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
);
static void wintc_explorer_window_set_property(
GObject* object,
guint prop_id,
@@ -156,7 +165,10 @@ struct _WinTCExplorerWindow
WinTCExplorerWindowMode mode;
WinTCExplorerSidebar* sidebar_folders;
WinTCExplorerLoader* loader;
gchar* active_sidebar_id;
WinTCExplorerSidebar* active_sidebar;
WinTCExplorerToolbar* toolbar_adr;
WinTCExplorerToolbar* toolbar_std;
@@ -195,6 +207,7 @@ static void wintc_explorer_window_class_init(
object_class->constructed = wintc_explorer_window_constructed;
object_class->dispose = wintc_explorer_window_dispose;
object_class->finalize = wintc_explorer_window_finalize;
object_class->get_property = wintc_explorer_window_get_property;
object_class->set_property = wintc_explorer_window_set_property;
g_object_class_install_property(
@@ -208,6 +221,17 @@ static void wintc_explorer_window_class_init(
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
g_object_class_install_property(
object_class,
PROP_EXPLORER_LOADER,
g_param_spec_object(
"explorer-loader",
"ExplorerLoader",
"The explorer sidebar and toolbar loader host object to use.",
WINTC_TYPE_EXPLORER_LOADER,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
g_object_class_install_property(
object_class,
PROP_INITIAL_PATH,
@@ -220,6 +244,18 @@ static void wintc_explorer_window_class_init(
)
);
g_object_class_install_property(
object_class,
PROP_ACTIVE_SIDEBAR,
g_param_spec_string(
"active-sidebar",
"ActiveSidebar",
"The currently active sidebar.",
NULL,
G_PARAM_READWRITE
)
);
wintc_explorer_window_signals[SIGNAL_LOCATION_CHANGED] =
g_signal_new(
"location-changed",
@@ -309,17 +345,8 @@ static void wintc_explorer_window_init(
// FIXME: Temporary pane setup
//
self->sidebar_folders = wintc_exp_folders_sidebar_new(self);
self->scrollwnd_main = gtk_scrolled_window_new(NULL, NULL);
gtk_paned_pack1(
GTK_PANED(self->pane_view),
wintc_explorer_sidebar_get_root_widget(
self->sidebar_folders
),
FALSE,
FALSE
);
gtk_paned_pack2(
GTK_PANED(self->pane_view),
self->scrollwnd_main,
@@ -378,6 +405,11 @@ static void wintc_explorer_window_constructed(
//
if (!wnd->initial_path)
{
wintc_explorer_window_toggle_sidebar(
wnd,
WINTC_EXPLORER_SIDEBAR_ID_FOLDERS
);
// Nav to desktop if there's no path
//
do_navigation(
@@ -409,6 +441,8 @@ static void wintc_explorer_window_dispose(
g_clear_object(&(wnd->iconview_browser));
g_clear_object(&(wnd->webkit_browser));
g_clear_object(&(wnd->loader));
g_clear_object(&(wnd->active_sidebar));
g_clear_object(&(wnd->toolbar_adr));
g_clear_object(&(wnd->toolbar_std));
@@ -421,6 +455,7 @@ static void wintc_explorer_window_finalize(
{
WinTCExplorerWindow* wnd = WINTC_EXPLORER_WINDOW(object);
g_free(wnd->active_sidebar_id);
g_free(wnd->initial_path);
g_free(wnd->internet_path);
wintc_shext_path_info_free_data(&(wnd->local_path));
@@ -428,6 +463,27 @@ static void wintc_explorer_window_finalize(
(G_OBJECT_CLASS(wintc_explorer_window_parent_class))->finalize(object);
}
static void wintc_explorer_window_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
)
{
WinTCExplorerWindow* wnd = WINTC_EXPLORER_WINDOW(object);
switch (prop_id)
{
case PROP_ACTIVE_SIDEBAR:
g_value_set_string(value, wnd->active_sidebar_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void wintc_explorer_window_set_property(
GObject* object,
guint prop_id,
@@ -443,10 +499,81 @@ static void wintc_explorer_window_set_property(
wnd->shext_host = g_value_dup_object(value);
break;
case PROP_EXPLORER_LOADER:
wnd->loader = g_value_dup_object(value);
break;
case PROP_INITIAL_PATH:
wnd->initial_path = g_value_dup_string(value);
break;
case PROP_ACTIVE_SIDEBAR:
// Check if this is a nothing burger
//
if (
g_strcmp0(
wnd->active_sidebar_id,
g_value_get_string(value)
) == 0
)
{
break;
}
if (wnd->active_sidebar)
{
gtk_container_remove(
GTK_CONTAINER(wnd->pane_view),
gtk_paned_get_child1(GTK_PANED(wnd->pane_view))
);
g_clear_object(&(wnd->active_sidebar));
}
g_free(wnd->active_sidebar_id);
wnd->active_sidebar_id = g_value_dup_string(value);
if (wnd->active_sidebar_id)
{
GType sidebar_type =
wintc_explorer_loader_lookup_sidebar_type(
wnd->loader,
wnd->active_sidebar_id
);
if (!sidebar_type)
{
// Safety - set toolbar to NULL
//
g_object_set(
wnd,
"active-sidebar", NULL,
NULL
);
break;
}
wnd->active_sidebar =
WINTC_EXPLORER_SIDEBAR(
g_object_new(
sidebar_type,
"owner-explorer", wnd,
NULL
)
);
gtk_paned_pack1(
GTK_PANED(wnd->pane_view),
wintc_explorer_sidebar_get_root_widget(
wnd->active_sidebar
),
FALSE,
FALSE
);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -459,15 +586,17 @@ static void wintc_explorer_window_set_property(
GtkWidget* wintc_explorer_window_new(
WinTCExplorerApplication* app,
WinTCShextHost* shext_host,
WinTCExplorerLoader* loader,
const gchar* initial_path
)
{
return GTK_WIDGET(
g_object_new(
WINTC_TYPE_EXPLORER_WINDOW,
"application", GTK_APPLICATION(app),
"shext-host", shext_host,
"initial-path", initial_path,
"application", GTK_APPLICATION(app),
"shext-host", shext_host,
"explorer-loader", loader,
"initial-path", initial_path,
NULL
)
);
@@ -520,6 +649,22 @@ WinTCExplorerWindowMode wintc_explorer_window_get_mode(
return wnd->mode;
}
void wintc_explorer_window_toggle_sidebar(
WinTCExplorerWindow* wnd,
const gchar* sidebar_id
)
{
const gchar* to_select =
g_strcmp0(wnd->active_sidebar_id, sidebar_id) == 0 ?
NULL : sidebar_id;
g_object_set(
wnd,
"active-sidebar", to_select,
NULL
);
}
//
// PRIVATE FUNCTIONS
//

View File

@@ -7,6 +7,7 @@
#include <wintc/shellext.h>
#include "application.h"
#include "loader.h"
//
// PUBLIC ENUMS
@@ -39,6 +40,7 @@ GType wintc_explorer_window_get_type(void) G_GNUC_CONST;
GtkWidget* wintc_explorer_window_new(
WinTCExplorerApplication* app,
WinTCShextHost* shext_host,
WinTCExplorerLoader* loader,
const gchar* initial_path
);
@@ -52,5 +54,9 @@ void wintc_explorer_window_get_location(
WinTCExplorerWindowMode wintc_explorer_window_get_mode(
WinTCExplorerWindow* wnd
);
void wintc_explorer_window_toggle_sidebar(
WinTCExplorerWindow* wnd,
const gchar* sidebar_id
);
#endif

View File

@@ -303,6 +303,8 @@ static void wintc_view_zip_refresh_items(
WINTC_LOG_DEBUG("%s", "shext-zip: refresh zip view");
_wintc_ishext_view_refreshing(view);
// Open the archive
//
const gchar* path = view_zip->zip_uri + strlen("file://");