From 9e844573e0eaf27a5274ba71b55361782ae8a457 Mon Sep 17 00:00:00 2001 From: fnevgeny Date: Thu, 19 Aug 2004 23:03:13 +0000 Subject: [PATCH] Fonttool enhancements: preserve cursor positions, be smart about font escape strings, etc. --- src/fontwin.c | 636 ++++++++++++++++++++++++++----------------------------- src/motifinc.h | 1 + src/motifutils.c | 9 +- src/xprotos.h | 5 +- 4 files changed, 312 insertions(+), 339 deletions(-) rewrite src/fontwin.c (65%) diff --git a/src/fontwin.c b/src/fontwin.c dissimilarity index 65% index 86d78545..bc093713 100644 --- a/src/fontwin.c +++ b/src/fontwin.c @@ -1,335 +1,301 @@ -/* - * Grace - GRaphing, Advanced Computation and Exploration of data - * - * Home page: http://plasma-gate.weizmann.ac.il/Grace/ - * - * Copyright (c) 1991-1995 Paul J Turner, Portland, OR - * Copyright (c) 1996-2004 Grace Development Team - * - * Maintained by Evgeny Stambulchik - * - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * - * Font tool - * - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "globals.h" -#include "grace/canvas.h" -#include "utils.h" -#include "motifinc.h" -#include "protos.h" - - -/* used globally */ -extern Widget app_shell; - -static Widget fonttool_frame = NULL; -static OptionStructure *font_select_item; -static TextStructure *string_item = NULL; - -static Widget cstext_parent = NULL; - -static int FontID; -static int csize; - -static int enable_edit_cb; - -static void DrawCB(Widget w,XtPointer cd, XbaeMatrixDrawCellCallbackStruct *cbs); -static void EnterCB(Widget w, XtPointer cd, XbaeMatrixEnterCellCallbackStruct *cbs); -static void update_fonttool_cb(OptionStructure *opt, int value, void *data); -static void EditStringCB(Widget w, XtPointer client_data, XmAnyCallbackStruct *cbs); -static void fonttool_aac_cb(Widget but, void *data); - -void create_fonttool_cb(Widget but, void *data) -{ - create_fonttool((Widget) data); -} - -void create_fonttool(Widget cstext) -{ - int i; - short widths[16]; - unsigned char column_alignments[16]; - Widget fonttool_panel, font_table, aac_buts; - - if (string_item != NULL && cstext == string_item->text) { - /* avoid recursion */ - return; - } - - if (cstext_parent != NULL) { - /* unlock previous parent */ - SetSensitive(cstext_parent, True); - } - - cstext_parent = cstext; - - if (fonttool_frame == NULL) { - fonttool_frame = XmCreateDialogShell(app_shell, "Font tool", NULL, 0); - handle_close(fonttool_frame); - fonttool_panel = XtVaCreateWidget("fonttool_panel", xmFormWidgetClass, - fonttool_frame, NULL, 0); - - font_select_item = CreateFontChoice(fonttool_panel, "Font:"); - XtVaSetValues(font_select_item->menu, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - NULL); - - for (i = 0; i < 16; i++) { - widths[i] = 2; - column_alignments[i] = XmALIGNMENT_BEGINNING; - } - font_table = XtVaCreateManagedWidget( - "fontTable", xbaeMatrixWidgetClass, fonttool_panel, - XmNrows, 16, - XmNcolumns, 16, - XmNvisibleRows, 8, - XmNvisibleColumns, 16, - XmNfill, True, - XmNcolumnWidths, widths, - XmNcolumnAlignments, column_alignments, - XmNgridType, XmGRID_CELL_SHADOW, - XmNcellShadowType, XmSHADOW_ETCHED_OUT, - XmNcellShadowThickness, 2, - XmNaltRowCount, 0, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_WIDGET, - XmNtopWidget, font_select_item->menu, - NULL); - - XtAddCallback(font_table, XmNdrawCellCallback, (XtCallbackProc) DrawCB, NULL); - XtAddCallback(font_table, XmNenterCellCallback, (XtCallbackProc) EnterCB, NULL); - AddOptionChoiceCB(font_select_item, update_fonttool_cb, font_table); - - string_item = CreateCSText(fonttool_panel, "CString:"); - XtVaSetValues(string_item->form, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, - NULL); - - XtAddCallback(string_item->text, - XmNmodifyVerifyCallback, (XtCallbackProc) EditStringCB, font_table); - - aac_buts = CreateAACButtons(fonttool_panel, - fonttool_panel, fonttool_aac_cb); - XtVaSetValues(aac_buts, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - NULL); - - XtVaSetValues(string_item->form, - XmNbottomAttachment, XmATTACH_WIDGET, - XmNbottomWidget, aac_buts, - NULL); - - XtVaSetValues(font_table, - XmNbottomAttachment, XmATTACH_WIDGET, - XmNbottomWidget, string_item->form, - NULL); - - update_fonttool_cb(NULL, 0, font_table); - ManageChild(fonttool_panel); - } - - enable_edit_cb = FALSE; - if (cstext_parent == NULL) { - SetTextString(string_item, ""); - } else { - SetTextString(string_item, xv_getstr(cstext_parent)); - /* Lock editable text */ - SetSensitive(cstext_parent, False); - } - enable_edit_cb = TRUE; - - RaiseWindow(fonttool_frame); -} - -static void DrawCB(Widget w, XtPointer cd, XbaeMatrixDrawCellCallbackStruct *cbs) -{ - X11Stuff *xstuff = grace->gui->xstuff; - unsigned char c; - Pixmap pixmap; - char dummy_bits[1] = {0}; - int valid_char; - - - c = 16*cbs->row + cbs->column; - - if (FontID == BAD_FONT_ID) { - pixmap = 0; - } else { - pixmap = char_to_pixmap(w, FontID, c, csize); - } - - if (!pixmap) { - pixmap = XCreateBitmapFromData(xstuff->disp, xstuff->root, - dummy_bits, 1, 1); - valid_char = FALSE; - } else { - valid_char = TRUE; - } - - /* Assign it a pixmap */ - cbs->pixmap = pixmap; - cbs->type = XbaePixmap; - XbaeMatrixSetCellUserData(w, cbs->row, cbs->column, (XtPointer) valid_char); - - return; -} - -static void insert_into_string(char *s) -{ - int pos; - - pos = GetTextCursorPos(string_item); - TextInsert(string_item, pos, s); -} - -static void EnterCB(Widget w, XtPointer cd, XbaeMatrixEnterCellCallbackStruct *cbs) -{ - X11Stuff *xstuff = grace->gui->xstuff; - int valid_char; - char s[7]; - unsigned char c; - - valid_char = (int) XbaeMatrixGetCellUserData(w, cbs->row, cbs->column); - if (valid_char == TRUE) { - c = 16*cbs->row + cbs->column; - /* TODO: check for c being displayable in the _X_ font */ - if (c > 31) { - s[0] = (char) c; - s[1] = '\0'; - } else { - sprintf(s, "\\#{%02x}", c); - } - insert_into_string(s); - } else { - XBell(xstuff->disp, 25); - } -} - - -static void update_fonttool_cb(OptionStructure *opt, int value, void *data) -{ - Widget font_table = (Widget) data; - int x0, y0, x1, y1, cwidth, cheight; - char *buf; - FontID = value; - - XbaeMatrixRowColToXY(font_table, 0, 0, &x0, &y0); - XbaeMatrixRowColToXY(font_table, 1, 1, &x1, &y1); - cwidth = x1 - x0; - cheight = y1 - y0; - - /* 6 = 2*cellShadowThickness + 2 */ - csize = MIN2(cwidth, cheight) - 6; - - buf = copy_string(NULL, "\\f{"); - buf = concat_strings(buf, get_fontalias(grace->rt->canvas, FontID)); - buf = concat_strings(buf, "}"); - insert_into_string(buf); - xfree(buf); - - XbaeMatrixRefresh(font_table); -} - - -static void EditStringCB(Widget w, XtPointer client_data, XmAnyCallbackStruct *cbs) -{ - unsigned char c; - int valid_char; - static int column = 0, row = 0; - XmTextVerifyCallbackStruct *tcbs; - XmTextBlock text; - Widget ftable = (Widget) client_data; - - if (enable_edit_cb != TRUE) { - return; - } - - XbaeMatrixDeselectCell(ftable, row, column); - - tcbs = (XmTextVerifyCallbackStruct *) cbs; - - text = tcbs->text; - - if (text->length == 1) { - /* */ - c = text->ptr[0]; - row = c/16; - column = c % 16; - - valid_char = (int) XbaeMatrixGetCellUserData(ftable, row, column); - if (valid_char == TRUE) { - XbaeMatrixSelectCell(ftable, row, column); - } else { - tcbs->doit = False; - } - } -} - -static void fonttool_aac_cb(Widget but, void *data) -{ - int aac_mode; - - aac_mode = (int) data; - - if (aac_mode == AAC_CLOSE) { - UnmanageChild(fonttool_frame); - if (cstext_parent != NULL) { - SetSensitive(cstext_parent, True); - } - return; - } - - if (cstext_parent != NULL) { - char *s = GetTextString(string_item); - xv_setstr(cstext_parent, s); - xfree(s); - } - - if (aac_mode == AAC_ACCEPT) { - UnmanageChild(fonttool_frame); - if (cstext_parent != NULL) { - SetSensitive(cstext_parent, True); - } - } -} +/* + * Grace - GRaphing, Advanced Computation and Exploration of data + * + * Home page: http://plasma-gate.weizmann.ac.il/Grace/ + * + * Copyright (c) 1996-2004 Grace Development Team + * + * Maintained by Evgeny Stambulchik + * + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * + * Font tool + * + */ + +#include + +#include + +#include "globals.h" +#include "motifinc.h" +#include "protos.h" + +typedef struct _fonttool_ui +{ + Widget fonttool_panel; + OptionStructure *font_select; + Widget font_table; + TextStructure *cstext; + WidgetList aac_buts; + + TextStructure *cstext_parent; + + int new_font; + int font_id; + int csize; + + int enable_edit_cb; + + char valid_chars[256]; +} fonttool_ui; + +static void DrawCB(Widget w, XtPointer client_data, XtPointer call_data); +static void EnterCB(Widget w, XtPointer client_data, XtPointer call_data); +static void EditStringCB(Widget w, XtPointer client_data, XtPointer call_data); + +static void update_fonttool_cb(OptionStructure *opt, int value, void *data); +static int fonttool_aac_cb(void *data); + +void create_fonttool_cb(Widget but, void *data) +{ + create_fonttool((TextStructure *) data); +} + +void create_fonttool(TextStructure *cstext_parent) +{ + static fonttool_ui *ui = NULL; + + if (ui == NULL) { + int i; + short widths[16]; + unsigned char column_alignments[16]; + + ui = xmalloc(sizeof(fonttool_ui)); + memset(ui, 0, sizeof(fonttool_ui)); + + ui->fonttool_panel = CreateDialogForm(app_shell, "Font tool"); + + ui->font_select = CreateFontChoice(ui->fonttool_panel, "Font:"); + AddDialogFormChild(ui->fonttool_panel, ui->font_select->menu); + + for (i = 0; i < 16; i++) { + widths[i] = 2; + column_alignments[i] = XmALIGNMENT_BEGINNING; + } + ui->font_table = XtVaCreateManagedWidget( + "fontTable", xbaeMatrixWidgetClass, ui->fonttool_panel, + XmNrows, 16, + XmNcolumns, 16, + XmNvisibleRows, 8, + XmNvisibleColumns, 16, + XmNfill, True, + XmNcolumnWidths, widths, + XmNcolumnAlignments, column_alignments, + XmNgridType, XmGRID_CELL_SHADOW, + XmNcellShadowType, XmSHADOW_ETCHED_OUT, + XmNcellShadowThickness, 2, + XmNaltRowCount, 0, + NULL); + + XtAddCallback(ui->font_table, XmNdrawCellCallback, DrawCB, ui); + XtAddCallback(ui->font_table, XmNenterCellCallback, EnterCB, ui); + AddOptionChoiceCB(ui->font_select, update_fonttool_cb, ui); + + AddDialogFormChild(ui->fonttool_panel, ui->font_table); + + ui->cstext = CreateCSText(ui->fonttool_panel, "CString:"); + + XtAddCallback(ui->cstext->text, + XmNmodifyVerifyCallback, EditStringCB, ui); + + ui->aac_buts = CreateAACDialog(ui->fonttool_panel, + ui->cstext->form, fonttool_aac_cb, ui); + + FixateDialogFormChild(ui->cstext->form); + + update_fonttool_cb(NULL, 0, ui); + } + + if (cstext_parent == ui->cstext) { + /* avoid recursion */ + return; + } + + ui->cstext_parent = cstext_parent; + + ui->enable_edit_cb = FALSE; + if (ui->cstext_parent == NULL) { + SetTextString(ui->cstext, ""); + SetSensitive(ui->aac_buts[0], FALSE); + SetSensitive(ui->aac_buts[1], FALSE); + } else { + char *s = GetTextString(ui->cstext_parent); + int pos = GetTextCursorPos(ui->cstext_parent); + SetTextString(ui->cstext, s); + SetTextCursorPos(ui->cstext, pos); + xfree(s); + SetSensitive(ui->aac_buts[0], TRUE); + SetSensitive(ui->aac_buts[1], TRUE); + } + ui->enable_edit_cb = TRUE; + + RaiseWindow(GetParent(ui->fonttool_panel)); +} + +static void DrawCB(Widget w, XtPointer client_data, XtPointer call_data) +{ + fonttool_ui *ui = (fonttool_ui *) client_data; + XbaeMatrixDrawCellCallbackStruct *cbs = + (XbaeMatrixDrawCellCallbackStruct *) call_data; + unsigned char c; + Pixmap pixmap; + + c = 16*cbs->row + cbs->column; + + if (ui->font_id == BAD_FONT_ID) { + pixmap = 0; + } else { + pixmap = char_to_pixmap(w, ui->font_id, c, ui->csize); + } + + if (!pixmap) { + ui->valid_chars[c] = FALSE; + } else { + ui->valid_chars[c] = TRUE; + } + + /* Assign it a pixmap */ + if (pixmap) { + cbs->pixmap = pixmap; + cbs->type = XbaePixmap; + } + + return; +} + +static void insert_into_string(TextStructure *cstext, char *s) +{ + int pos; + + pos = GetTextCursorPos(cstext); + TextInsert(cstext, pos, s); +} + +static void EnterCB(Widget w, XtPointer client_data, XtPointer call_data) +{ + fonttool_ui *ui = (fonttool_ui *) client_data; + XbaeMatrixEnterCellCallbackStruct *cbs = + (XbaeMatrixEnterCellCallbackStruct *) call_data; + X11Stuff *xstuff = grace->gui->xstuff; + char s[7]; + unsigned char c; + + c = 16*cbs->row + cbs->column; + if (ui->valid_chars[c]) { + c = 16*cbs->row + cbs->column; + /* TODO: check for c being displayable in the _X_ font */ + if (c > 31) { + s[0] = (char) c; + s[1] = '\0'; + } else { + sprintf(s, "\\#{%02x}", c); + } + insert_into_string(ui->cstext, s); + } else { + cbs->doit = False; + XBell(xstuff->disp, 25); + } +} + + +static void update_fonttool_cb(OptionStructure *opt, int value, void *data) +{ + fonttool_ui *ui = (fonttool_ui *) data; + int x0, y0, x1, y1, cwidth, cheight; + + if (ui->font_id != value) { + ui->font_id = value; + ui->new_font = TRUE; + } + + XbaeMatrixRowColToXY(ui->font_table, 0, 0, &x0, &y0); + XbaeMatrixRowColToXY(ui->font_table, 1, 1, &x1, &y1); + cwidth = x1 - x0; + cheight = y1 - y0; + + /* 6 = 2*cellShadowThickness + 2 */ + ui->csize = MIN2(cwidth, cheight) - 6; + + XbaeMatrixRefresh(ui->font_table); +} + + +static void EditStringCB(Widget w, XtPointer client_data, XtPointer call_data) +{ + fonttool_ui *ui = (fonttool_ui *) client_data; + XmTextVerifyCallbackStruct *tcbs = + (XmTextVerifyCallbackStruct *) call_data; + unsigned char c; + static int column = 0, row = 0; + XmTextBlock text; + + if (ui->enable_edit_cb != TRUE) { + return; + } + + text = tcbs->text; + + XbaeMatrixDeselectCell(ui->font_table, row, column); + + if (text->length == 1) { + /* */ + c = text->ptr[0]; + row = c/16; + column = c % 16; + + if (ui->valid_chars[c]) { + XbaeMatrixSelectCell(ui->font_table, row, column); + } else { + tcbs->doit = False; + return; + } + } + + if (ui->new_font) { + char *buf; + + buf = copy_string(NULL, "\\f{"); + buf = concat_strings(buf, get_fontalias(grace->rt->canvas, ui->font_id)); + buf = concat_strings(buf, "}"); + buf = concat_strings(buf, text->ptr); + XtFree(text->ptr); + text->ptr = XtNewString(buf); + text->length = strlen(buf); + xfree(buf); + + ui->new_font = FALSE; + } +} + +static int fonttool_aac_cb(void *data) +{ + fonttool_ui *ui = (fonttool_ui *) data; + if (ui->cstext_parent != NULL) { + char *s = GetTextString(ui->cstext); + int pos = GetTextCursorPos(ui->cstext); + SetTextString(ui->cstext_parent, s); + SetTextCursorPos(ui->cstext_parent, pos); + xfree(s); + } + + return RETURN_SUCCESS; +} diff --git a/src/motifinc.h b/src/motifinc.h index a2b7f0fa..2803e24d 100644 --- a/src/motifinc.h +++ b/src/motifinc.h @@ -463,6 +463,7 @@ char *GetTextString(TextStructure *cst); void SetTextString(TextStructure *cst, char *s); void AddTextInputCB(TextStructure *cst, Text_CBProc cbproc, void *data); int GetTextCursorPos(TextStructure *cst); +void SetTextCursorPos(TextStructure *cst, int pos); void TextInsert(TextStructure *cst, int pos, char *s); void SetTextEditable(TextStructure *cst, int onoff); void cstext_edit_action(Widget w, XEvent *e, String *par, Cardinal *npar); diff --git a/src/motifutils.c b/src/motifutils.c index 7ef3d2c3..08e40b9a 100644 --- a/src/motifutils.c +++ b/src/motifutils.c @@ -1611,7 +1611,8 @@ TextStructure *CreateTextInput(Widget parent, char *s) void cstext_edit_action(Widget w, XEvent *e, String *par, Cardinal *npar) { - create_fonttool(w); + TextStructure *cst = (TextStructure *) GetUserData(w); + create_fonttool(cst); } static char cstext_translation_table[] = "\ @@ -1622,6 +1623,7 @@ TextStructure *CreateCSText(Widget parent, char *s) TextStructure *retval; retval = CreateTextInput(parent, s); + SetUserData(retval->text, retval); XtOverrideTranslations(retval->text, XtParseTranslationTable(cstext_translation_table)); @@ -1678,6 +1680,11 @@ int GetTextCursorPos(TextStructure *cst) return XmTextGetInsertionPosition(cst->text); } +void SetTextCursorPos(TextStructure *cst, int pos) +{ + XmTextSetInsertionPosition(cst->text, pos); +} + void TextInsert(TextStructure *cst, int pos, char *s) { XmTextInsert(cst->text, pos, s); diff --git a/src/xprotos.h b/src/xprotos.h index 28a6a242..3a58e5c3 100644 --- a/src/xprotos.h +++ b/src/xprotos.h @@ -34,10 +34,9 @@ #ifndef __XPROTOS_H_ #define __XPROTOS_H_ -#include - #include "defines.h" #include "core_utils.h" +#include "motifinc.h" typedef int (*CanvasPointSink) ( unsigned int npoints, @@ -187,7 +186,7 @@ void create_nonl_frame(Widget but, void *data); void create_props_frame(Widget but, void *data); -void create_fonttool(Widget w); +void create_fonttool(TextStructure *cstext_parent); void create_fonttool_cb(Widget but, void *data); void create_datasetprop_popup(Widget but, void *data); -- 2.11.4.GIT