tWin32 now supports the "foreground" attribute of GtkTextTags when using Rich E… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c383b81213580add66d8116f660768060253e32d | |
parent 20317b21645411bd9e3a83c822d2a59499631cb7 | |
Author: Ben Webb <[email protected]> | |
Date: Sat, 31 Aug 2002 18:12:41 +0000 | |
Win32 now supports the "foreground" attribute of GtkTextTags when using | |
Rich Edit controls (there are, however, some problems when using Unicode | |
which remain to be fixed). | |
Diffstat: | |
M src/gtkport/gtkport.c | 128 +++++++++++++++++++++++++++--… | |
M src/gtkport/gtkport.h | 8 ++++++++ | |
M src/gui_client/gtk_client.c | 17 +++++++++++------ | |
3 files changed, 134 insertions(+), 19 deletions(-) | |
--- | |
diff --git a/src/gtkport/gtkport.c b/src/gtkport/gtkport.c | |
t@@ -35,6 +35,7 @@ | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdarg.h> | |
+#include <ctype.h> | |
#include <glib.h> | |
#include "gtkport.h" | |
t@@ -65,6 +66,7 @@ const gchar *GTK_STOCK_HELP = N_("_Help"); | |
HICON mainIcon = NULL; | |
static WNDPROC customWndProc = NULL; | |
static gboolean HaveRichEdit = FALSE; | |
+static gchar *RichEditClass = NULL; | |
static guint RecurseLevel = 0; | |
t@@ -82,6 +84,7 @@ static void gtk_entry_set_size(GtkWidget *widget, | |
GtkAllocation *allocation); | |
static void gtk_text_size_request(GtkWidget *widget, | |
GtkRequisition *requisition); | |
+static void gtk_text_destroy(GtkWidget *widget); | |
static void gtk_button_destroy(GtkWidget *widget); | |
static void gtk_check_button_size_request(GtkWidget *widget, | |
GtkRequisition *requisition); | |
t@@ -393,6 +396,7 @@ static GtkClass GtkSpinButtonClass = { | |
static GtkSignalType GtkTextSignals[] = { | |
{"size_request", gtk_marshal_VOID__GPOIN, gtk_text_size_request}, | |
{"realize", gtk_marshal_VOID__VOID, gtk_text_realize}, | |
+ {"destroy", gtk_marshal_VOID__VOID, gtk_text_destroy}, | |
{"", NULL, NULL} | |
}; | |
t@@ -1148,7 +1152,16 @@ void win32_init(HINSTANCE hInstance, HINSTANCE hPrevIns… | |
InitCommonControls(); | |
LoadLibrary("RICHED32.DLL"); | |
- HaveRichEdit = GetClassInfo(hInstance, "RichEdit", &wc); | |
+ | |
+ /* Rich Edit controls have two different class names, depending on whether | |
+ * we want ANSI or Unicode - argh! */ | |
+ if (HaveUnicodeSupport()) { | |
+ RichEditClass = "RichEdit20W"; | |
+ } else { | |
+ RichEditClass = "RichEdit20A"; | |
+ } | |
+ RichEditClass = "RichEdit"; | |
+ HaveRichEdit = GetClassInfo(hInstance, RichEditClass, &wc); | |
if (!hPrevInstance) { | |
wc.style = 0; | |
t@@ -1861,7 +1874,12 @@ GtkWidget *gtk_frame_new(const gchar *text) | |
GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj) | |
{ | |
- return GTK_WIDGET(GtkNewObject(&GtkTextClass)); | |
+ GtkText *text; | |
+ | |
+ text = GTK_TEXT(GtkNewObject(&GtkTextClass)); | |
+ text->buffer = g_new(GtkTextBuffer, 1); | |
+ g_datalist_init(&text->buffer->tags); | |
+ return GTK_WIDGET(text); | |
} | |
GtkWidget *gtk_scrolled_text_view_new(GtkWidget **pack_widg) | |
t@@ -1937,8 +1955,9 @@ static void gtk_text_view_set_format(GtkTextView *textvi… | |
const gchar *tagname, guint len, | |
gint endpos) | |
{ | |
- CHARFORMAT cf; | |
+ CHARFORMAT *cf, cfdef; | |
GtkWidget *widget = GTK_WIDGET(textview); | |
+ GtkTextBuffer *buffer; | |
if (!GTK_WIDGET_REALIZED(widget)) { | |
return; | |
t@@ -1946,15 +1965,15 @@ static void gtk_text_view_set_format(GtkTextView *text… | |
mySendMessage(widget->hWnd, EM_SETSEL, (WPARAM)(endpos - len), | |
(LPARAM)endpos); | |
- cf.cbSize = sizeof(CHARFORMAT); | |
- cf.dwMask = CFM_COLOR; | |
- if (tagname) { | |
- cf.crTextColor = RGB(0, 0, 255); | |
- cf.dwEffects = 0; | |
- } else { | |
- cf.dwEffects = CFE_AUTOCOLOR; | |
+ | |
+ if (!tagname || !(buffer = gtk_text_view_get_buffer(textview)) | |
+ || !(cf = g_datalist_get_data(&buffer->tags, tagname))) { | |
+ cfdef.cbSize = sizeof(CHARFORMAT); | |
+ cfdef.dwMask = CFM_COLOR; | |
+ cfdef.dwEffects = CFE_AUTOCOLOR; | |
+ cf = &cfdef; | |
} | |
- mySendMessage(widget->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); | |
+ mySendMessage(widget->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)cf); | |
} | |
void gtk_editable_delete_text(GtkEditable *editable, | |
t@@ -2092,6 +2111,17 @@ void gtk_box_destroy(GtkWidget *widget) | |
g_list_free(GTK_BOX(widget)->children); | |
} | |
+static void gtk_text_destroy(GtkWidget *widget) | |
+{ | |
+ GtkText *text = GTK_TEXT(widget); | |
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(text); | |
+ | |
+ if (buffer) { | |
+ g_datalist_clear(&buffer->tags); | |
+ g_free(buffer); | |
+ } | |
+} | |
+ | |
static void EnableParent(GtkWindow *window) | |
{ | |
GtkWidget *parent; | |
t@@ -2457,7 +2487,7 @@ void gtk_text_realize(GtkWidget *widget) | |
editable = GTK_EDITABLE(widget)->is_editable; | |
GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS); | |
widget->hWnd = myCreateWindowEx(WS_EX_CLIENTEDGE, | |
- HaveRichEdit ? "RichEdit" : "EDIT", "", | |
+ HaveRichEdit ? RichEditClass : "EDIT", "", | |
WS_CHILD | (editable ? WS_TABSTOP : 0) | | |
ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL | | |
(GTK_TEXT(widget)->word_wrap ? | |
t@@ -4677,6 +4707,78 @@ void gtk_text_thaw(GtkText *text) | |
{ | |
} | |
+GtkTextBuffer *gtk_text_view_get_buffer(GtkText *text) | |
+{ | |
+ return text->buffer; | |
+} | |
+ | |
+static int parse_colcomp(const gchar *hexval) | |
+{ | |
+ int col = 0, i, ch; | |
+ | |
+ for (i = 0; i < 4; ++i) { | |
+ col <<= 4; | |
+ ch = toupper(hexval[i]); | |
+ if (ch >= '0' && ch <= '9') { | |
+ col |= (ch - '0'); | |
+ } else if (ch >= 'A' && ch <= 'F') { | |
+ col |= (ch - 'A' + 10); | |
+ } | |
+ } | |
+ return col / 257; /* Scale from 0-65535 to 0-255 */ | |
+} | |
+ | |
+static gboolean parse_color(const gchar *name, COLORREF *color) | |
+{ | |
+ int red, green, blue, i, ch; | |
+ | |
+ if (!name || strlen(name) != 13 || name[0] != '#') { | |
+ return FALSE; | |
+ } | |
+ for (i = strlen(name) - 1; i >= 1; --i) { | |
+ ch = toupper(name[i]); | |
+ if (!((ch >= '0' && ch <= '9') | |
+ || (ch >= 'A' && ch <= 'F'))) { | |
+ return FALSE; | |
+ } | |
+ } | |
+ red = parse_colcomp(&name[1]); | |
+ green = parse_colcomp(&name[5]); | |
+ blue = parse_colcomp(&name[9]); | |
+ if (color) { | |
+ *color = RGB(red, green, blue); | |
+ } | |
+ return TRUE; | |
+} | |
+ | |
+void gtk_text_buffer_create_tag(GtkTextBuffer *buffer, const gchar *name, ...) | |
+{ | |
+ va_list ap; | |
+ gchar *attr, *data; | |
+ CHARFORMAT *cf; | |
+ | |
+ va_start(ap, name); | |
+ cf = g_new(CHARFORMAT, 1); | |
+ cf->cbSize = sizeof(CHARFORMAT); | |
+ cf->dwMask = 0; | |
+ do { | |
+ attr = va_arg(ap, gchar *); | |
+ if (attr) { | |
+ if (strcmp(attr, "foreground") == 0) { | |
+ data = va_arg(ap, gchar *); | |
+ cf->dwMask |= CFM_COLOR; | |
+ cf->dwEffects = 0; | |
+ if (!parse_color(data, &cf->crTextColor)) { | |
+ cf->dwEffects = CFE_AUTOCOLOR; | |
+ } | |
+ } | |
+ } | |
+ } while (attr); | |
+ | |
+ g_datalist_set_data_full(&buffer->tags, name, cf, g_free); | |
+ va_end(ap); | |
+} | |
+ | |
GtkWidget *gtk_option_menu_new() | |
{ | |
GtkOptionMenu *option_menu; | |
t@@ -5507,7 +5609,7 @@ void TextViewAppend(GtkTextView *textview, const gchar *… | |
gtk_editable_insert_text(GTK_EDITABLE(textview), text, strlen(text), | |
&editpos); | |
#ifdef CYGWIN | |
- gtk_text_view_set_format(textview, tagname, strlen(text), editpos); | |
+ gtk_text_view_set_format(textview, tagname, myw32strlen(text), editpos); | |
#endif | |
if (scroll) { | |
gtk_editable_set_position(GTK_EDITABLE(textview), editpos); | |
diff --git a/src/gtkport/gtkport.h b/src/gtkport/gtkport.h | |
t@@ -225,6 +225,7 @@ struct _GtkMenuBar { | |
typedef struct _GtkEditable GtkEditable; | |
typedef struct _GtkEntry GtkEntry; | |
typedef struct _GtkText GtkText; | |
+typedef struct _GtkTextBuffer GtkTextBuffer; | |
typedef struct _GtkSpinButton GtkSpinButton; | |
struct _GtkEditable { | |
t@@ -244,9 +245,14 @@ struct _GtkSpinButton { | |
HWND updown; | |
}; | |
+struct _GtkTextBuffer { | |
+ GData *tags; | |
+}; | |
+ | |
struct _GtkText { | |
GtkEditable editable; | |
gint word_wrap:1; | |
+ GtkTextBuffer *buffer; | |
}; | |
typedef struct _GtkLabel GtkLabel; | |
t@@ -547,6 +553,8 @@ void gtk_text_set_editable(GtkText *text, gboolean is_edit… | |
void gtk_text_set_word_wrap(GtkText *text, gboolean word_wrap); | |
void gtk_text_freeze(GtkText *text); | |
void gtk_text_thaw(GtkText *text); | |
+GtkTextBuffer *gtk_text_view_get_buffer(GtkText *text); | |
+void gtk_text_buffer_create_tag(GtkTextBuffer *buffer, const gchar *name, ...); | |
void gtk_table_attach(GtkTable *table, GtkWidget *widget, | |
guint left_attach, guint right_attach, | |
guint top_attach, guint bottom_attach, | |
diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c | |
t@@ -2142,14 +2142,19 @@ static void SetIcon(GtkWidget *window, gchar **xpmdata) | |
static void make_tags(GtkTextView *textview) | |
{ | |
-#if HAVE_GLIB2 && !CYGWIN | |
+#if HAVE_GLIB2 | |
GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); | |
- gtk_text_buffer_create_tag(buffer, "jet", "foreground", "blue", NULL); | |
- gtk_text_buffer_create_tag(buffer, "talk", "foreground", "red", NULL); | |
- gtk_text_buffer_create_tag(buffer, "page", "foreground", "magenta", NULL); | |
- gtk_text_buffer_create_tag(buffer, "join", "foreground", "darkblue", NULL); | |
- gtk_text_buffer_create_tag(buffer, "leave", "foreground", "darkred", NULL); | |
+ gtk_text_buffer_create_tag(buffer, "jet", "foreground", | |
+ "#00000000FFFF", NULL); | |
+ gtk_text_buffer_create_tag(buffer, "talk", "foreground", | |
+ "#FFFF00000000", NULL); | |
+ gtk_text_buffer_create_tag(buffer, "page", "foreground", | |
+ "#FFFF0000FFFF", NULL); | |
+ gtk_text_buffer_create_tag(buffer, "join", "foreground", | |
+ "#000000008B8B", NULL); | |
+ gtk_text_buffer_create_tag(buffer, "leave", "foreground", | |
+ "#8B8B00000000", NULL); | |
#endif | |
} | |