home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / xaes_new / formkbd.c < prev    next >
C/C++ Source or Header  |  1994-10-26  |  12KB  |  529 lines

  1. /********************************************************************
  2.  *                                                                1.20*
  3.  *    XAES: Custom text editor                                        *
  4.  *    Code by Ken Hollis, GNU C Extensions by Sascha Blank            *
  5.  *                                                                    *
  6.  *    Copyright (c) 1994, Bitgate Software                            *
  7.  *                                                                    *
  8.  *    These are just the form_keybd replacement calls for windows.    *
  9.  *    I need to add template checking.                                *
  10.  *                                                                    *
  11.  ********************************************************************/
  12.  
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <ctype.h>
  16.  
  17. #include "xaes.h"        /* XAES header file */
  18. #include "nkcc.h"        /* Normalized Keycodes header file */
  19.  
  20. #ifdef __TURBOC__
  21. #pragma warn -pia
  22. #endif
  23.  
  24. #ifndef __FORMKEYBOARD__
  25. #define __FORMKEYBOARD__
  26. #endif
  27.  
  28. /*
  29.  *  Reposition the cursor to an index
  30.  *  (It took a bit of thinking it out, but it worked in the end!)
  31.  *
  32.  *  where = offset into string to put cursor on
  33.  */
  34. GLOBAL void edit_pos(WINDOW *win, int where)
  35. {
  36.     if ((win) && (win->handle != 0)) {
  37. /*        if (where!=win->edpos) { */
  38.             int textlen = (int)(strlen(win->tree[win->edobject].ob_spec.tedinfo->te_ptext));
  39.             WObjc_Edit(win, ED_END, 0, 0);
  40.  
  41.             if (where > (win->tree[win->edobject].ob_spec.tedinfo->te_txtlen - 1))
  42.                 win->edpos = win->tree[win->edobject].ob_spec.tedinfo->te_txtlen - 1;
  43.             else
  44.                 win->edpos = where;
  45.  
  46.             if (win->edpos > textlen)
  47.                 win->edpos = textlen;
  48.  
  49.             WObjc_Edit(win, ED_INIT, 0, 0);
  50.     }
  51. }
  52.  
  53. /*
  54.  *    Function to reposition cursor inside an object
  55.  *
  56.  *    This code segment by Jan Starzynski
  57.  *    Modifications by Ken Hollis
  58.  *
  59.  *    obj = Address of the root object (dialog box)
  60.  *    No  = editable object which was clicked on
  61.  *    mx  = X coordinate of mouse at time of click (from event info)
  62.  *
  63.  */
  64. GLOBAL int find_position(OBJECT *obj, int No, int mx)
  65. {
  66.     int te_x= 0;    /* Absolute coordinate of text */
  67.     int    P_text = 0;    /* Position in text */
  68.     int    P_mask = 0;    /* Position in mask */
  69.     int    size;        /* Text font size */
  70.     int    i, Child;    /* Children and the parent pointer */
  71.  
  72.     size = (obj[No].ob_spec.tedinfo->te_font == 3) ? 8 : 6;
  73.     te_x = (obj[No].ob_spec.tedinfo->te_just)
  74.             ? obj[No].ob_width - (obj[No].ob_spec.tedinfo->te_tmplen - 1) * size : 0;
  75.     if(obj[No].ob_spec.tedinfo->te_just == 2)
  76.             te_x /= 2;
  77.     te_x += obj[No].ob_x + size / 2;
  78.     Child = No;
  79.     for (i = No - 1; 0 <= i; i--)
  80.         if ((obj[i].ob_head <= Child) && (Child <= obj[i].ob_tail))    {
  81.             Child = i;
  82.             te_x += obj[i].ob_x;
  83.         }
  84.  
  85.     while ((te_x < mx) && (P_mask < obj[No].ob_spec.tedinfo->te_tmplen - 1)) {
  86.         if (obj[No].ob_spec.tedinfo->te_ptmplt[P_mask++] == '_')
  87.             P_text++;
  88.         te_x += size;
  89.     }
  90.     return P_text;
  91. }
  92.  
  93.  
  94. /*
  95.  *  Check to see if an object is hidden
  96.  *
  97.  *  tree = Address of dialog box to check
  98.  *  obj  = Object to check
  99.  *  flag = Flag to truly check for the object (usually TRUE)
  100.  *
  101.  *  Returns: TRUE = it is hidden
  102.  *             FALSE = it is not
  103.  */
  104. LOCAL int IsHidden(OBJECT *tree, int obj, int flag)
  105. {
  106.     int    index = obj, next;
  107.  
  108.     if (!(tree[obj].ob_flags & HIDETREE))
  109.         if (flag == TRUE || !(tree[obj].ob_state & DISABLED)) {
  110.             while ((next = tree[index].ob_next) != -1) {
  111.                 if ((tree[index].ob_flags & HIDETREE))
  112.                     return TRUE;
  113.                 index = next;
  114.             }
  115.             return FALSE;
  116.         }
  117.  
  118.     return TRUE;
  119. }
  120.  
  121. /*
  122.  *  Check for a specified flag against an object
  123.  *
  124.  *  tree = Address of the dialog box
  125.  *  obj  = Object to check
  126.  *  flag = Boolean value to truly check or not (usually TRUE)
  127.  *  mask = Mask to check for; make sure it's an integer value!
  128.  *
  129.  *  Returns: TRUE = object is flag
  130.  *             FALSE = it is not
  131.  */
  132. LOCAL int IsFlag(OBJECT *tree, int obj, int flag, int mask)
  133. {
  134.     if ((flag & mask) && (!IsHidden(tree, obj, FALSE)))
  135.         return TRUE;
  136.  
  137.     return FALSE;
  138. }
  139.  
  140. /*
  141.  *  Jump to the first editable object
  142.  *
  143.  *  tree = Address of the dialog box to go to the first object in
  144.  *
  145.  *  Returns: index of the first object
  146.  *             0 on failure
  147.  */
  148. LOCAL int FirstEdit(OBJECT *tree)
  149. {
  150.     int    index = 0;
  151.  
  152.     do {
  153.         index++;
  154.         if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
  155.             return index;
  156.     }
  157.     while (!(tree[index].ob_flags & LASTOB));
  158.  
  159.     return 0;
  160. }
  161.  
  162. /*
  163.  *  Jump to the last editable object
  164.  *
  165.  *  tree = Address of the dialog box to jump to the last object in
  166.  *
  167.  *  Returns: index of the last object
  168.  *             0 on failure
  169.  */
  170. LOCAL int LastEdit(OBJECT *tree)
  171. {
  172.     int    index = 0, last = 0;
  173.  
  174.     do {
  175.         index++;
  176.         if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
  177.             last = index;
  178.     }
  179.     while (!(tree[index].ob_flags & LASTOB));
  180.  
  181.     if (last)
  182.         return last;
  183.  
  184.     return 0;
  185. }
  186.  
  187. /*
  188.  *    Find next editable object
  189.  *
  190.  *    tree = Address of the dialog box to search
  191.  *    cobj = Current object the cursor is at
  192.  *
  193.  *    Returns: index of the next object
  194.  *             0 on failure
  195.  */
  196. LOCAL int NextEdit(OBJECT *tree, int cobj)
  197. {
  198.     int    index = cobj;
  199.     int    flag = FALSE;
  200.  
  201.     if (index) {
  202.         while (!(tree[index].ob_flags & LASTOB)) {
  203.             index++;
  204.             if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
  205.                 return index;
  206.         }
  207.  
  208.         if (!flag)
  209.             return FirstEdit(tree);
  210.     }
  211.  
  212.     return 0;
  213. }
  214.  
  215. /*
  216.  *    Clear all editable fields
  217.  *
  218.  *    tree = Object tree to clear out editable fields
  219.  */
  220. LOCAL int ClearAllEdit(OBJECT *tree)
  221. {
  222.     int    index = 0;
  223.  
  224.     do {
  225.         if (tree[++index].ob_flags & EDITABLE)
  226.             tree[index].ob_spec.tedinfo->te_ptext = "\0";
  227.     } while (!(tree[index].ob_flags & LASTOB));
  228.  
  229.     return FirstEdit(tree);
  230. }
  231.  
  232. /*
  233.  *  Find the object before the current one
  234.  *
  235.  *  tree = Address of the dialog box to search
  236.  *  cobj = Current object that the cursor is at
  237.  *
  238.  *  Returns: the index of the previous editable object
  239.  *             0 on failure
  240.  */
  241. LOCAL int PrevEdit(OBJECT *tree, int cobj)
  242. {
  243.     int    index = cobj;
  244.     int    flag = FALSE;
  245.  
  246.     if (index) {
  247.         do {
  248.             index--;
  249.             if (IsFlag(tree, index, tree[index].ob_flags, EDITABLE))
  250.                 return index;
  251.         }
  252.         while (index);
  253.  
  254.         if (!flag)
  255.             return LastEdit(tree);
  256.     }
  257.  
  258.     return 0;
  259. }
  260.  
  261. /*
  262.  *  Customized form_keybd call
  263.  *
  264.  *  win    = Window structure
  265.  *  key    = Keyboard keycode from EvntMulti
  266.  *    kstate = Keyboard status
  267.  *  nchr   = Processed keycode (0 if handled, otherwise, it
  268.  *           returns the keycode that was typed.)
  269.  *
  270.  *    Returns: 0 if an exitobject was selected
  271.  */
  272. GLOBAL int WForm_keybd(WINDOW *win, int key, int kstate, int *nobj, int *nchr)
  273. {
  274.     int n_key;
  275.  
  276.     *nobj = 0;
  277.  
  278.     if ((win) && (win->handle != 0)) {
  279.         int lastob = 0;
  280.  
  281.         n_key = nkc_tconv((key & 0xff) | (((long) key & 0xff00) << 8) | ((long) kstate << 24)) & ~(NKF_FUNC | NKF_RESVD | NKF_NUM);
  282.         *nchr = 0;
  283.  
  284.         do {
  285.             lastob++;
  286.         } while (!(win->tree[lastob].ob_flags & LASTOB));
  287.  
  288.         if ((!win->edobject && n_key == NK_RET) || (n_key == (NK_RET | NKF_CTRL))) {
  289.             int    i = 0;
  290.  
  291.             do {
  292.                 if (win->tree[i].ob_flags & DEFAULT) {
  293.                     *nobj = i;
  294.  
  295.                     if (*nobj != 0) {
  296.                         printf("\033Y1 Object: %3d\n", *nobj);
  297.                         Objc_Change(win, *nobj, 0, win->tree[*nobj].ob_state | SELECTED, 1);
  298.                     }
  299.  
  300.                     return FALSE;
  301.                 }
  302.                 i++;
  303.             } while (!(win->tree[i++].ob_flags & LASTOB) && (i<lastob));
  304.  
  305.             *nobj = 0;
  306.             return TRUE;
  307.         }
  308.  
  309. /*        if (!win->edobject || n_key & NKF_ALT) {
  310.             int    i = 0, mask = (toupper(n_key & 0xff) & 0x7f);
  311.  
  312.             do {
  313.                 EXTINFO *ex = (EXTINFO *)(win->tree[i].ob_spec.userblk->ub_parm);
  314.  
  315.                 if ((ex->te_hotkey == mask) && !(win->tree[i].ob_state & DISABLED) && ((win->tree[i].ob_flags & SELECTABLE) || (win->tree[i].ob_flags & EXIT))) {
  316.                     *nobj = i;
  317.                     return FALSE;
  318.                 }
  319.                 i++;
  320.             }
  321.             while (!(win->tree[i++].ob_flags & LASTOB));
  322.         } */
  323.  
  324.         if (win->edobject) {
  325.             register char *text = win->tree[win->edobject].ob_spec.tedinfo->te_ptext;
  326.             switch (n_key) {
  327.                 case NK_ENTER:
  328.                 case NK_DOWN:
  329.                 case NK_TAB:
  330.                 case NK_RET:
  331.                     WObjc_Edit(win, ED_END, 0, 0);
  332.                     win->edobject = NextEdit(win->tree, win->edobject);
  333.                     win->edpos = (int) strlen(win->tree[win->edobject].ob_spec.tedinfo->te_ptext);
  334.                     WObjc_Edit(win, ED_INIT, 0, 0);
  335.                     break;
  336.  
  337.                 case NK_UP:
  338.                 case NK_TAB | NKF_LSH:
  339.                 case NK_TAB | NKF_RSH:
  340.                     WObjc_Edit(win, ED_END, 0, 0);
  341.                     win->edobject = PrevEdit(win->tree, win->edobject);
  342.                     win->edpos = (int) strlen(win->tree[win->edobject].ob_spec.tedinfo->te_ptext);
  343.                     WObjc_Edit(win, ED_INIT, 0, 0);
  344.                     break;
  345.  
  346.                 case NK_UNDO:
  347.                     WCallUndoDispatcher(win);
  348.                     break;
  349.  
  350.                 case NK_HELP:
  351.                     WCallHelpDispatcher(win);
  352.                      break;
  353.  
  354.                 case NK_F1:
  355.                     WCallFKeyDispatcher(win, 1);
  356.                     break;
  357.  
  358.                 case NK_F2:
  359.                     WCallFKeyDispatcher(win, 2);
  360.                     break;
  361.  
  362.                 case NK_F3:
  363.                     WCallFKeyDispatcher(win, 3);
  364.                     break;
  365.  
  366.                 case NK_F4:
  367.                     WCallFKeyDispatcher(win, 4);
  368.                     break;
  369.  
  370.                 case NK_F5:
  371.                     WCallFKeyDispatcher(win, 5);
  372.                     break;
  373.  
  374.                 case NK_F6:
  375.                     WCallFKeyDispatcher(win, 6);
  376.                     break;
  377.  
  378.                 case NK_F7:
  379.                     WCallFKeyDispatcher(win, 7);
  380.                     break;
  381.  
  382.                 case NK_F8:
  383.                     WCallFKeyDispatcher(win, 8);
  384.                     break;
  385.  
  386.                 case NK_F9:
  387.                     WCallFKeyDispatcher(win, 9);
  388.                     break;
  389.  
  390.                 case NK_F10:
  391.                     WCallFKeyDispatcher(win, 10);
  392.                     break;
  393.  
  394.                 case NK_CLRHOME | NKF_CTRL:
  395.                     {
  396.                         int x, y, w, h;
  397.  
  398.                         win->edobject = ClearAllEdit(win->tree);
  399.                         WWindGet(win, WF_WORKXYWH, &x, &y, &w, &h);
  400.                         WRedrawWindow(win, x, y, w, h);
  401.                     }
  402.                     break;
  403.  
  404.                 case NK_LEFT | NKF_LSH:
  405.                 case NK_LEFT | NKF_RSH:
  406.                     edit_pos(win, 0);
  407.                     break;
  408.  
  409.                 case NK_RIGHT | NKF_LSH:
  410.                 case NK_RIGHT | NKF_RSH:
  411.                     edit_pos(win, (int) strlen(text));
  412.                     break;
  413.  
  414.                 case NK_RIGHT | NKF_CTRL:
  415.                     {
  416.                         char *ptr = text + win->edpos;
  417.  
  418.                         if (*ptr) {
  419.                             while (*(++ptr))
  420.                                 if (isalnum(*ptr) && !isalnum(*(ptr - 1)))
  421.                                     break;
  422.  
  423.                             edit_pos(win, (int) (ptr - text));
  424.                         }
  425.                     }
  426.                     break;
  427.  
  428.                 case NK_LEFT | NKF_CTRL:
  429.                     if (win->edpos) {
  430.                         char *ptr = text + win->edpos;
  431.  
  432.                         while (text != --ptr)
  433.                             if (!isalnum(*ptr) && text != ptr - 1)
  434.                                 if (isalnum(*(ptr - 1)))
  435.                                     break;
  436.  
  437.                         edit_pos(win, (int) (ptr - text));
  438.                     }
  439.                     break;
  440.  
  441.                 case NK_LEFT:
  442.                     {
  443.                         int pos = win->edpos;
  444.  
  445.                         pos--;
  446.                         if (pos<0) pos = 0;
  447.                         edit_pos(win, pos);
  448.                     }
  449.                     break;
  450.  
  451.                 case NK_RIGHT:
  452.                     {
  453.                         int pos = win->edpos;
  454.  
  455.                         pos++;
  456.                         if (pos>(int) strlen(text)) pos = (int) strlen(text);
  457.                         edit_pos(win, pos);
  458.                     }
  459.                     break;
  460.  
  461.                 case NK_UP | NKF_LSH:
  462.                 case NK_UP | NKF_RSH:
  463.                 case NK_CLRHOME:
  464.                     {
  465.                         int prev = win->edobject;
  466.                         int storage;
  467.  
  468.                         storage = FirstEdit(win->tree);
  469.                         if (storage == prev) {
  470.                             win->edobject = prev;
  471.                             edit_pos(win, 0);
  472.                         } else {
  473.                             WObjc_Edit(win, ED_END, 0, 0);
  474.                             win->edobject = storage;
  475.                             win->edpos = (int) strlen(win->tree[win->edobject].ob_spec.tedinfo->te_ptext);
  476.                             WObjc_Edit(win, ED_INIT, 0, 0);
  477.                         }
  478.                     }
  479.                     break;
  480.  
  481.                 case NK_CLRHOME | NKF_LSH:
  482.                 case NK_CLRHOME | NKF_RSH:
  483.                 case NK_DOWN | NKF_LSH:
  484.                 case NK_DOWN | NKF_RSH:
  485.                     {
  486.                         int prev = win->edobject;
  487.                         int    storage;
  488.  
  489.                         storage = LastEdit(win->tree);
  490.                         if (storage == prev) {
  491.                             win->edobject = prev;
  492.                             edit_pos(win, 0);
  493.                         } else {
  494.                             WObjc_Edit(win, ED_END, 0, 0);
  495.                             win->edobject = storage;
  496.                             win->edpos = (int) strlen(win->tree[win->edobject].ob_spec.tedinfo->te_ptext);
  497.                             WObjc_Edit(win, ED_INIT, 0, 0);
  498.                         }
  499.                     }
  500.                     break;
  501.  
  502.                 case NK_INS:
  503.                     WGrafMouse(ARROW);
  504.                     {
  505. /*                        int edittype = WFind_EditType(win);
  506.                         *nchr = (char) WAscii_Table(edittype); */
  507.                         WObjc_Edit(win, ED_END, 0, 0);
  508.  
  509.                         if (win->editmode == EDIT_INSERT)
  510.                             win->editmode = EDIT_REPLACE;
  511.                         else
  512.                             win->editmode = EDIT_INSERT;
  513.  
  514.                         WObjc_Edit(win, ED_INIT, 0, 0);
  515.                     }
  516.                     break;
  517.  
  518.                 default:
  519.                     *nchr = key;
  520.                     break;
  521.             }
  522.         }
  523.  
  524.         *nobj = win->edobject;
  525.  
  526.         return TRUE;
  527.     } else
  528.         return TRUE;
  529. }