changeset 13882:5c750626eaa5

[gaim-migrate @ 16362] New widget GntTextView. It's really simple as it is. But it 'works'. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 28 Jun 2006 00:17:35 +0000
parents 5d5e249c488e
children ab6376814e73
files console/libgnt/Makefile console/libgnt/gntbox.c console/libgnt/gntcolors.c console/libgnt/gntentry.c console/libgnt/gntentry.h console/libgnt/gnttextview.c console/libgnt/gnttextview.h console/libgnt/gnttree.c console/libgnt/gntwidget.c
diffstat 9 files changed, 310 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/console/libgnt/Makefile	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/Makefile	Wed Jun 28 00:17:35 2006 +0000
@@ -8,6 +8,7 @@
 	gntcolors.h \
 	gntentry.h \
 	gntlabel.h \
+	gnttextview.h \
 	gnttree.h \
 	gntutils.h \
 	gnt.h
@@ -19,6 +20,7 @@
 	gntcolors.c \
 	gntentry.c \
 	gntlabel.c \
+	gnttextview.c \
 	gnttree.c \
 	gntutils.c \
 	gntmain.c
@@ -30,6 +32,7 @@
 	gntcolors.o \
 	gntentry.o \
 	gntlabel.o \
+	gnttextview.o \
 	gnttree.o \
 	gntutils.o \
 	gntmain.o
@@ -45,6 +48,7 @@
 gntcolors.o: gntcolors.c $(HEADERS)
 gntentry.o: gntentry.c $(HEADERS)
 gntlabel.o: gntlabel.c $(HEADERS)
+gnttextview.o: gnttextview.c $(HEADERS)
 gnttree.o: gnttree.c $(HEADERS)
 gntutils.o: gntutils.c $(HEADERS)
 gntmain.o: gntmain.c $(HEADERS)
--- a/console/libgnt/gntbox.c	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gntbox.c	Wed Jun 28 00:17:35 2006 +0000
@@ -374,11 +374,17 @@
 	GList *iter;
 	GntWidget *widget = GNT_WIDGET(box);
 
+	/* XXX: werase first? */
+
 	for (iter = box->list; iter; iter = iter->next)
 	{
 		GntWidget *w = GNT_WIDGET(iter->data);
-		copywin(w->window, widget->window, 0, 0, w->priv.y - widget->priv.y, w->priv.x - widget->priv.x,
-					w->priv.height, w->priv.width, FALSE);
+		copywin(w->window, widget->window, 0, 0,
+				w->priv.y - widget->priv.y,
+				w->priv.x - widget->priv.x,
+				w->priv.y - widget->priv.y + w->priv.height - 1,
+				w->priv.x - widget->priv.x + w->priv.width - 1,
+				FALSE);
 	}
 }
 
--- a/console/libgnt/gntcolors.c	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gntcolors.c	Wed Jun 28 00:17:35 2006 +0000
@@ -20,14 +20,16 @@
 		init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY);
 		init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_DARK_GRAY);
 		init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_GRAY);
+		init_pair(GNT_COLOR_HIGHLIGHT_D, GNT_COLOR_BLACK, GNT_COLOR_GRAY);
 	}
 	else
 	{
 		init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE);
-		init_pair(GNT_COLOR_HIGHLIGHT, COLOR_CYAN, COLOR_BLACK);
+		init_pair(GNT_COLOR_HIGHLIGHT, COLOR_YELLOW, COLOR_BLACK);
 		init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK);
 		init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLACK);
 		init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_BLACK, COLOR_WHITE);
+		init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK);
 	}
 }
 
--- a/console/libgnt/gntentry.c	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gntentry.c	Wed Jun 28 00:17:35 2006 +0000
@@ -29,8 +29,12 @@
 gnt_entry_size_request(GntWidget *widget)
 {
 	GntEntry *entry = GNT_ENTRY(widget);
-	widget->priv.height = 1;
-	widget->priv.width = 20;
+
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		widget->priv.height = 1;
+		widget->priv.width = 20;
+	}
 }
 
 static void
@@ -41,6 +45,13 @@
 	DEBUG;
 }
 
+static void
+entry_redraw(GntWidget *widget)
+{
+	gnt_entry_draw(widget);
+	gnt_widget_queue_update(widget);
+}
+
 static gboolean
 gnt_entry_key_pressed(GntWidget *widget, const char *text)
 {
@@ -52,21 +63,21 @@
 		{
 			memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor + 1);
 			entry->end--;
-			gnt_entry_draw(widget);
+			entry_redraw(widget);
 		}
 		else if (strcmp(text + 1, GNT_KEY_LEFT) == 0 && entry->cursor > entry->start)
 		{
 			entry->cursor--;
 			if (entry->cursor < entry->scroll)
 				entry->scroll--;
-			gnt_entry_draw(widget);
+			entry_redraw(widget);
 		}
 		else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0 && entry->cursor < entry->end)
 		{
 			entry->cursor++;
 			if (entry->cursor - entry->scroll > widget->priv.width)
 				entry->scroll++;
-			gnt_entry_draw(widget);
+			entry_redraw(widget);
 		}
 		/* XXX: handle other keys, like home/end, and ctrl+ goodness */
 	}
@@ -106,7 +117,8 @@
 				if (entry->cursor - entry->scroll > widget->priv.width)
 					entry->scroll++;
 			}
-			gnt_entry_draw(widget);
+			entry_redraw(widget);
+			return TRUE;
 		}
 		else
 		{
@@ -120,7 +132,7 @@
 				if (entry->scroll > entry->start)
 					entry->scroll--;
 
-				gnt_entry_draw(widget);
+				entry_redraw(widget);
 			}
 		}
 	}
@@ -233,7 +245,8 @@
 	entry->scroll = entry->start + scroll;
 	entry->cursor = entry->end - cursor;
 
-	/* XXX: redraw if necessary? */
+	if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED))
+		entry_redraw(GNT_WIDGET(entry));
 }
 
 void gnt_entry_set_max(GntEntry *entry, int max)
@@ -247,3 +260,16 @@
 	/* XXX: Check the existing string to make sure the flags are respected? */
 }
 
+const char *gnt_entry_get_text(GntEntry *entry)
+{
+	return entry->start;
+}
+
+void gnt_entry_clear(GntEntry *entry)
+{
+	gnt_entry_set_text(entry, NULL);
+	entry->scroll = entry->cursor = entry->end = entry->start;
+	entry_redraw(GNT_WIDGET(entry));
+}
+
+
--- a/console/libgnt/gntentry.h	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gntentry.h	Wed Jun 28 00:17:35 2006 +0000
@@ -69,10 +69,15 @@
 
 void gnt_entry_set_max(GntEntry *entry, int max);
 
+/* XXX: For now, call gnt_entry_clear before calling this */
 void gnt_entry_set_text(GntEntry *entry, const char *text);
 
 void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag);
 
+const char *gnt_entry_get_text(GntEntry *entry);
+
+void gnt_entry_clear(GntEntry *entry);
+
 G_END_DECLS
 
 #endif /* GNT_ENTRY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttextview.c	Wed Jun 28 00:17:35 2006 +0000
@@ -0,0 +1,177 @@
+#include "gnttextview.h"
+
+enum
+{
+	SIGS = 1,
+};
+
+static GntWidgetClass *parent_class = NULL;
+static guint signals[SIGS] = { 0 };
+
+static void
+gnt_text_view_draw(GntWidget *widget)
+{
+	GntTextView *view = GNT_TEXT_VIEW(widget);
+
+	copywin(view->scroll, widget->window, view->pos, 0, 0, 0,
+					widget->priv.height - 1, widget->priv.width - 1, FALSE);
+	
+	DEBUG;
+}
+
+static void
+gnt_text_view_size_request(GntWidget *widget)
+{
+	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+	{
+		gnt_widget_set_size(widget, 64, 24);
+	}
+}
+
+static void
+gnt_text_view_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	DEBUG;
+}
+
+static gboolean
+gnt_text_view_key_pressed(GntWidget *widget, const char *text)
+{
+	return FALSE;
+}
+
+static void
+gnt_text_view_destroy(GntWidget *widget)
+{
+}
+
+static void
+gnt_text_view_class_init(GntTextViewClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->destroy = gnt_text_view_destroy;
+	parent_class->draw = gnt_text_view_draw;
+	parent_class->map = gnt_text_view_map;
+	parent_class->size_request = gnt_text_view_size_request;
+	parent_class->key_pressed = gnt_text_view_key_pressed;
+
+	DEBUG;
+}
+
+static void
+gnt_text_view_init(GTypeInstance *instance, gpointer class)
+{
+	DEBUG;
+}
+
+/******************************************************************************
+ * GntTextView API
+ *****************************************************************************/
+GType
+gnt_text_view_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntTextViewClass),
+			NULL,					/* base_init		*/
+			NULL,					/* base_finalize	*/
+			(GClassInitFunc)gnt_text_view_class_init,
+			NULL,					/* class_finalize	*/
+			NULL,					/* class_data		*/
+			sizeof(GntTextView),
+			0,						/* n_preallocs		*/
+			gnt_text_view_init,			/* instance_init	*/
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+									  "GntTextView",
+									  &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_text_view_new()
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_TEXTVIEW, NULL);
+	GntTextView *view = GNT_TEXT_VIEW(widget);
+
+	view->scroll = newwin(255, widget->priv.width, widget->priv.y, widget->priv.x);
+	scrollok(view->scroll, TRUE);
+	wsetscrreg(view->scroll, 0, 254);
+	wbkgd(view->scroll, COLOR_PAIR(GNT_COLOR_NORMAL));
+	werase(view->scroll);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
+
+	return widget;
+}
+
+void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextViewFlags flags)
+{
+	GntWidget *widget = GNT_WIDGET(view);
+	int fl = 0;
+	char **split;
+	int i;
+
+	if (text == NULL || *text == '\0')
+		return;
+
+	if (flags & GNT_TEXT_FLAG_BOLD)
+		fl |= A_BOLD;
+	if (flags & GNT_TEXT_FLAG_UNDERLINE)
+		fl |= A_UNDERLINE;
+	if (flags & GNT_TEXT_FLAG_BLINK)
+		fl |= A_BLINK;
+
+	wattrset(view->scroll, fl | COLOR_PAIR(GNT_COLOR_NORMAL));
+
+	split = g_strsplit(text, "\n", 0);
+	for (i = 0; split[i + 1]; i++)
+	{
+		/* XXX: Do something if the strlen of split[i] is big
+		 * enough to cause the text to wrap. */
+		wprintw(view->scroll, "%s\n", split[i]);
+		view->lines++;
+	}
+	wprintw(view->scroll, "%s", split[i]);
+	g_strfreev(split);
+
+	gnt_widget_draw(widget);
+}
+
+void gnt_text_view_scroll(GntTextView *view, int scroll)
+{
+	GntWidget *widget = GNT_WIDGET(view);
+	int height;
+
+	if (scroll == 0)
+	{
+		view->pos = view->lines - widget->priv.height + 1;
+	}
+	else
+	{
+		view->pos += scroll;
+	}
+
+	if (view->pos + (height = widget->priv.height) > view->lines)
+		view->pos = view->lines - height + 1;
+
+	if (view->pos < 0)
+		view->pos = 0;
+
+	gnt_widget_draw(GNT_WIDGET(view));
+}
+
+void gnt_text_view_next_line(GntTextView *view)
+{
+	wclrtoeol(view->scroll);
+	gnt_text_view_append_text_with_flags(view, "\n", 0);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/console/libgnt/gnttextview.h	Wed Jun 28 00:17:35 2006 +0000
@@ -0,0 +1,69 @@
+#ifndef GNT_TEXT_VIEW_H
+#define GNT_TEXT_VIEW_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntcolors.h"
+#include "gntkeys.h"
+
+#define GNT_TYPE_TEXTVIEW				(gnt_text_view_get_gtype())
+#define GNT_TEXT_VIEW(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TEXTVIEW, GntTextView))
+#define GNT_TEXT_VIEW_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TEXTVIEW, GntTextViewClass))
+#define GNT_IS_TEXTVIEW(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TEXTVIEW))
+#define GNT_IS_TEXTVIEW_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TEXTVIEW))
+#define GNT_TEXT_VIEW_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TEXTVIEW, GntTextViewClass))
+
+#define GNT_TEXT_VIEW_FLAGS(obj)				(GNT_TEXT_VIEW(obj)->priv.flags)
+#define GNT_TEXT_VIEW_SET_FLAGS(obj, flags)		(GNT_TEXT_VIEW_FLAGS(obj) |= flags)
+#define GNT_TEXT_VIEW_UNSET_FLAGS(obj, flags)	(GNT_TEXT_VIEW_FLAGS(obj) &= ~(flags))
+
+typedef struct _GnTextView			GntTextView;
+typedef struct _GnTextViewPriv		GntTextViewPriv;
+typedef struct _GnTextViewClass		GntTextViewClass;
+
+struct _GnTextView
+{
+	GntWidget parent;
+
+	WINDOW *scroll;     /* XXX: For now, let's do with this. */
+	int pos;            /* Scroll position. */
+	int lines;          /* No. of lines of text. */
+};
+
+typedef enum
+{
+	GNT_TEXT_FLAG_BOLD        = 1 << 0,
+	GNT_TEXT_FLAG_UNDERLINE   = 1 << 1,
+	GNT_TEXT_FLAG_BLINK       = 1 << 2,
+} GntTextViewFlags;
+
+struct _GnTextViewClass
+{
+	GntWidgetClass parent;
+
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+GType gnt_text_view_get_gtype(void);
+
+/* XXX: For now, don't set a textview to have any border.
+ *      If you want borders real bad, put it in a box. */
+GntWidget *gnt_text_view_new();
+
+/* scroll > 0 means scroll up, < 0 means scroll down, == 0 means scroll to the end */
+void gnt_text_view_scroll(GntTextView *view, int scroll);
+
+void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextViewFlags flags);
+
+/* Move the cursor to the beginning of the next line and resets text-attributes.
+ * It first completes the current line with the current text-attributes. */
+void gnt_text_view_next_line(GntTextView *view);
+
+G_END_DECLS
+
+#endif /* GNT_TEXT_VIEW_H */
--- a/console/libgnt/gnttree.c	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gnttree.c	Wed Jun 28 00:17:35 2006 +0000
@@ -203,7 +203,10 @@
 		
 		if (row == tree->current)
 		{
-			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
+			if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS))
+				wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
+			else
+				wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); /* XXX: This, somehow, doesn't work */
 			mvwprintw(widget->window, start, pos, str);
 			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL));
 		}
--- a/console/libgnt/gntwidget.c	Tue Jun 27 21:55:47 2006 +0000
+++ b/console/libgnt/gntwidget.c	Wed Jun 28 00:17:35 2006 +0000
@@ -267,13 +267,13 @@
 		widget->window = newwin(widget->priv.height, widget->priv.width,
 						widget->priv.y, widget->priv.x);
 		wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
+	
+		if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
+			box(widget->window, 0, 0);
+		else
+			werase(widget->window);
 	}
 
-	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))
-		box(widget->window, 0, 0);
-	else
-		werase(widget->window);
-	
 #if 0
 	/* XXX: No shadow for now :( */
 	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_SHADOW))
@@ -358,6 +358,7 @@
 {
 	widget->priv.width = width;
 	widget->priv.height = height;
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED);
 }
 
 gboolean