Added support for inline images, this currently only works in dmenu mode

This commit is contained in:
Scoopta 2019-08-27 23:15:18 -07:00
parent 34681ca8f9
commit e3c79c3bd4
8 changed files with 164 additions and 89 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -19,7 +19,7 @@
#include <map.h>
#include <config.h>
#include <property_label.h>
#include <property_box.h>
#include <errno.h>
#include <stddef.h>

View File

@ -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
View 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);
}

View File

@ -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);
}

View File

@ -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);