How to apply transparency to text in GTK2 widgets? - c

I've been playing around with Xfce 4.12, which uses GTK2, and I would like to make taskbar buttons to have semi-transparent text when their respective windows are minimized. Here's the original code:
xfce_tasklist_button_name_changed (WnckWindow *window, XfceTasklistChild *child)
{
const gchar *name;
gchar *label = NULL;
panel_return_if_fail (window == NULL || child->window == window);
panel_return_if_fail (WNCK_IS_WINDOW (child->window));
panel_return_if_fail (XFCE_IS_TASKLIST (child->tasklist));
name = wnck_window_get_name (child->window);
gtk_widget_set_tooltip_text (GTK_WIDGET (child->button), name);
if (!child->tasklist->only_minimized && wnck_window_is_minimized (child->window))
name = label = g_strdup_printf ("[%s]", name);
else if (wnck_window_is_shaded (child->window))
name = label = g_strdup_printf ("=%s=", name);
gtk_label_set_text (GTK_LABEL (child->label), name);
g_free (label);
if (window != NULL)
xfce_tasklist_sort (child->tasklist);
}
I tried countless things, but I failed to find a way to apply alpha to the text in the widget.
Interesting to notice that the icons next to the text have alpha using pixbuf, which I guess doesn't work for text in widgets:
XfceTasklist *tasklist = child->tasklist;
GdkPixbuf *pixbuf = wnck_window_get_icon (window);
GdkPixbuf *lucent = lucent = exo_gdk_pixbuf_lucent (pixbuf, tasklist->minimized_icon_lucency);
if (G_UNLIKELY (lucent != NULL))
pixbuf = lucent;
xfce_panel_image_set_from_pixbuf (XFCE_PANEL_IMAGE (child->icon), pixbuf);

Related

GTK - Cannot print buffer value using function `printf`

I get the contents of my textview and I want to display the contents in the terminal using the printf function. But have stange symbols (Why?):
// get textbuffer from textview end print value in terminal
void on_lower_button_clicked(GtkWidget *lower_button, GtkTextView *textview_1)
{
GtkTextBuffer *textbuffer_1;
textbuffer_1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview_1));
printf("%s\n", textbuffer_1); // strange symbols from my buffer ...
}
int main(int argc, char *argv[])
{
GtkWidget *lower_button;
GtkBuilder *builder;
GtkWidget *window;
GError *error = NULL;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
if(!gtk_builder_add_from_file(builder, "template.ui", &error)) {
g_printerr("Error loading file: %s\n", error->message);
g_clear_error(&error);
return 1;
}
window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
lower_button = GTK_WIDGET(gtk_builder_get_object(builder, "lower_button"));
gtk_builder_connect_signals(builder, NULL);
// when I click on the button (lower_button) call
// on_lower_button_clicked function and transferred to her textview_1
g_object_unref(G_OBJECT(builder));
gtk_widget_show(window);
gtk_main();
return 0;
}
GtkTextBuffer is not a character array, it is a GTK object that can not be simply printed as text.
You need to extract the text from it if you want to print it or write it to file.
To do this, you will need to get a couple of GtkTextIter objects, and then use gtk_text_buffer_get_text.
Note, that if you have non English characters in your text, you may still have issues using printf, because the resulting text is UTF-8 encoded.
Here is an example code:
GtkTextIter start, end;
gchar *text;
gtk_text_buffer_get_start_iter(textview_1, &start);
gtk_text_buffer_get_end_iter(textview_1, &end);
text = gtk_text_buffer_get_text(textview_1, &start, &end, FALSE);
printf("%s\n",text);
g_free(text); //you need to clean up this buffer!

how to parse image between GstBuffer and Mat in Gstreamer Plugin chain function

I'm trying to implement a Gstreamer plugin _chain function based on its template, which simply replaces the input video frame(BGRx) to my converted image in the same size, shown as below:
static GstFlowReturn gst_myplugin_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) {
Gstmyplugin *filter;
filter = GST_MYPLUGIN (parent);
if(filter->silent == FALSE)
g_print("I'm plugged, therefore I'm in. \n");
// retrieve pass-in image frame from input buf
GstMapInfo map;
gst_buffer_map(buf, &map, GST_MAP_READ);
cv::Mat frame(cv::Size(width, height), CV_8UC4, (char *)map.data, cv::Mat::AUTOSTEP); //Q1
// check the orignal frame
cv::imshow("Input image", frame); //Q2
// convert to new image by same size
cv::Mat out = my_convert(frame);
// how to populate output buffer from Mat out then
GstBuffer *out_buf = ??? //Q3
//return gst_pad_push(filter->srcpad, buf); transparent filter in plugin template
return gst_pad_push(filer->srcpad, out_buf); //send my converted image
}
So there are three questions(also marked in above lines):
Q1: how to get input image's width and height ?
Q2: why the parsed image can't be shown properly as those in the video ?
Q3: how to populate the output buffer ?
I've searched a lots online for days, but still can't get them solved yet.
Q1: how to get input image's width and height ?
This is done in the gst_my_filter_sink_event function when it receives the GST_EVENT_CAPS, from which you can get the height/width. Note that I added height and width variables to the filter class.
/* this function handles sink events */
static gboolean
gst_my_filter_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{
GstMyFilter *filter;
gboolean ret;
filter = GST_MYFILTER (parent);
GST_LOG_OBJECT (filter, "Received %s event: %" GST_PTR_FORMAT,
GST_EVENT_TYPE_NAME (event), event);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
/* do something with the caps */
GstStructure *caps_struct = gst_caps_get_structure(caps, 0);
if( !caps_struct) {
g_warning("caps have NULL structure");
}
if( !gst_structure_get_int(caps_struct, "width", &filter->width) ||
!gst_structure_get_int(caps_struct, "height", &filter->height)) {
g_warning("caps have no HEIGHT, WIDTH");
}
const gchar* format = gst_structure_get_string(caps_struct, "format");
g_info("height: %d, width: %d, format: %s", filter->height, filter->width, format);
/* and forward */
ret = gst_pad_event_default (pad, parent, event);
break;
}
default:
ret = gst_pad_event_default (pad, parent, event);
break;
}
return ret;
}

How to load GdkPixbuf from file in a callback function?

I'm using gtk+ 3.14 and I want to load a picture that the user chooses.
The code here correctly displays the picture but doest not seem to update
the GdkPixbuf *pixbuf. In fact, GdkPixbuf is not NULL inside the function but it
is NULL outside it. What can I do to correctly load and use pixbuf in other functions ?
Here is the callback structure :
struct callback_struct
{
GdkPixbuf *pix;
GtkWidget *img;
int height;
int width;
float scale;
};
Here is my code :
void callback_load(gpointer data)
{
struct callback_struct *passed = data;
GdkPixbuf *pixbuf = passed->pix;
GtkWidget *image = passed->img;
int h_scr = passed ->height;
int w_scr = passed->width;
float scale = passed->scale;
GtkWidget *dial_box = gtk_file_chooser_dialog_new("Choose the image to load"
,GTK_WINDOW(gtk_widget_get_toplevel(image)),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel",GTK_RESPONSE_CANCEL,"Open",GTK_RESPONSE_ACCEPT,NULL);
switch (gtk_dialog_run (GTK_DIALOG (dial_box)))
{
case GTK_RESPONSE_ACCEPT:
{
gchar *filename =gtk_file_chooser_get_filename
(GTK_FILE_CHOOSER (dial_box));
pixbuf = gdk_pixbuf_new_from_file(filename,NULL);
printf("%d\n",(pixbuf == 0));
GdkPixbuf *scaled_buffer = gdk_pixbuf_scale_simple
(pixbuf,h_scr*scale,w_scr*scale,GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(image),scaled_buffer);
printf("%d\n",(pixbuf == 0));
gtk_widget_destroy(dial_box);
break;
}
case GTK_RESPONSE_CANCEL:
{
gtk_widget_destroy(dial_box);
break;
}
}
}
You only modify the local pointer pixbuf: in fact passed->pix is NULL throughout the code.
You should either not use a local pointer at all (and just refer to passed->pix) , or alternatively set the structs pointer equal to the local pointer at some point after initializing it.

Optimise queries file information and attributes inside of function called at regular intervals

I'm developing an application that records audio files with GStreamer.
One feature of this app is to display a GTK dialog with a label
that contains information about the file recording process (name, type and size).
code:
static int timeout_id = -1;
static GtkWidget *file_label, *type_label, *size_label;
static gboolean timeout_cb(gpointer data)
{
GFile *session_file;
GFileInfo *info;
session_file = g_file_new_for_path (path);
info = g_file_query_info (session_file,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
G_FILE_ATTRIBUTE_STANDARD_SIZE,
G_FILE_QUERY_INFO_NONE,
NULL,
NULL);
if (info != NULL) {
/* name */
const gchar *display_name = g_file_info_get_attribute_string (info,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
gtk_label_set_text (GTK_LABEL (file_label), display_name);
/* type */
const gchar *type = g_file_info_get_attribute_string (info,
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
gtk_label_set_text (GTK_LABEL (type_label), type);
/* size */
guint64 size = g_file_info_get_attribute_uint64 (info,
G_FILE_ATTRIBUTE_STANDARD_SIZE);
gchar *tmp = g_format_size_full (size, G_FORMAT_SIZE_LONG_FORMAT);
gtk_label_set_text (GTK_LABEL (size_label), tmp);
g_free (tmp);
g_object_unref (info);
}
g_object_unref (file);
return TRUE;
}
void run_status_window(Record *record)
{
timeout_id = g_timeout_add(500, (GSourceFunc) timeout_cb, record);
}
I'm use queries for file information and attributes and calling this at 500 ms intervals.
My question is how can optimise this feature because the name and type aren't likely to change during the recording process.
Thanks

gtk+ text editor vim type modes (insert / command)

I'm trying to incorporate vim like functionality in a text editor I am creating in gtk+ 2.0 and gtksourceview 2.0. I have it working except when I press "i" to enter insert mode it enters this mode properly, but then it types an "i" in the text buffer. Here is my keypress function which is setup to enter command mode (leave insert mode) when the esc key is hit, and as I said before enter insert mode when the i key is pressed:
gboolean on_key_press_win_main (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
switch (event->keyval)
{
case GDK_i:
if (event->state & GDK_CONTROL_MASK)
{
printf("key pressed: %s\n", "ctrl + i");
}
else
{
GtkTextBuffer *tbuffer;
GtkTextView *text_view;
int page = 0;
gchar *msg;
gint row, col;
GtkTextIter iter;
page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
tbuffer = gtk_text_view_get_buffer (text_view);
if (insert_mode == 0)
{
insert_mode = 1;
command_mode = 0;
/* update statusbar */
gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0);
gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));
row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);
msg = g_strdup_printf("INSERT\t\t Col %d Ln %d", col+1, row+1);
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
gtk_text_view_set_editable (text_view, TRUE);
}
}
break;
/* esc key */
case 65307:
{
GtkTextBuffer *tbuffer;
GtkTextView *text_view;
int page = 0;
gchar *msg;
gint row, col;
GtkTextIter iter;
page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
tbuffer = gtk_text_view_get_buffer (text_view);
insert_mode = 0;
command_mode = 1;
gtk_text_view_set_editable (text_view, FALSE);
/* update statusbar */
gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0);
gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));
row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);
msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
}
break;
default:
return FALSE;
}
return FALSE;
}
As you can see gtk_text_view_set_editable (text_view, FALSE) is set when entering command mode, and gtk_text_view_set_editable (text_view, TRUE) is set when entering insert mode. However, when entering insert mode the text_view is set editable before the keystroke registers in the buffer even if it is the last command in the keypress case. How can I keep the i from being placed in the text buffer when entering insert mode?
Return TRUE from the event handler instead of FALSE to block any further processing of the event. Event handlers work like a filter, you filter out the keystrokes that you don't want to pass on to the textview.
PS. Don't use constants like 65307, use GDK_KEY_Escape or whatever it is.
Wouldn't you know it, as soon as I finished writing this question a viable option pops into my head. This is probably why the key_release_event was created. Worked like a charm.

Resources