2015-12-06 00:18:32 -06:00
// 6 december 2015
# include "uipriv_unix.h"
2017-02-07 18:14:51 -06:00
// TODO GTK_WRAP_WORD_CHAR to avoid spurious resizes?
2015-12-06 00:18:32 -06:00
struct uiMultilineEntry {
uiUnixControl c ;
GtkWidget * widget ;
GtkContainer * scontainer ;
GtkScrolledWindow * sw ;
GtkWidget * textviewWidget ;
GtkTextView * textview ;
GtkTextBuffer * textbuf ;
void ( * onChanged ) ( uiMultilineEntry * , void * ) ;
void * onChangedData ;
gulong onChangedSignal ;
} ;
2016-04-25 19:00:25 -05:00
uiUnixControlAllDefaults ( uiMultilineEntry )
2015-12-06 00:18:32 -06:00
static void onChanged ( GtkTextBuffer * textbuf , gpointer data )
{
uiMultilineEntry * e = uiMultilineEntry ( data ) ;
( * ( e - > onChanged ) ) ( e , e - > onChangedData ) ;
}
static void defaultOnChanged ( uiMultilineEntry * e , void * data )
{
// do nothing
}
char * uiMultilineEntryText ( uiMultilineEntry * e )
{
GtkTextIter start , end ;
char * tret , * out ;
gtk_text_buffer_get_start_iter ( e - > textbuf , & start ) ;
gtk_text_buffer_get_end_iter ( e - > textbuf , & end ) ;
tret = gtk_text_buffer_get_text ( e - > textbuf , & start , & end , TRUE ) ;
// theoretically we could just return tret because uiUnixStrdupText() is just g_strdup(), but if that ever changes we can't, so let's do it this way to be safe
out = uiUnixStrdupText ( tret ) ;
g_free ( tret ) ;
return out ;
}
void uiMultilineEntrySetText ( uiMultilineEntry * e , const char * text )
{
2016-05-22 22:14:33 -05:00
// we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
g_signal_handler_block ( e - > textbuf , e - > onChangedSignal ) ;
2015-12-06 00:18:32 -06:00
gtk_text_buffer_set_text ( e - > textbuf , text , - 1 ) ;
2016-05-22 22:14:33 -05:00
g_signal_handler_unblock ( e - > textbuf , e - > onChangedSignal ) ;
2015-12-06 00:18:32 -06:00
}
// TODO scroll to end?
void uiMultilineEntryAppend ( uiMultilineEntry * e , const char * text )
{
GtkTextIter end ;
gtk_text_buffer_get_end_iter ( e - > textbuf , & end ) ;
2016-05-22 22:14:33 -05:00
// we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
g_signal_handler_block ( e - > textbuf , e - > onChangedSignal ) ;
2015-12-06 00:18:32 -06:00
gtk_text_buffer_insert ( e - > textbuf , & end , text , - 1 ) ;
2016-05-22 22:14:33 -05:00
g_signal_handler_unblock ( e - > textbuf , e - > onChangedSignal ) ;
2015-12-06 00:18:32 -06:00
}
void uiMultilineEntryOnChanged ( uiMultilineEntry * e , void ( * f ) ( uiMultilineEntry * e , void * data ) , void * data )
{
e - > onChanged = f ;
e - > onChangedData = data ;
}
int uiMultilineEntryReadOnly ( uiMultilineEntry * e )
{
return gtk_text_view_get_editable ( e - > textview ) = = FALSE ;
}
void uiMultilineEntrySetReadOnly ( uiMultilineEntry * e , int readonly )
{
gboolean editable ;
editable = TRUE ;
if ( readonly )
editable = FALSE ;
gtk_text_view_set_editable ( e - > textview , editable ) ;
}
2016-05-22 13:20:54 -05:00
static uiMultilineEntry * finishMultilineEntry ( GtkPolicyType hpolicy , GtkWrapMode wrapMode )
2015-12-06 00:18:32 -06:00
{
uiMultilineEntry * e ;
2016-04-25 19:00:25 -05:00
uiUnixNewControl ( uiMultilineEntry , e ) ;
2015-12-06 00:18:32 -06:00
e - > widget = gtk_scrolled_window_new ( NULL , NULL ) ;
e - > scontainer = GTK_CONTAINER ( e - > widget ) ;
e - > sw = GTK_SCROLLED_WINDOW ( e - > widget ) ;
gtk_scrolled_window_set_policy ( e - > sw ,
2016-05-22 13:20:54 -05:00
hpolicy ,
2015-12-06 00:18:32 -06:00
GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_set_shadow_type ( e - > sw , GTK_SHADOW_IN ) ;
e - > textviewWidget = gtk_text_view_new ( ) ;
e - > textview = GTK_TEXT_VIEW ( e - > textviewWidget ) ;
2016-05-22 13:20:54 -05:00
gtk_text_view_set_wrap_mode ( e - > textview , wrapMode ) ;
2015-12-06 00:18:32 -06:00
gtk_container_add ( e - > scontainer , e - > textviewWidget ) ;
// and make the text view visible; only the scrolled window's visibility is controlled by libui
gtk_widget_show ( e - > textviewWidget ) ;
e - > textbuf = gtk_text_view_get_buffer ( e - > textview ) ;
e - > onChangedSignal = g_signal_connect ( e - > textbuf , " changed " , G_CALLBACK ( onChanged ) , e ) ;
uiMultilineEntryOnChanged ( e , defaultOnChanged , NULL ) ;
return e ;
}
2016-05-22 13:20:54 -05:00
uiMultilineEntry * uiNewMultilineEntry ( void )
{
return finishMultilineEntry ( GTK_POLICY_NEVER , GTK_WRAP_WORD ) ;
}
uiMultilineEntry * uiNewNonWrappingMultilineEntry ( void )
{
return finishMultilineEntry ( GTK_POLICY_AUTOMATIC , GTK_WRAP_NONE ) ;
}