window with widgets and adjustable transparency

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

window with widgets and adjustable transparency

Gtk+ - General mailing list
Dear Sirs/Madams,

I am new in C programming and in GTK, I made a window with a timer, some buttons and a scalebar,
the scalebar is for adjusting the transaparency of the whole window but does not work and at this moment I am stuck, can you please have a look at the code and if you have any good idea how to do it, I will be very happy, thanks a lot,
Best regards: Pablo

#include <gtk/gtk.h>
 
 int seconds = 0;
 guint timerId = 0;
 GtkWidget *timer;
 static gdouble val = 0.5;
 
 
 
 gboolean timerTick(__attribute__((unused)) gpointer userData)
 {
     static GString *time = NULL;
 
     if(time == NULL)
     {
         time = g_string_sized_new(10);
     }
 
     seconds += 1;
     printf("Timer Tick %d \n",seconds);
   
     g_string_printf(time,"%02d:%02d",seconds/60,seconds%60);
     gtk_entry_set_text (GTK_ENTRY(timer),time->str);
     
     return TRUE;
 }
 
 void stopButtonClicked(__attribute__((unused)) GtkWidget *widget,
                        __attribute__((unused)) gpointer   data)
 {
     g_print("Stop Clicked\n");
     if(timerId != 0)
     {
         g_source_remove(timerId);
         timerId = 0;
     }
     else
         g_print("Not Running\n");
 }
 
 void startButtonClicked(__attribute__((unused)) GtkWidget *widget,
                         __attribute__((unused)) gpointer   data)
 {
     g_print("Start Clicked\n");
     if(timerId == 0)
         timerId = g_timeout_add(1000,timerTick,NULL);
     else
         g_print("Already Running\n");
 }
 
 void clearButtonClicked(__attribute__((unused)) GtkWidget *widget,
                         __attribute__((unused)) gpointer   data)
 {
     g_print("Clear Clicked\n");
     if(timerId == 0)
     {
         seconds = 0;
         gtk_entry_set_text (GTK_ENTRY(timer),"00:00");
     }
     else
         g_print("Ignored, Running\n");
 }
 

 void quitButtonClicked(__attribute__((unused)) GtkWidget *widget,
                        __attribute__((unused)) gpointer   data)
 {
     g_print("Quit Clicked\n");
     gtk_main_quit();
 }
 
// Handle the user trying to close the window
 gboolean windowDelete(__attribute__((unused)) GtkWidget *widget,
                       __attribute__((unused)) GdkEvent  *event,
                       __attribute__((unused)) gpointer   data)
 {
     g_print("%s called.\n",__FUNCTION__);
     return TRUE;    // Returning TRUE stops the window being deleted.
                     // Returning FALSE allows deletion.  
 }
 
 void value_changed(GtkRange *range, gpointer window) {
   
   val = gtk_range_get_value(range);
   gtk_widget_set_opacity (GTK_WIDGET (window), val);

}
 
 int main ( int argc, char **argv) {
     GtkWidget *window;
     GtkWidget *box;
     GtkWidget *hscale;
     
     GtkWidget *startButton;
     GtkWidget *stopButton;
     GtkWidget *clearButton;
     GtkWidget *quitButton;
 
 
     gtk_init(&argc , &argv);
 
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
     gtk_window_set_default_size(GTK_WINDOW(window), 300, 250);
     gtk_container_set_border_width(GTK_CONTAINER(window), 10);
     gtk_window_set_title(GTK_WINDOW(window), "Timer");
     
     box = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
     gtk_container_add(GTK_CONTAINER (window), box);
 
     timer = gtk_entry_new();
     gtk_entry_set_text(GTK_ENTRY(timer),"00:00");
 
     gtk_container_add(GTK_CONTAINER (box), timer);
     
     hscale = gtk_hscale_new_with_range(0, 1, 0.1);
   
     gtk_container_add(GTK_CONTAINER (box), hscale);
 
 
     startButton = gtk_button_new_with_label("START");
     gtk_container_add(GTK_CONTAINER (box), startButton);
 
     g_signal_connect(startButton, "clicked", G_CALLBACK (startButtonClicked), NULL);
 
     stopButton = gtk_button_new_with_label("STOP");
     gtk_container_add(GTK_CONTAINER (box), stopButton);
 
     g_signal_connect(stopButton, "clicked", G_CALLBACK (stopButtonClicked), NULL);
 
     clearButton = gtk_button_new_with_label("CLEAR");
     gtk_container_add(GTK_CONTAINER (box), clearButton);
 
     g_signal_connect(clearButton, "clicked", G_CALLBACK (clearButtonClicked), NULL);
 
     quitButton = gtk_button_new_with_label("QUIT");
     gtk_container_add(GTK_CONTAINER (box), quitButton);
 
     g_signal_connect(quitButton, "clicked", G_CALLBACK (quitButtonClicked), NULL);
     g_signal_connect(window, "delete_event", G_CALLBACK(windowDelete), NULL);
   
     g_signal_connect(hscale, "value-changed", G_CALLBACK(value_changed), NULL);
 
     gtk_widget_show_all (window);
     
     gtk_main ();
     return 0;
}

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: window with widgets and adjustable transparency

Rafal Luzynski
Hi Pablo,

30.07.2018 21:14 pablo andrade pereira via gtk-list <[hidden email]> wrote:
>
>  Dear Sirs/Madams,
>  
>  I am new in C programming and in GTK,[...]

You are welcome. :-)

>   [...]
>   void value_changed(GtkRange *range, gpointer window) {
>    
>     val = gtk_range_get_value(range);
>     gtk_widget_set_opacity (GTK_WIDGET (window), val);
>  
>  }
>  
>   [...]
>  
>       g_signal_connect(hscale, "value-changed", G_CALLBACK(value_changed),
> NULL);

This should be:

    g_signal_connect(hscale, "value-changed", G_CALLBACK(value_changed),
window);

The 4th argument of g_signal_connect() is the value which will be
passed later as the 2nd argument of the value_changed() callback,
that is also called window.

Once I did this change your program started working.

Few more remarks:

* The initial value of the hscale is 0 but the initial opacity
  of the window is not 0.
* It is wrong idea to set the initial opacity of the window to 0
  because the window would be invisible (fully transparent).
* The transparency/opacity setting works only if you use a compositing
  window manager (which handles translucent windows).
* Setting the window opacity before the window is shown (gtk_widget_show
  or gtk_widget_show_all) has no effect and may even disable setting
  the opacity in future. This is the bug which I have discovered
  recently and did not yet have time to report it.

Regards,

Rafal
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: window with widgets and adjustable transparency

Gtk+ - General mailing list
In reply to this post by Gtk+ - General mailing list

Hi Pablo,

If you have a window compositor you can draw with transparency. If you want your main window transparent and have a compositor, you can tell GTK that you are going to take care of drawing to the window. That may get you in a bit of trouble with some other widgets that expect a background drawn from the main window. Fun to draw with transparency though.

Eric


/*
    gcc -Wall transparent1.c -o transparent1 `pkg-config --cflags --libs gtk+-3.0`

    Tested on Ubuntu16.04 and GTK3.18
*/

#include<gtk/gtk.h>

//Alpha of the main window.
static gdouble alpha=0.0;

//Set alpha with the slider.
static void set_alpha(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer data);
//Draw the main window transparent and paned window cyan.
static gboolean draw_main_window(GtkWidget *window, cairo_t *cr, gpointer data);
//The drawing area.
static gboolean draw_da(GtkWidget *da, cairo_t *cr, gpointer data);

int main(int argc, char **argv)
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Tranparency");
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 500);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_set_app_paintable(window, TRUE);
    //Try to set transparency of main window.
    GdkScreen *screen=gtk_widget_get_screen(window); 
    if(gdk_screen_is_composited(screen))
      {
        GdkVisual *visual=gdk_screen_get_rgba_visual(screen);
        gtk_widget_set_visual(window, visual);
      }
    else g_print("Can't set window transparency.\n");

    GtkWidget *da=gtk_drawing_area_new();
    gtk_widget_set_hexpand(da, TRUE);
    gtk_widget_set_vexpand(da, TRUE);
    g_signal_connect(da, "draw", G_CALLBACK(draw_da), NULL);

    GtkWidget *alpha_label=gtk_label_new("Alpha");
    gtk_widget_set_hexpand(alpha_label, TRUE);
   
    GtkWidget *alpha_slider=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, 0.0, 1.0, 0.01);
    gtk_widget_set_vexpand(alpha_slider, TRUE);
    gtk_range_set_value(GTK_RANGE(alpha_slider), 0.0);
    g_signal_connect(alpha_slider, "change-value", G_CALLBACK(set_alpha), da);  

    GtkWidget *grid1=gtk_grid_new();
    gtk_container_set_border_width(GTK_CONTAINER(grid1), 15);
    gtk_grid_set_row_spacing(GTK_GRID(grid1), 8);   
    gtk_grid_attach(GTK_GRID(grid1), alpha_label, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid1), alpha_slider, 0, 1, 1, 1);

    GtkWidget *scroll=gtk_scrolled_window_new(NULL, NULL);
    gtk_widget_set_hexpand(scroll, TRUE);
    gtk_widget_set_vexpand(scroll, TRUE);
    gtk_container_add(GTK_CONTAINER(scroll), grid1);
  
    GtkWidget *paned1=gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_paned_pack1(GTK_PANED(paned1), scroll, TRUE, TRUE);
    gtk_paned_pack2(GTK_PANED(paned1), da, TRUE, TRUE);
    gtk_paned_set_position(GTK_PANED(paned1), 250);

    g_signal_connect(window, "draw", G_CALLBACK(draw_main_window), paned1);
  
    gtk_container_add(GTK_CONTAINER(window), paned1);
   
    gtk_widget_show_all(window);

    gtk_main();

    return 0; 
  }
static void set_alpha(GtkRange *range, GtkScrollType scroll, gdouble value, gpointer data)
  {
    alpha=value;
    gtk_widget_queue_draw(GTK_WIDGET(data));
  }
static gboolean draw_main_window(GtkWidget *window, cairo_t *cr, gpointer data)
  {
    //Paint backing window.
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, alpha);
    cairo_paint(cr);

    //Paint paned window.
    cairo_set_source_rgba(cr, 0.0, 1.0, 1.0, 1.0);
    gint width=gtk_paned_get_position(GTK_PANED(data));
    gint height=gtk_widget_get_allocated_height(window);

    cairo_rectangle(cr, 0.0, 0.0, width, height);
    cairo_fill(cr);
    cairo_set_source_rgba(cr, 1.0, 1.0, 0.0, 1.0);
    cairo_rectangle(cr, width, 0.0, 10, height);
    cairo_fill(cr);

    return FALSE;
  }
//The top drawing function.
static gboolean draw_da(GtkWidget *da, cairo_t *cr, gpointer data)
  {
    gdouble width=(gdouble)gtk_widget_get_allocated_width(da);
    gdouble height=(gdouble)gtk_widget_get_allocated_height(da);
    gdouble w1=1.0*width/10.0;
    gdouble h1=1.0*height/10.0;

    //Paint background transparent.
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
    cairo_paint(cr);

    //Cartesian coordinates for drawing.
    cairo_set_line_width(cr, 3.0);
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
    cairo_rectangle(cr, w1, h1, 8.0*w1, 8.0*h1);
    cairo_stroke(cr);
    cairo_move_to(cr, 1.0*w1, 5.0*h1);
    cairo_line_to(cr, 9.0*w1, 5.0*h1);
    cairo_stroke(cr);
    cairo_move_to(cr, 5.0*w1, 1.0*h1);
    cairo_line_to(cr, 5.0*w1, 9.0*h1);
    cairo_stroke(cr);

    //Draw a circle in the center.
    cairo_translate(cr, width/2.0, height/2.0);     
    cairo_set_source_rgba(cr, 1.0, 0.0, 1.0, 1.0);
    cairo_arc (cr, 0.0, 0.0, 2.5*w1, 0.0, 2.0*G_PI);
    cairo_fill(cr);
 
    return FALSE;
  }




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list