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/main.c \
|
||||
../src/map.c \
|
||||
../src/property_label.c \
|
||||
../src/property_box.c \
|
||||
../src/utils.c \
|
||||
../src/wofi.c
|
||||
|
||||
@ -15,7 +15,7 @@ OBJS += \
|
||||
./src/config.o \
|
||||
./src/main.o \
|
||||
./src/map.o \
|
||||
./src/property_label.o \
|
||||
./src/property_box.o \
|
||||
./src/utils.o \
|
||||
./src/wofi.o
|
||||
|
||||
@ -23,7 +23,7 @@ C_DEPS += \
|
||||
./src/config.d \
|
||||
./src/main.d \
|
||||
./src/map.d \
|
||||
./src/property_label.d \
|
||||
./src/property_box.d \
|
||||
./src/utils.d \
|
||||
./src/wofi.d
|
||||
|
||||
|
@ -7,7 +7,7 @@ C_SRCS += \
|
||||
../src/config.c \
|
||||
../src/main.c \
|
||||
../src/map.c \
|
||||
../src/property_label.c \
|
||||
../src/property_box.c \
|
||||
../src/utils.c \
|
||||
../src/wofi.c
|
||||
|
||||
@ -15,7 +15,7 @@ OBJS += \
|
||||
./src/config.o \
|
||||
./src/main.o \
|
||||
./src/map.o \
|
||||
./src/property_label.o \
|
||||
./src/property_box.o \
|
||||
./src/utils.o \
|
||||
./src/wofi.o
|
||||
|
||||
@ -23,7 +23,7 @@ C_DEPS += \
|
||||
./src/config.d \
|
||||
./src/main.d \
|
||||
./src/map.d \
|
||||
./src/property_label.d \
|
||||
./src/property_box.d \
|
||||
./src/utils.d \
|
||||
./src/wofi.d
|
||||
|
||||
|
@ -15,19 +15,19 @@
|
||||
along with Wofi. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROPERTY_LABEL_H
|
||||
#define PROPERTY_LABEL_H
|
||||
#ifndef PROPERTY_BOX_H
|
||||
#define PROPERTY_BOX_H
|
||||
#include <map.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define WOFI_TYPE_PROPERTY_LABEL wofi_property_label_get_type()
|
||||
G_DECLARE_FINAL_TYPE(WofiPropertyLabel, wofi_property_label, WOFI, PROPERTY_LABEL, GtkLabel);
|
||||
#define WOFI_TYPE_PROPERTY_BOX wofi_property_box_get_type()
|
||||
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
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <map.h>
|
||||
#include <config.h>
|
||||
#include <property_label.h>
|
||||
#include <property_box.h>
|
||||
|
||||
#include <errno.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("--yoffset\t-y\tThe y offset\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);
|
||||
}
|
||||
|
||||
@ -242,6 +243,12 @@ int main(int argc, char** argv) {
|
||||
.flag = NULL,
|
||||
.val = 'n'
|
||||
},
|
||||
{
|
||||
.name = "allow-images",
|
||||
.has_arg = no_argument,
|
||||
.flag = NULL,
|
||||
.val = 'i'
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.has_arg = 0,
|
||||
@ -260,8 +267,9 @@ int main(int argc, char** argv) {
|
||||
char* x = NULL;
|
||||
char* y = NULL;
|
||||
char* normal_window = NULL;
|
||||
char* allow_images = NULL;
|
||||
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) {
|
||||
case 'h':
|
||||
print_usage(argv);
|
||||
@ -307,6 +315,9 @@ int main(int argc, char** argv) {
|
||||
case 'n':
|
||||
normal_window = "true";
|
||||
break;
|
||||
case 'i':
|
||||
allow_images = "true";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,6 +411,9 @@ int main(int argc, char** argv) {
|
||||
if(normal_window != NULL) {
|
||||
map_put(config, "normal_window", normal_window);
|
||||
}
|
||||
if(allow_images != NULL) {
|
||||
map_put(config, "allow_images", allow_images);
|
||||
}
|
||||
|
||||
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 time_t filter_time;
|
||||
static int64_t filter_rate;
|
||||
static bool allow_images;
|
||||
|
||||
struct node {
|
||||
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));
|
||||
}
|
||||
|
||||
static GtkWidget* create_label(const char* text, char* action) {
|
||||
GtkWidget* label = wofi_property_label_new(text);
|
||||
gtk_widget_set_name(label, "unselected");
|
||||
wofi_property_label_add_property(WOFI_PROPERTY_LABEL(label), "action", action);
|
||||
gtk_label_set_xalign(GTK_LABEL(label), 0);
|
||||
return label;
|
||||
static GtkWidget* create_label(char* text, char* action) {
|
||||
GtkWidget* box = wofi_property_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_name(box, "unselected");
|
||||
wofi_property_box_add_property(WOFI_PROPERTY_BOX(box), "action", action);
|
||||
if(allow_images) {
|
||||
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) {
|
||||
struct node* node = data;
|
||||
GtkWidget* label = create_label(node->text, node->action);
|
||||
gtk_container_add(node->container, label);
|
||||
gtk_widget_show(label);
|
||||
GtkWidget* box = create_label(node->text, node->action);
|
||||
gtk_container_add(node->container, box);
|
||||
gtk_widget_show_all(box);
|
||||
free(node->text);
|
||||
free(node->action);
|
||||
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) {
|
||||
(void) box;
|
||||
static void activate_item(GtkListBox* list_box, GtkListBoxRow* row, gpointer data) {
|
||||
(void) list_box;
|
||||
(void) data;
|
||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
||||
execute_action(mode, wofi_property_label_get_property(WOFI_PROPERTY_LABEL(label), "action"));
|
||||
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||
execute_action(mode, wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
|
||||
}
|
||||
|
||||
static void select_item(GtkListBox* box, GtkListBoxRow* row, gpointer data) {
|
||||
(void) box;
|
||||
static void select_item(GtkListBox* list_box, GtkListBoxRow* row, gpointer data) {
|
||||
(void) list_box;
|
||||
(void) data;
|
||||
if(previous_selection != NULL) {
|
||||
gtk_widget_set_name(previous_selection, "unselected");
|
||||
}
|
||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
||||
gtk_widget_set_name(label, "selected");
|
||||
previous_selection = label;
|
||||
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||
gtk_widget_set_name(box, "selected");
|
||||
previous_selection = box;
|
||||
}
|
||||
|
||||
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));
|
||||
} else {
|
||||
GtkListBoxRow* row = gtk_list_box_get_row_at_y(GTK_LIST_BOX(inner_box), 0);
|
||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
||||
execute_action(mode, wofi_property_label_get_property(WOFI_PROPERTY_LABEL(label), "action"));
|
||||
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||
execute_action(mode, wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "action"));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean do_filter(GtkListBoxRow* row, gpointer data) {
|
||||
(void) data;
|
||||
GtkWidget* label = gtk_bin_get_child(GTK_BIN(row));
|
||||
const gchar* text = gtk_label_get_text(GTK_LABEL(label));
|
||||
GtkWidget* box = gtk_bin_get_child(GTK_BIN(row));
|
||||
const gchar* text = wofi_property_box_get_property(WOFI_PROPERTY_BOX(box), "filter");
|
||||
if(filter == NULL || strcmp(filter, "") == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
@ -419,6 +473,7 @@ void wofi_init(struct map* config) {
|
||||
char* prompt = config_get(config, "prompt", mode);
|
||||
filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
||||
filter_time = utils_get_time_millis();
|
||||
allow_images = strcmp(config_get(config, "allow_images", "false"), "true") == 0;
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_realize(window);
|
||||
|
Loading…
Reference in New Issue
Block a user