записал видео.
click
на видео видно, что когда добавляешь элементы, которые выходят за область виджета, то сверху не рисуется полностью виджет. И еще когда достигаешь краев scroll, то эффект не нужный появляется, который портит вид. Вот код. Подскажите как сделать.
#include <gtk/gtk.h>
#include <time.h>
#include <string.h>
GtkWidget *menu, *item;
GtkWidget *window;
GtkApplication *app;
GtkWidget *frame_chat_view;
GtkWidget *text_box;
GtkWidget *entry_input_text;
GtkWidget *scroll;
int scroll_event = 0;
static gboolean window_delete ( GtkWidget *widget, GdkEvent *event, gpointer user_data ) {
g_application_quit ( ( GApplication * ) app );
exit ( EXIT_SUCCESS );
return FALSE;
}
static gboolean text_view_draw_cb ( GtkWidget *widget, cairo_t *cr, gpointer data ) {
gtk_widget_queue_resize ( widget );
GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment ( ( GtkScrolledWindow * ) scroll );
if ( scroll_event == 0 ) {
gtk_adjustment_set_value ( vadj, gtk_adjustment_get_upper ( vadj ) );
} else {
gtk_adjustment_set_value ( vadj, gtk_adjustment_get_value ( vadj ) );
}
return FALSE;
}
static gboolean scroll_scroll_child_cb ( GtkWidget *widget, GdkEvent *event, gpointer data ) {
GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment ( ( GtkScrolledWindow * ) scroll );
gtk_adjustment_set_value ( vadj, gtk_adjustment_get_value ( vadj ) );
scroll_event = 1;
return FALSE;
}
const char *style = "* { background-color: #3c3c3c; } entry { color: #ffffff; } frame#frame_text * { background-color: #1c1c1c; border-radius: 6px; } textview text { color: #ffffff; } textview#text_view_w * { border-radius: 0px; }";
int index_list = 0;
static gboolean entry_input_text_cb ( GtkWidget *widget, GdkEvent *event, gpointer data ) {
GdkEventKey *key = ( GdkEventKey * ) event;
if ( key->keyval == GDK_KEY_Return ) {
scroll_event = 0;
const char *t = gtk_entry_get_text ( ( GtkEntry * ) entry_input_text );
if ( strlen ( t ) == 0 ) return FALSE;
GtkTextBuffer *buf = gtk_text_buffer_new ( NULL );
gtk_text_buffer_set_text ( buf, t, -1 );
GtkWidget *frame = g_object_new ( GTK_TYPE_FRAME, "shadow-type", GTK_SHADOW_NONE, "name", "frame_text", NULL );
GtkWidget *text_view = gtk_text_view_new ( );
gtk_text_view_set_editable ( ( GtkTextView * ) text_view, FALSE );
gtk_text_view_set_wrap_mode ( ( GtkTextView * ) text_view, GTK_WRAP_WORD_CHAR );
gtk_text_view_set_buffer ( ( GtkTextView * ) text_view, buf );
g_signal_connect ( text_view, "draw", G_CALLBACK ( text_view_draw_cb ), NULL );
gtk_widget_set_name ( text_view, "text_view_w" );
gtk_widget_set_margin_start ( frame, 10 );
gtk_widget_set_margin_end ( frame, 10 );
gtk_widget_set_margin_top ( frame, 10 );
gtk_widget_set_margin_bottom ( frame, 0 );
gtk_widget_set_margin_top ( text_view, 10 );
gtk_widget_set_margin_end ( text_view, 10 );
gtk_widget_set_margin_bottom ( text_view, 10 );
gtk_widget_set_margin_start ( text_view, 10 );
gtk_container_add ( ( GtkContainer * ) frame, text_view );
gtk_box_pack_start ( ( GtkBox * ) text_box, frame, FALSE, FALSE, 0 );
gtk_widget_show_all ( text_box );
gtk_entry_set_text ( ( GtkEntry * ) entry_input_text, "" );
}
return FALSE;
}
static void g_startup ( GtkApplication *app, gpointer data ) {
GMainLoop *loop = g_main_loop_new ( NULL, FALSE );
window = gtk_application_window_new ( app );
gtk_window_set_default_size ( ( GtkWindow * ) window, 1024, 600 );
GdkDisplay *display = gdk_display_get_default ();
GdkScreen *screen = gdk_display_get_default_screen (display);
GtkCssProvider *pr = gtk_css_provider_new ( );
GError *error;
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (pr), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_css_provider_load_from_data ( ( GtkCssProvider * ) pr, style, strlen ( style ), NULL );
GtkStyleContext *ctx = gtk_style_context_new ( );
gtk_style_context_add_provider ( ( GtkStyleContext * ) ctx, ( GtkStyleProvider * ) pr, GTK_STYLE_PROVIDER_PRIORITY_USER );
frame_chat_view = g_object_new ( GTK_TYPE_FRAME, "shadow-type", GTK_SHADOW_NONE, NULL );
g_signal_connect ( window, "delete-event", G_CALLBACK ( window_delete ), NULL );
GtkWidget *main_box = gtk_box_new ( GTK_ORIENTATION_VERTICAL, 0 );
GtkWidget *input_box = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, 0 );
text_box = gtk_box_new ( GTK_ORIENTATION_VERTICAL, 0 );
gtk_widget_set_name ( text_box, "text_box" );
entry_input_text = gtk_entry_new ( );
scroll = g_object_new ( GTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_NONE, "hadjustment", NULL, "vadjustment", NULL, NULL );
gtk_scrolled_window_set_policy ( ( GtkScrolledWindow * ) scroll, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
g_signal_connect ( scroll, "scroll-event", G_CALLBACK ( scroll_scroll_child_cb ), NULL );
gtk_container_add ( ( GtkContainer * ) frame_chat_view, text_box );
gtk_container_add ( ( GtkContainer * ) scroll, frame_chat_view );
gtk_box_pack_start ( ( GtkBox * ) main_box, scroll, TRUE, TRUE, 0 );
gtk_box_pack_start ( ( GtkBox * ) main_box, input_box, FALSE, FALSE, 0 );
gtk_box_pack_end ( ( GtkBox * ) input_box, entry_input_text, TRUE, TRUE, 0 );
g_signal_connect ( entry_input_text, "key-press-event", G_CALLBACK ( entry_input_text_cb ), NULL );
gtk_container_add ( ( GtkContainer * ) window, main_box );
gtk_widget_show_all ( window );
g_main_loop_run ( loop );
}
int main ( int argc, char **argv ) {
app = gtk_application_new ( "org.xverizex.lanxchat", G_APPLICATION_FLAGS_NONE );
g_application_register ( ( GApplication * ) app, NULL, NULL );
g_signal_connect ( app, "activate", G_CALLBACK ( g_startup ), NULL );
int ret = g_application_run ( ( GApplication * ) app, argc, argv );
g_object_unref ( app );
return ret;
}