Added support for inline images, this currently only works in dmenu mode
This commit is contained in:
parent
34681ca8f9
commit
e3c79c3bd4
@ -7,7 +7,7 @@ C_SRCS += \
|
|||||||
../src/config.c \
|
../src/config.c \
|
||||||
../src/main.c \
|
../src/main.c \
|
||||||
../src/map.c \
|
../src/map.c \
|
||||||
../src/property_label.c \
|
../src/property_box.c \
|
||||||
../src/utils.c \
|
../src/utils.c \
|
||||||
../src/wofi.c
|
../src/wofi.c
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ OBJS += \
|
|||||||
./src/config.o \
|
./src/config.o \
|
||||||
./src/main.o \
|
./src/main.o \
|
||||||
./src/map.o \
|
./src/map.o \
|
||||||
./src/property_label.o \
|
./src/property_box.o \
|
||||||
./src/utils.o \
|
./src/utils.o \
|
||||||
./src/wofi.o
|
./src/wofi.o
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ C_DEPS += \
|
|||||||
./src/config.d \
|
./src/config.d \
|
||||||
./src/main.d \
|
./src/main.d \
|
||||||
./src/map.d \
|
./src/map.d \
|
||||||
./src/property_label.d \
|
./src/property_box.d \
|
||||||
./src/utils.d \
|
./src/utils.d \
|
||||||
./src/wofi.d
|
./src/wofi.d
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ C_SRCS += \
|
|||||||
../src/config.c \
|
../src/config.c \
|
||||||
../src/main.c \
|
../src/main.c \
|
||||||
../src/map.c \
|
../src/map.c \
|
||||||
../src/property_label.c \
|
../src/property_box.c \
|
||||||
../src/utils.c \
|
../src/utils.c \
|
||||||
../src/wofi.c
|
../src/wofi.c
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ OBJS += \
|
|||||||
./src/config.o \
|
./src/config.o \
|
||||||
./src/main.o \
|
./src/main.o \
|
||||||
./src/map.o \
|
./src/map.o \
|
||||||
./src/property_label.o \
|
./src/property_box.o \
|
||||||
./src/utils.o \
|
./src/utils.o \
|
||||||
./src/wofi.o
|
./src/wofi.o
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ C_DEPS += \
|
|||||||
./src/config.d \
|
./src/config.d \
|
||||||
./src/main.d \
|
./src/main.d \
|
||||||
./src/map.d \
|
./src/map.d \
|
||||||
./src/property_label.d \
|
./src/property_box.d \
|
||||||
./src/utils.d \
|
./src/utils.d \
|
||||||
./src/wofi.d
|
./src/wofi.d
|
||||||
|
|
||||||
|
@ -15,19 +15,19 @@
|
|||||||
along with Wofi. If not, see <http://www.gnu.org/licenses/>.
|
along with Wofi. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PROPERTY_LABEL_H
|
#ifndef PROPERTY_BOX_H
|
||||||
#define PROPERTY_LABEL_H
|
#define PROPERTY_BOX_H
|
||||||
#include <map.h>
|
#include <map.h>
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#define WOFI_TYPE_PROPERTY_LABEL wofi_property_label_get_type()
|
#define WOFI_TYPE_PROPERTY_BOX wofi_property_box_get_type()
|
||||||
G_DECLARE_FINAL_TYPE(WofiPropertyLabel, wofi_property_label, WOFI, PROPERTY_LABEL, GtkLabel);
|
G_DECLARE_FINAL_TYPE(WofiPropertyBox, wofi_property_box, WOFI, PROPERTY_BOX, GtkBox);
|
||||||
|
|
||||||
GtkWidget* wofi_property_label_new(const gchar* str);
|
GtkWidget* wofi_property_box_new(GtkOrientation orientation, gint spacing);
|
||||||
|
|
||||||
void wofi_property_label_add_property(WofiPropertyLabel* this, const gchar* key, gchar* value);
|
void wofi_property_box_add_property(WofiPropertyBox* this, const gchar* key, gchar* value);
|
||||||
|
|
||||||
const gchar* wofi_property_label_get_property(WofiPropertyLabel* this, const gchar* key);
|
const gchar* wofi_property_box_get_property(WofiPropertyBox* this, const gchar* key);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <map.h>
|
#include <map.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <property_label.h>
|
#include <property_box.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
16
src/main.c
16
src/main.c
@ -61,6 +61,7 @@ static void print_usage(char** argv) {
|
|||||||
printf("--xoffset\t-x\tThe x offset\n");
|
printf("--xoffset\t-x\tThe x offset\n");
|
||||||
printf("--yoffset\t-y\tThe y offset\n");
|
printf("--yoffset\t-y\tThe y offset\n");
|
||||||
printf("--normal-window\t-n\tRender to a normal window\n");
|
printf("--normal-window\t-n\tRender to a normal window\n");
|
||||||
|
printf("--allow-images\t-i\tAllows images to be rendered\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +243,12 @@ int main(int argc, char** argv) {
|
|||||||
.flag = NULL,
|
.flag = NULL,
|
||||||
.val = 'n'
|
.val = 'n'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "allow-images",
|
||||||
|
.has_arg = no_argument,
|
||||||
|
.flag = NULL,
|
||||||
|
.val = 'i'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = NULL,
|
.name = NULL,
|
||||||
.has_arg = 0,
|
.has_arg = 0,
|
||||||
@ -260,8 +267,9 @@ int main(int argc, char** argv) {
|
|||||||
char* x = NULL;
|
char* x = NULL;
|
||||||
char* y = NULL;
|
char* y = NULL;
|
||||||
char* normal_window = NULL;
|
char* normal_window = NULL;
|
||||||
|
char* allow_images = NULL;
|
||||||
char opt;
|
char opt;
|
||||||
while((opt = getopt_long(argc, argv, "hfc:s:C:dS:W:H:p:x:y:n", opts, NULL)) != -1) {
|
while((opt = getopt_long(argc, argv, "hfc:s:C:dS:W:H:p:x:y:ni", opts, NULL)) != -1) {
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
print_usage(argv);
|
print_usage(argv);
|
||||||
@ -307,6 +315,9 @@ int main(int argc, char** argv) {
|
|||||||
case 'n':
|
case 'n':
|
||||||
normal_window = "true";
|
normal_window = "true";
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
allow_images = "true";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +411,9 @@ int main(int argc, char** argv) {
|
|||||||
if(normal_window != NULL) {
|
if(normal_window != NULL) {
|
||||||
map_put(config, "normal_window", normal_window);
|
map_put(config, "normal_window", normal_window);
|
||||||
}
|
}
|
||||||
|
if(allow_images != NULL) {
|
||||||
|
map_put(config, "allow_images", allow_images);
|
||||||
|
}
|
||||||
|
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
|
|
||||||
|
58
src/property_box.c
Normal file
58
src/property_box.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Scoopta
|
||||||
|
* This file is part of Wofi
|
||||||
|
* Wofi is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Wofi is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Wofi. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <property_box.h>
|
||||||
|
|
||||||
|
struct _WofiPropertyBox {
|
||||||
|
GtkBox super;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct map* properties;
|
||||||
|
} WofiPropertyBoxPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE(WofiPropertyBox, wofi_property_box, GTK_TYPE_BOX);
|
||||||
|
|
||||||
|
static void wofi_property_box_init(WofiPropertyBox* box) {
|
||||||
|
WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
|
||||||
|
this->properties = map_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void finalize(GObject* obj) {
|
||||||
|
WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(WOFI_PROPERTY_BOX(obj));
|
||||||
|
map_free(this->properties);
|
||||||
|
G_OBJECT_CLASS(wofi_property_box_parent_class)->finalize(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wofi_property_box_class_init(WofiPropertyBoxClass* class) {
|
||||||
|
GObjectClass* g_class = G_OBJECT_CLASS(class);
|
||||||
|
g_class->finalize = finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget* wofi_property_box_new(GtkOrientation orientation, gint spacing) {
|
||||||
|
return g_object_new(WOFI_TYPE_PROPERTY_BOX, "orientation", orientation, "spacing", spacing, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wofi_property_box_add_property(WofiPropertyBox* box, const gchar* key, gchar* value) {
|
||||||
|
WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
|
||||||
|
map_put(this->properties, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar* wofi_property_box_get_property(WofiPropertyBox* box, const gchar* key) {
|
||||||
|
WofiPropertyBoxPrivate* this = wofi_property_box_get_instance_private(box);
|
||||||
|
return map_get(this->properties, key);
|
||||||
|
}
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 Scoopta
|
|
||||||
* This file is part of Wofi
|
|
||||||
* Wofi is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Wofi is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Wofi. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <property_label.h>
|
|
||||||
|
|
||||||
struct _WofiPropertyLabel {
|
|
||||||
GtkLabel super;
|
|
||||||
struct map* properties;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(WofiPropertyLabel, wofi_property_label, GTK_TYPE_LABEL);
|
|
||||||
|
|
||||||
static void wofi_property_label_init(WofiPropertyLabel* this) {
|
|
||||||
this->properties = map_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void finalize(GObject* obj) {
|
|
||||||
WofiPropertyLabel* this = WOFI_PROPERTY_LABEL(obj);
|
|
||||||
map_free(this->properties);
|
|
||||||
G_OBJECT_CLASS(wofi_property_label_parent_class)->finalize(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wofi_property_label_class_init(WofiPropertyLabelClass* class) {
|
|
||||||
GObjectClass* g_class = G_OBJECT_CLASS(class);
|
|
||||||
g_class->finalize = finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget* wofi_property_label_new(const gchar* str) {
|
|
||||||
return g_object_new(WOFI_TYPE_PROPERTY_LABEL, "label", str, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wofi_property_label_add_property(WofiPropertyLabel* this, const gchar* key, gchar* value) {
|
|
||||||
map_put(this->properties, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const gchar* wofi_property_label_get_property(WofiPropertyLabel* this, const gchar* key) {
|
|
||||||
return map_get(this->properties, key);
|
|
||||||
}
|
|
99
src/wofi.c
99
src/wofi.c
@ -25,6 +25,7 @@ static const gchar* filter;
|
|||||||
static char* mode;
|
static char* mode;
|
||||||
static time_t filter_time;
|
static time_t filter_time;
|
||||||
static int64_t filter_rate;
|
static int64_t filter_rate;
|
||||||
|
static bool allow_images;
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
char* text, *action;
|
char* text, *action;
|
||||||
@ -73,19 +74,72 @@ static void get_search(GtkSearchEntry* entry, gpointer data) {
|
|||||||
gtk_list_box_invalidate_filter(GTK_LIST_BOX(inner_box));
|
gtk_list_box_invalidate_filter(GTK_LIST_BOX(inner_box));
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget* create_label(const char* text, char* action) {
|
static GtkWidget* create_label(char* text, char* action) {
|
||||||
GtkWidget* label = wofi_property_label_new(text);
|
GtkWidget* box = wofi_property_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
gtk_widget_set_name(label, "unselected");
|
gtk_widget_set_name(box, "unselected");
|
||||||
wofi_property_label_add_property(WOFI_PROPERTY_LABEL(label), "action", action);
|
wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "action", action);
|
||||||
gtk_label_set_xalign(GTK_LABEL(label), 0);
|
if(allow_images) {
|
||||||
return label;
|
char* tmp = strdup(text);
|
||||||
|
char* original = tmp;
|
||||||
|
char* mode = NULL;
|
||||||
|
char* filter = NULL;
|
||||||
|
|
||||||
|
size_t colon_count = utils_split(tmp, ':');
|
||||||
|
for(size_t count = 0; count < colon_count; ++count) {
|
||||||
|
if(mode == NULL) {
|
||||||
|
mode = tmp;
|
||||||
|
} else {
|
||||||
|
if(strcmp(mode, "img") == 0) {
|
||||||
|
GdkPixbuf* buf = gdk_pixbuf_new_from_file(tmp, NULL);
|
||||||
|
int width = gdk_pixbuf_get_width(buf);
|
||||||
|
int height = gdk_pixbuf_get_height(buf);
|
||||||
|
if(height > width) {
|
||||||
|
float percent = 32.f / height;
|
||||||
|
GdkPixbuf* tmp = gdk_pixbuf_scale_simple(buf, width * percent, 32, GDK_INTERP_BILINEAR);
|
||||||
|
g_object_unref(buf);
|
||||||
|
buf = tmp;
|
||||||
|
} else {
|
||||||
|
float percent = 32.f / width;
|
||||||
|
GdkPixbuf* tmp = gdk_pixbuf_scale_simple(buf, 32, height * percent, GDK_INTERP_BILINEAR);
|
||||||
|
g_object_unref(buf);
|
||||||
|
buf = tmp;
|
||||||
|
}
|
||||||
|
GtkWidget* img = gtk_image_new_from_pixbuf(buf);
|
||||||
|
gtk_container_add(GTK_CONTAINER(box), img);
|
||||||
|
} else if(strcmp(mode, "text") == 0) {
|
||||||
|
if(filter == NULL) {
|
||||||
|
filter = strdup(tmp);
|
||||||
|
} else {
|
||||||
|
char* tmp_filter = utils_concat(2, filter, tmp);
|
||||||
|
free(filter);
|
||||||
|
filter = tmp_filter;
|
||||||
|
}
|
||||||
|
GtkWidget* label = gtk_label_new(tmp);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 0);
|
||||||
|
gtk_container_add(GTK_CONTAINER(box), label);
|
||||||
|
}
|
||||||
|
mode = NULL;
|
||||||
|
}
|
||||||
|
tmp += strlen(tmp) + 1;
|
||||||
|
}
|
||||||
|
wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "filter", filter);
|
||||||
|
free(filter);
|
||||||
|
free(original);
|
||||||
|
} else {
|
||||||
|
wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "filter", text);
|
||||||
|
GtkWidget* label = gtk_label_new(text);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 0);
|
||||||
|
gtk_container_add(GTK_CONTAINER(box), label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean insert_widget(gpointer data) {
|
static gboolean insert_widget(gpointer data) {
|
||||||
struct node* node = data;
|
struct node* node = data;
|
||||||
GtkWidget* label = create_label(node->text, node->action);
|
GtkWidget* box = create_label(node->text, node->action);
|
||||||
gtk_container_add(node->container, label);
|
gtk_container_add(node->container, box);
|
||||||
gtk_widget_show(label);
|
gtk_widget_show_all(box);
|
||||||
free(node->text);
|
free(node->text);
|
||||||
free(node->action);
|
free(node->action);
|
||||||
free(node);
|
free(node);
|
||||||
@ -342,22 +396,22 @@ static void execute_action(char* mode, const gchar* cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_item(GtkListBox* box, GtkListBoxRow* row, gpointer data) {
|
static void activate_item(GtkListBox* list_box, GtkListBoxRow* row, gpointer data) {
|
||||||
(void) box;
|
(void) list_box;
|
||||||
(void) data;
|
(void) data;
|
||||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||||
execute_action(mode, wofi_property_label_get_property(WOFI_PROPERTY_LABEL(label), "action"));
|
execute_action(mode, wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_item(GtkListBox* box, GtkListBoxRow* row, gpointer data) {
|
static void select_item(GtkListBox* list_box, GtkListBoxRow* row, gpointer data) {
|
||||||
(void) box;
|
(void) list_box;
|
||||||
(void) data;
|
(void) data;
|
||||||
if(previous_selection != NULL) {
|
if(previous_selection != NULL) {
|
||||||
gtk_widget_set_name(previous_selection, "unselected");
|
gtk_widget_set_name(previous_selection, "unselected");
|
||||||
}
|
}
|
||||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||||
gtk_widget_set_name(label, "selected");
|
gtk_widget_set_name(box, "selected");
|
||||||
previous_selection = label;
|
previous_selection = box;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_search(GtkEntry* entry, gpointer data) {
|
static void activate_search(GtkEntry* entry, gpointer data) {
|
||||||
@ -366,15 +420,15 @@ static void activate_search(GtkEntry* entry, gpointer data) {
|
|||||||
execute_action(mode, gtk_entry_get_text(entry));
|
execute_action(mode, gtk_entry_get_text(entry));
|
||||||
} else {
|
} else {
|
||||||
GtkListBoxRow* row = gtk_list_box_get_row_at_y(GTK_LIST_BOX(inner_box), 0);
|
GtkListBoxRow* row = gtk_list_box_get_row_at_y(GTK_LIST_BOX(inner_box), 0);
|
||||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||||
execute_action(mode, wofi_property_label_get_property(WOFI_PROPERTY_LABEL(label), "action"));
|
execute_action(mode, wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean do_filter(GtkListBoxRow* row, gpointer data) {
|
static gboolean do_filter(GtkListBoxRow* row, gpointer data) {
|
||||||
(void) data;
|
(void) data;
|
||||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||||
const gchar* text = gtk_label_get_text(GTK_LABEL(label));
|
const gchar* text = wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "filter");
|
||||||
if(filter == NULL || strcmp(filter, "") == 0) {
|
if(filter == NULL || strcmp(filter, "") == 0) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -419,6 +473,7 @@ void wofi_init(struct map* config) {
|
|||||||
char* prompt = config_get(config, "prompt", mode);
|
char* prompt = config_get(config, "prompt", mode);
|
||||||
filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
||||||
filter_time = utils_get_time_millis();
|
filter_time = utils_get_time_millis();
|
||||||
|
allow_images = strcmp(config_get(config, "allow_images", "false"), "true") == 0;
|
||||||
|
|
||||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_widget_realize(window);
|
gtk_widget_realize(window);
|
||||||
|
Loading…
Reference in New Issue
Block a user