How to make placeholder text of a Gtk.SearchEntry visible even if the entry is focused? - gtk

The search entry appears when a menu button is clicked. But the problem is that, it gets automatically focused and as a result, the placeholder text is not visible. I want the placeholder text to be always visible, even when the entry is focused.
Feel free to post the solutions using any language you want but vala is preferred.
Thank you

Until you find a better solution, this is what I'll do in this case:
create an entry buffer
set the buffer on that entry
set cursor position at the end of the buffer (optional)
select the whole region text (probably this is what you need)
Now what I did was to connect the button to the "toggled" signal and put all that information in the callback, feel free to adjust it for your needs:
#include <gtk/gtk.h>
static void toggled_clbk ( GtkWidget *button, GtkWidget *search_entry )
{
g_return_if_fail ( GTK_IS_TOGGLE_BUTTON ( button ) );
g_return_if_fail ( GTK_IS_SEARCH_ENTRY ( search_entry ) );
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( button ) ) )
{
/// ***
GtkEntryBuffer *buffer;
/// ***
buffer = gtk_entry_buffer_new ( "Type here...", -1 );
/// ***
gtk_entry_set_buffer ( GTK_ENTRY ( search_entry ), buffer );
/// ***
///gtk_editable_set_position ( GTK_EDITABLE ( search_entry ), -1 );
gtk_editable_select_region ( GTK_EDITABLE ( search_entry ), 0, -1 );
/// ***
g_object_unref ( buffer );
}
}
int main ( void )
{
GtkWidget *window;
GtkWidget *box;
GtkWidget *search_box;
GtkWidget *search_button;
GtkWidget *search_bar;
GtkWidget *search_entry;
/// ***
gtk_init ( NULL, NULL );
/// ***
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_widget_set_size_request ( window, 300, -1 );
/// ***
g_signal_connect ( window, "destroy", gtk_main_quit, NULL );
/// ***
box = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, 5 );
gtk_container_add ( GTK_CONTAINER ( window ), box );
gtk_container_set_border_width ( GTK_CONTAINER ( box ), 0 );
/// ***
search_entry = gtk_search_entry_new ();
/// ***
search_box = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, 10 );
gtk_box_pack_start ( GTK_BOX ( search_box ), search_entry, FALSE, FALSE, 0 );
/// ***
search_bar = gtk_search_bar_new ();
gtk_search_bar_connect_entry ( GTK_SEARCH_BAR ( search_bar ), GTK_ENTRY ( search_entry ) );
/// ***
gtk_container_add ( GTK_CONTAINER ( search_bar ), search_box );
gtk_box_pack_end ( GTK_BOX ( box ), search_bar, FALSE, FALSE, 0 );
/// ***
search_button = gtk_toggle_button_new_with_label ( "Search" );
g_object_bind_property ( search_button, "active", search_bar, "search-mode-enabled", G_BINDING_BIDIRECTIONAL );
/// ***
gtk_box_pack_start ( GTK_BOX ( box ), search_button, TRUE, TRUE, 0 );
/// ***
g_signal_connect ( search_button, "toggled", G_CALLBACK ( toggled_clbk ), search_entry );
/// ***
gtk_widget_show_all ( window );
/// ***
gtk_main();
}
As a result, once that you click the search button and the search bar gets revealed you will have something like this:
Before you click the button:
After you click the button:

Related

TreeView or ListView without column title bar

Is there a way to show data in TreeView or ListView without column title bar?
When you talk about column title bar without showing any code makes me think that you are asking about Header.
If so, then this is the function you need:
gtk_tree_view_set_headers_visible()
Here is with headers_visible set to TRUE (which is default):
And here is with headers_visible set to FALSE:
And here is an example Code:
#include <gtk/gtk.h>
GtkWidget *create_window ( void );
GtkWidget *create_scrolled_window ( void );
GtkWidget *create_tree_view ( void );
GtkListStore *create_list_store ( void );
int main ( void )
{
GtkWidget *window;
GtkWidget *scrolled_window;
GtkWidget *tree_view;
/// ***
gtk_init ( NULL, NULL );
/// ***
window = create_window();
/// ***
///scrolled_window = gtk_scrolled_window_new ( NULL, NULL );
scrolled_window = create_scrolled_window ( );
gtk_scrolled_window_set_kinetic_scrolling ( GTK_SCROLLED_WINDOW ( scrolled_window ), TRUE );
gtk_scrolled_window_set_capture_button_press ( GTK_SCROLLED_WINDOW ( scrolled_window ), TRUE );
/// ***
tree_view = create_tree_view ( );
gtk_container_add ( GTK_CONTAINER ( scrolled_window ), tree_view );
gtk_container_add ( GTK_CONTAINER ( window ), scrolled_window );
/// ***
gtk_widget_show_all ( window );
// ***
gtk_widget_show_all ( window );
gtk_main ();
}
GtkWidget *create_window ( void )
{
GtkWidget *window;
/// ***
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size ( GTK_WINDOW ( window ), 150, 150 );
gtk_container_set_border_width ( GTK_CONTAINER ( window ), 5 );
/// ***
g_signal_connect ( window, "delete_event", G_CALLBACK ( gtk_main_quit ), NULL );
/// ***
return window;
}
GtkWidget *create_scrolled_window ( void )
{
GtkWidget *scrolled_window;
/// ***
scrolled_window = gtk_scrolled_window_new ( NULL, NULL );
gtk_scrolled_window_set_kinetic_scrolling ( GTK_SCROLLED_WINDOW ( scrolled_window ), TRUE );
gtk_scrolled_window_set_capture_button_press ( GTK_SCROLLED_WINDOW ( scrolled_window ), TRUE );
/// ***
return scrolled_window;
}
GtkListStore *create_list_store ( void )
{
GtkListStore *list_store;
list_store = gtk_list_store_new ( 1, G_TYPE_STRING );
/// ***
for ( gint i = 0; i < 10; i++ )
{
GtkTreeIter iter;
gchar *label = g_strdup_printf ( "Row number %d", i );
/// ***
gtk_list_store_append ( list_store, &iter );
gtk_list_store_set ( list_store, &iter, 0, label, -1 );
/// ***
g_free ( label );
}
return list_store;
}
GtkWidget *create_tree_view ( void )
{
GtkWidget *tree_view;
GtkCellRenderer *renderer;
GtkListStore *store;
/// ***
tree_view = gtk_tree_view_new ();
store = create_list_store();
/// ***
renderer = gtk_cell_renderer_text_new ();
g_object_set ( renderer, "editable", TRUE, NULL );
/// **
gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW ( tree_view ),
0, "This is the Title",
renderer,
"text", 0,
NULL );
/// ***
gtk_tree_view_set_model ( GTK_TREE_VIEW ( tree_view ), GTK_TREE_MODEL ( store ) );
g_object_unref ( store );
/// ***
gtk_tree_view_set_headers_visible ( GTK_TREE_VIEW ( tree_view ), FALSE );
/// ***
return tree_view;
}

how to auto scroll the scrollbar to bottom when window get minimized

I am working on a project which has to be in GTK-2.0 and the problem I am facing is that If the window gets Minimized after being Maximized the scrollbar does not goes back the bottom anymore.
Here is a part of the code which could be seen and tested:
#include <gtk/gtk.h>
typedef struct
{
GtkWidget *entry;
GtkWidget *textview;
} Widgets;
void chatMSG ( GtkButton *, Widgets * );
int main ( void )
{
GtkWidget *window, *scrolled_win, *hbox, *vbox, *button;
Widgets *widg = g_slice_new ( Widgets );
/// ***
gtk_init ( NULL, NULL );
/// ***
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
g_signal_connect ( G_OBJECT ( window ), "delete_event", gtk_main_quit, NULL );
gtk_window_set_title ( GTK_WINDOW ( window ), "WhatsChat" );
gtk_container_set_border_width ( GTK_CONTAINER ( window ), 10 );
gtk_widget_set_size_request ( window, 250, 200 );
/// ***
widg->textview = gtk_text_view_new();
gtk_text_view_set_editable ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
/// ***
widg->entry = gtk_entry_new();
button = gtk_button_new_with_label ( "Send" );
/// ***
g_signal_connect ( G_OBJECT ( button ), "clicked", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
g_signal_connect ( G_OBJECT ( widg->entry ), "activate", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
/// ***
scrolled_win = gtk_scrolled_window_new ( NULL, NULL );
gtk_widget_set_size_request ( scrolled_win, -1, 200 );
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
gtk_container_add ( GTK_CONTAINER ( scrolled_win ), widg->textview );
/// ***
hbox = gtk_hbox_new ( FALSE, 5 );
gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), widg->entry );
gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), button );
/// ***
vbox = gtk_vbox_new ( FALSE, 5 );
gtk_box_pack_start ( GTK_BOX ( vbox ), scrolled_win, TRUE, TRUE, 0 );
gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, TRUE, 0 );
/// ***
gtk_container_add ( GTK_CONTAINER ( window ), vbox );
gtk_widget_show_all ( window );
gtk_main();
}
void chatMSG ( GtkButton *button, Widgets *widg )
{
( void ) button;
GtkTextBuffer *buffer;
GtkTextMark *mark;
GtkTextIter iter, start, end;
const gchar *text;
/// ***
buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW ( widg->textview ) );
text = gtk_entry_get_text ( GTK_ENTRY ( widg->entry ) );
/// ***
mark = gtk_text_buffer_get_insert ( buffer );
gtk_text_buffer_get_iter_at_mark ( buffer, &iter, mark );
gtk_text_buffer_get_bounds ( buffer, &start, &end );
if ( gtk_text_buffer_get_char_count ( buffer ) && strlen( text ) > 0 )
{
gtk_text_buffer_insert ( buffer, &iter, "\n", -1 );
}
gtk_text_buffer_insert ( buffer, &iter, text, -1 );
gtk_entry_set_text ( GTK_ENTRY ( widg->entry ), "" );
/// ***
mark = gtk_text_buffer_create_mark ( buffer, NULL, &iter, FALSE );
gtk_text_view_scroll_mark_onscreen ( GTK_TEXT_VIEW ( widg->textview ), mark );
gtk_text_buffer_delete_mark ( buffer, mark );
}
My guess is that somehow I mixed up things in the chatMSG() Funcion.
How do I keep the scrollbar at a bottom after user minimize the Window?
I also tried the following:
GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_win ) );
gtk_adjustment_set_value ( adj, adj->upper );
But it is not working too.
After a lot of search and trying different things which did not helped I searched help by Gnome-Team and managed to fix it.
I decided to share this here two, because it could help in the future other too.
Here is an working example:
#include <gtk/gtk.h>
typedef struct
{
GtkWidget *entry;
GtkWidget *textview;
} Widgets;
void chatMSG ( GtkButton *, Widgets * );
void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data );
void scroll_bottom_gravity ( GtkWidget *scrolled_window, gpointer user_data );
int main ( void )
{
GtkWidget *window, *scrolled_win, *hbox, *vbox, *button;
Widgets *widg = g_slice_new ( Widgets );
double from_bottom = 0.0;
/// ***
gtk_init ( NULL, NULL );
/// ***
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
g_signal_connect ( G_OBJECT ( window ), "delete_event", gtk_main_quit, NULL );
gtk_window_set_title ( GTK_WINDOW ( window ), "WhatsChat" );
gtk_container_set_border_width ( GTK_CONTAINER ( window ), 10 );
gtk_widget_set_size_request ( window, 250, 200 );
/// ***
widg->textview = gtk_text_view_new();
gtk_text_view_set_editable ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
/// ***
widg->entry = gtk_entry_new();
button = gtk_button_new_with_label ( "Send" );
/// ***
g_signal_connect ( G_OBJECT ( button ), "clicked", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
g_signal_connect ( G_OBJECT ( widg->entry ), "activate", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
/// ***
scrolled_win = gtk_scrolled_window_new ( NULL, NULL );
gtk_widget_set_size_request ( scrolled_win, -1, 200 );
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_win ) );
g_signal_connect ( scrolled_win, "size-allocate", ( GCallback ) scroll_bottom_gravity, &from_bottom );
g_signal_connect ( adjustment, "value-changed", ( GCallback ) scroll_value_changed, &from_bottom );
gtk_container_add ( GTK_CONTAINER ( scrolled_win ), widg->textview );
/// ***
hbox = gtk_hbox_new ( FALSE, 5 );
gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), widg->entry );
gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), button );
/// ***
vbox = gtk_vbox_new ( FALSE, 5 );
gtk_box_pack_start ( GTK_BOX ( vbox ), scrolled_win, TRUE, TRUE, 0 );
gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, TRUE, 0 );
/// ***
gtk_container_add ( GTK_CONTAINER ( window ), vbox );
gtk_widget_show_all ( window );
gtk_main();
}
void chatMSG ( GtkButton *button, Widgets *widg )
{
( void ) button;
GtkTextMark *mark;
GtkTextIter iter;
/// ***
GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW ( widg->textview ) );
const gchar *text = gtk_entry_get_text ( GTK_ENTRY ( widg->entry ) );
/// ***
mark = gtk_text_buffer_get_insert ( buffer );
gtk_text_buffer_get_iter_at_mark ( buffer, &iter, mark );
if ( gtk_text_buffer_get_char_count ( buffer ) && strlen ( text ) > 0 )
{
gtk_text_buffer_insert ( buffer, &iter, "\n", -1 );
}
gtk_text_buffer_insert ( buffer, &iter, text, -1 );
gtk_entry_set_text ( GTK_ENTRY ( widg->entry ), "" );
}
void scroll_bottom_gravity ( GtkWidget *scrolled_window, gpointer user_data )
{
GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_window ) );
double *from_bottom = user_data;
double upper = gtk_adjustment_get_upper ( adjustment );
double page_size = gtk_adjustment_get_page_size ( adjustment );
gtk_adjustment_set_value ( adjustment, upper - page_size - *from_bottom );
}
void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data )
{
double *from_bottom = user_data;
double value = gtk_adjustment_get_value ( adjustment );
double upper = gtk_adjustment_get_upper ( adjustment );
double page_size = gtk_adjustment_get_page_size ( adjustment );
*from_bottom = upper - page_size - value;
}

FreeRTOS: Queue did not work as expected

I am new to FreeRTOS. I have written an example using queue to transfer data between tasks. Nevertheless, the results displayed are wrong. May anyone help me to get over this problem?
Thanks!
Variables to be displayed:
unsigned int temperatureRaw = 25;
unsigned int flowRateRaw = 30;
unsigned int carbonLevelRaw = 250;
unsigned int salinityLevelRaw = 75;
Struct holding pointers to above variables:
struct RawData {
unsigned int *temperatureRaw;
unsigned int *flowRateRaw;
unsigned int *carbonLevelRaw;
unsigned int *salinityLevelRaw;
};
typedef struct RawData RawData;
Tasks' prototype
static void vOLEDTask( void *pvParameters );
static void vTask1( void *pvParameters );
static void prvSetupHardware( void );
Queue handles:
QueueHandle_t xOLEDQueue, xRawQueue;
Main:
int main( void )
{
prvSetupHardware();
/* Create queues */
xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( xOLEDMessage * ) );
xRawQueue = xQueueCreate( 3, sizeof( RawData * ) );
/* Check if queues are successfully created */
if( ( xOLEDQueue != 0 ) && ( xRawQueue != 0 ) ) {
// Declare variables
RawData xRawData = { &temperatureRaw, &flowRateRaw, &carbonLevelRaw, &salinityLevelRaw };
RawData *pxRawData = &xRawData;
/* Start the tasks defined within this file/specific to this demo. */
xTaskCreate( vOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vTask1, "Task1", 1000, ( void * )pxRawData, 1, NULL );
/* Start the scheduler. */
vTaskStartScheduler();
}
return 0;
}
Tasks' definition:
void prvSetupHardware( void )
{
/* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is
a workaround to allow the PLL to operate reliably. */
if( DEVICE_IS_REVA2 )
{
SysCtlLDOSet( SYSCTL_LDO_2_75V );
}
/* Set the clocking to run from the PLL at 50 MHz */
SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ );
}
void vOLEDTask( void *pvParameters )
{
RawData *pxRawData = NULL;
unsigned long ulMaxY;
static char cMessage[ mainMAX_MSG_LEN ];
extern volatile unsigned long ulMaxJitter;
const unsigned char *pucImage;
/* Functions to access the OLED. The one used depends on the dev kit
being used. */
void ( *vOLEDInit )( unsigned long ) = NULL;
void ( *vOLEDStringDraw )( const char *, unsigned long, unsigned long, unsigned char ) = NULL;
void ( *vOLEDImageDraw )( const unsigned char *, unsigned long, unsigned long, unsigned long, unsigned long ) = NULL;
void ( *vOLEDClear )( void ) = NULL;
/* Map the OLED access functions to the driver functions that are appropriate
for the evaluation kit being used. */
switch( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK )
{
case SYSCTL_DID1_PRTNO_6965 :
case SYSCTL_DID1_PRTNO_2965 : vOLEDInit = OSRAM128x64x4Init;
vOLEDStringDraw = OSRAM128x64x4StringDraw;
vOLEDImageDraw = OSRAM128x64x4ImageDraw;
vOLEDClear = OSRAM128x64x4Clear;
ulMaxY = mainMAX_ROWS_64;
pucImage = pucBasicBitmap;
break;
case SYSCTL_DID1_PRTNO_1968 :
case SYSCTL_DID1_PRTNO_8962 : vOLEDInit = RIT128x96x4Init;
vOLEDStringDraw = RIT128x96x4StringDraw;
vOLEDImageDraw = RIT128x96x4ImageDraw;
vOLEDClear = RIT128x96x4Clear;
ulMaxY = mainMAX_ROWS_96;
pucImage = pucBasicBitmap;
break;
default : vOLEDInit = vFormike128x128x16Init;
vOLEDStringDraw = vFormike128x128x16StringDraw;
vOLEDImageDraw = vFormike128x128x16ImageDraw;
vOLEDClear = vFormike128x128x16Clear;
ulMaxY = mainMAX_ROWS_128;
pucImage = pucGrLibBitmap;
break;
}
/* Initialise the OLED and display a startup message. */
vOLEDInit( ulSSI_FREQUENCY );
for( ;; )
{
xQueueReceive( xRawQueue, ( void * )&pxRawData, portMAX_DELAY );
/* Display the message. */
sprintf( cMessage, "%s %u C", "Temperature", *(pxRawData->temperatureRaw) );
vOLEDStringDraw( cMessage, 0, 10, mainFULL_SCALE );
sprintf( cMessage, "%s %u LPS", "Flow Rate", *(pxRawData->flowRateRaw) );
vOLEDStringDraw( cMessage, 0, 20, mainFULL_SCALE );
sprintf( cMessage, "%s %u ppm", "Carbon Level", *(pxRawData->carbonLevelRaw) );
vOLEDStringDraw( cMessage, 0, 30, mainFULL_SCALE );
sprintf( cMessage, "%s %u ppt", "Salinity Level", *(pxRawData->salinityLevelRaw) );
vOLEDStringDraw( cMessage, 0, 40, mainFULL_SCALE );
}
}
/*-----------------------------------------------------------*/
static void vTask1( void *pvParameters )
{
RawData *pxRawData = ( RawData * )pvParameters;
for( ;; ) {
xQueueSend( xRawQueue, ( void * )&pxRawData, portMAX_DELAY );
vTaskDelay( 1000/portTICK_RATE_MS );
}
}
I have not studied all the code, but the first problem I see is that you are passing pxRawData as a parameter to a task, pxRawData is a pointer to xRawData, but xRawData has a very narrow block scope, and the stack it is declared on is different to the stack used by the task, so the variable being pointed to will not exist when the task starts running - or if it does exist it is by luck and there is a risk it will get overwritten (depending on the FreeRTOS port being used).
Also, consider that xRawQueue is created to hold pointers to RawData, but I think your call to xQueueSend in vTask1 is passing the address of a pointer, so it is queuing a pointer to a pointer to RawData, not a pointer to RawData. Although that probably doesn't matter as its being received into a pointer to a pointer too, and then accessed as such.

Function gtk_cell_renderer_toggle_set_active does not work properly

I would like to put a Checkbox in treeview.
When I clicked the Checkbox, it should ckeck. But Checkbox keeps being not checked.
I have written a sample code in C and GTK3:
#include <gtk/gtk.h>
GtkTreeModel* create_model ()
{
GtkTreeIter gti;
GtkListStore *gls = gtk_list_store_new ( 1, G_TYPE_BOOLEAN );
gtk_list_store_append ( gls, &gti );
gtk_list_store_set ( gls, &gti, 0, FALSE, -1 );
return GTK_TREE_MODEL ( gls );
}
void check ( GtkCellRendererToggle *cell )
{
int active = gtk_cell_renderer_toggle_get_active ( cell );
g_print ( "%d\n", active );
if ( active )
{
//fail
gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE ( cell ), FALSE );
}
else
{
//fail
gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE ( cell ), TRUE) ;
}
return;
}
int main ( int argc, char *argv[] )
{
gtk_init ( &argc, &argv );
//window
GtkWidget *window_main = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
//tree view
GtkWidget *treeview = gtk_tree_view_new_with_model ( create_model () );
//cell_renderer_toggle
GtkCellRenderer *cell = gtk_cell_renderer_toggle_new ();
gtk_tree_view_append_column ( GTK_TREE_VIEW ( treeview ), gtk_tree_view_column_new_with_attributes ( "test", cell, "active", 0, NULL ) );
g_signal_connect ( cell, "toggled", G_CALLBACK ( check ), NULL );
gtk_container_add ( GTK_CONTAINER ( window_main ), treeview );
gtk_widget_show_all ( window_main );
gtk_main();
return 0;
}
Function gtk_cell_renderer_toggle_set_active call fails and does not set the cell active.
Please help me fix my code.
With the call of
gtk_tree_view_column_new_with_attributes ("test", cell, "active", 0, NULL);
you bind the "active" property of each cell renderer in any row of the column to the value in the first column of the related data model. Although the state of any GtkCellRendererToggle instance is represented by its own properties its "active" property reflects the corresponding value in the data model at the same time.
If you activate a single cell renderer by means of gtk_cell_renderer_toggle_set_active you just set the "active" property of the specific GtkCellRendererToggle instance. Unfortunately the instance has no knowledge about the data model from which it represent a value and therefore has no access to it. That means that on the next draw of the treeview the "active" property corresponds with the related value from the data model again. Your change is simply overwritten.
Nevertheless you can still safely set all other properties of a cell renderer that are not connected to the data model. I included an example for that in my example.
That means that your callback have to change the value in the data model instead of changing the property of the cell renderer.
The appended modification of your example code illustrates what i've described
#include <gtk/gtk.h>
GtkListStore *
create_model ()
{
GtkTreeIter gti;
GtkListStore *gls;
gls = gtk_list_store_new (1, G_TYPE_BOOLEAN);
gtk_list_store_append (gls, &gti);
gtk_list_store_set (gls, &gti, 0, TRUE, -1);
return gls;
}
void
check (GtkCellRendererToggle * cell, gchar * path, GtkListStore * model)
{
GtkTreeIter iter;
gboolean active;
active = gtk_cell_renderer_toggle_get_active (cell);
gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path);
if (active) {
gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(cell), 0, 0);
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, FALSE, -1);
}
else {
gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(cell), 0.5, 0.5);
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, TRUE, -1);
}
}
int
main (int argc, char *argv[])
{
GtkTreeViewColumn *column;
GtkWidget *window_main;
GtkWidget *treeview;
GtkCellRenderer *cell;
GtkListStore *store;
gtk_init (&argc, &argv);
store = create_model ();
//window
window_main = gtk_window_new (GTK_WINDOW_TOPLEVEL);
//tree view
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
//cell_renderer_toggle
cell = gtk_cell_renderer_toggle_new ();
column =
gtk_tree_view_column_new_with_attributes ("test",
cell, "active", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_signal_connect (cell, "toggled", G_CALLBACK (check), store);
g_signal_connect (window_main, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_container_add (GTK_CONTAINER (window_main), treeview);
gtk_widget_show_all (window_main);
gtk_main ();
return 0;
}

GTK and SFML 2 Blurred sprites

I want to use GTK+ and SFML 2.0 together. I created a simple window to test that, but doesn't work well. Sprites are blurred. Below is a screenshot describing the problem.
/edit:
The window renders only the first pixel of a texture.
It should look like this:
The code:
#include <gtk/gtk.h>
#include <SFML/Graphics.hpp>
#include <gdk/gdkwin32.h>
sf::RenderWindow Win;
sf::Sprite tile[ MAP_SIZE ][ MAP_SIZE ];
void on_expose( GtkWidget * widget, gpointer data )
{
MapView * view =( MapView * ) data;
sf::Event event;
while( Win.pollEvent( event ) )
{
if( event.type == sf::Event::Closed )
Win.close();
view->updateEvents( & event, Win );
}
Win.clear( sf::Color::White );
view->render( tile, Win );
Win.display();
gtk_widget_queue_draw(widget);
}
int main( int argc, char ** argv )
{
sf::Texture tex; // Testing texture
if( !tex.loadFromFile( "gfx/7.png" ) )
std::cout << "Unable to load texture!\n";
for( int i = 0; i < MAP_SIZE; ++i )
for( int j = 0; j < MAP_SIZE; ++j )
tile[ j ][ i ].setTexture( tex ); // Default texture, a.k.a MAP_NONE
MapView view( tile, sf::Vector2f( 0, 0 ) );
gtk_init( & argc, & argv );
GtkWidget * window;
GtkWidget * area;
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
area = gtk_drawing_area_new();
gtk_container_add( GTK_CONTAINER( window ), area );
GdkEventMask mask;
mask = GDK_ALL_EVENTS_MASK;
gtk_widget_add_events( area, mask );
gtk_widget_set_can_focus( area, true );
gtk_widget_set_size_request( area, 16 * 25, 16 * 25 ); // Preview size.
gtk_widget_realize( area );
gtk_widget_set_double_buffered( area, false );
Win.create( sf::WindowHandle( GDK_WINDOW_HWND( area->window ) ) ); // Windows-only solution
Win.setFramerateLimit( 30 );
g_signal_connect( window, "destroy", G_CALLBACK( gtk_main_quit ), NULL );
g_signal_connect( area, "expose-event", G_CALLBACK( on_expose ), & view );
gtk_widget_show_all( window );
gtk_main();
return 0;
}
I had to call
gdk_window_resize(area->window, MAP_SIZE*25, MAP_SIZE*25);
before creating a SFML window inside drawing-area.
My wild guess:
Use the second argument of sf::Sprite::setTexture to correctly reset the size of the sprite.
for( int i = 0; i < MAP_SIZE; ++i )
for( int j = 0; j < MAP_SIZE; ++j )
tile[ j ][ i ].setTexture( tex, true );