home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / GNU_C++ / LIB / CFLIB-11.LZH / src / form_do.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-03  |  8.0 KB  |  368 lines

  1. /*
  2.  * form_do.c
  3.  *
  4.  * Ein eigener form_do(), der einige Sondertastentasten kann:
  5.  *        HELP                Button mit Flag11
  6.  *        UNDO                Button mit Flag12
  7.  *     ^C^V^X            Klemmbrett in Editfeldern
  8.  *        ALT-X                MagiC-Shortcut
  9.  *
  10.  */
  11. #include <ctype.h>
  12.  
  13. #ifdef __MINT__
  14. #include <macros.h>
  15. #include <osbind.h>
  16. #endif
  17.  
  18. #include "intern.h"
  19.  
  20.  
  21. static KEYTAB    *keytab = NULL;
  22. static KEY_CB    key_cb = NULL;
  23.  
  24. /*
  25.  * Editfeld suchen. Die Suche beginnt bei <obj>. Ist <obj> das erste oder 
  26.  * letzte wird ge'wrapped, also das letzte oder das erste geliefert.
  27. */
  28. int edit_valid(OBJECT *tree, int obj)
  29. {
  30.     return ((tree[obj].ob_flags & EDITABLE) && 
  31.             !((tree[obj].ob_flags & HIDETREE) || 
  32.               (tree[obj].ob_state & DISABLED)));
  33. }
  34.  
  35. int find_edit(OBJECT *tree, int obj, int mode)
  36. {
  37.     int    ret = 0, i = 0;
  38.     int    prev = 0, next = 0;
  39.     int    first = 0, last = 0;
  40.         
  41.     do
  42.     {
  43.         i++;
  44.         if (edit_valid(tree, i))
  45.         {
  46.             /* ersten merken */
  47.             if (first == 0)
  48.                 first = i;
  49.                 
  50.             if (i < obj)
  51.                 prev = i;
  52.             if ((next == 0) && (i > obj))
  53.                 next = i;
  54.  
  55.             /* enthält beim while-Ende den letzen */
  56.             last = i;                
  57.         }
  58.     } 
  59.     while (!(tree[i].ob_flags & LASTOB));
  60.  
  61.     if (prev == 0)
  62.         prev = last;
  63.  
  64.     if (next == 0)
  65.         next = first;
  66.  
  67.     switch (mode)
  68.     {
  69.         case FMD_FORWARD:
  70.             ret = next;
  71.             break;
  72.         
  73.         case FMD_BACKWARD:
  74.             ret = prev;
  75.             break;
  76.  
  77.         default:
  78.             debug("\find_edit: unbekannter Modus %d.\n", mode);
  79.     }
  80.  
  81.     return ret;
  82. }
  83.  
  84. /*
  85.  * Liefert das Objekt an (x,y), wenn es nicht DISABLED oder HIDETREE ist,
  86.  * sonst -1.
  87. */
  88. int cf_objc_find(OBJECT *tree, int start, int depth, int x, int y)
  89. {
  90.     int    obj;
  91.     
  92.     obj = objc_find(tree, start, depth, x, y);
  93.     if ((obj != -1) && ((tree[obj].ob_flags & HIDETREE) || (tree[obj].ob_state & DISABLED)))
  94.         obj = -1;
  95.     return obj;
  96. }
  97.  
  98. int find_shortcut(OBJECT *tree, int kstate, int kreturn)
  99. {
  100.     int    ret = -1;
  101.     int    scan;
  102.     
  103.     if (keytab == NULL)
  104.         keytab = (KEYTAB *)Keytbl((void*)-1, (void*)-1, (void*)-1);
  105.  
  106.     scan = (kreturn & 0xFF00) >> 8;
  107.  
  108.     if (scan == 0x62)                                                    /* HELP */
  109.         ret = find_flag(tree, FLAG12);
  110.  
  111.     else if (scan == 0x61)                                            /* UNDO */
  112.         ret = find_flag(tree, FLAG11);
  113.  
  114.     else if (kstate & K_ALT)                                        /* Shortcut */
  115.     {
  116.         int    pos, obj;
  117.         char    c;
  118.         char    ascii;
  119.  
  120.         obj = -1;
  121.         do
  122.         {
  123.             obj++;
  124.             pos = get_magx_shortcut(tree, obj, &c);
  125.             if (pos != -1)
  126.             {
  127.                 if ((scan >= 0x78) && (scan < 0x80))
  128.                     ascii = keytab->capslock[scan - 0x76];
  129.                 else
  130.                     ascii = keytab->capslock[scan];
  131.                 if (toupper(c) == ascii)
  132.                 {
  133.                     ret = obj;
  134.                     break;
  135.                 }
  136.             }
  137.         }
  138.         while (!(tree[obj].ob_flags & LASTOB));
  139.     }
  140.     if ((tree[ret].ob_flags & HIDETREE) || (tree[ret].ob_state & DISABLED))
  141.         ret = -1;
  142.     return ret;
  143. }
  144.  
  145. int cf_form_keybd(OBJECT *tree, int edit_obj, int kstate, int *kreturn, int *next_obj)
  146. {
  147.     int    cont = TRUE, obj;
  148.     int    scan;
  149.  
  150.     if (key_cb != NULL)
  151.     {
  152.         cont = (*key_cb)(tree, edit_obj, kstate, kreturn, next_obj);
  153.         if (!cont || *kreturn == 0)
  154.             return cont;
  155.         else
  156.             cont = TRUE;
  157.     }
  158.     
  159.     obj = find_shortcut(tree, kstate, *kreturn);
  160.     if (obj != -1)
  161.     {
  162.         *kreturn = 0;
  163.         cont = form_button(tree, obj, 1, next_obj);
  164.         return cont;
  165.     }
  166.  
  167.     scan = (*kreturn & 0xFF00) >> 8;
  168.  
  169.     cont = form_keybd(tree, edit_obj, *next_obj, *kreturn, next_obj, kreturn);
  170.  
  171.     /*
  172.      * Den eventuellen Wechsel des Editfelds mit Cursor/TAB übernehmen wir
  173.      * selbst, da das AES auch HIDDEN oder DISABLE Felder anspringt!
  174.      * Außerdem werten wir dann gleich noch Shift-TAB mit aus.
  175.     */    
  176.     if ((scan == 0x48) || ((kstate & K_SHIFT) && scan == 0x0F))        /* UP, ⇧TAB */
  177.         *next_obj = find_edit(tree, edit_obj, FMD_BACKWARD);
  178.     else if ((scan == 0x50) || (scan == 0x0F))                            /* DOWN, TAB */
  179.         *next_obj = find_edit(tree, edit_obj, FMD_FORWARD);
  180.  
  181.     return cont;
  182. }
  183.  
  184. void cf_objc_edit(OBJECT *tree, int obj, int kreturn, int *idx, int mode, int kstate, int *ctrl)
  185. {
  186.     if (!(tree[obj].ob_flags & EDITABLE))
  187.         return;
  188.  
  189.     if (mode == ED_CHAR)
  190.     {
  191.         int        scan, i;
  192.         long        l;
  193.         TEDINFO    *ted;
  194.         char        *ptext;
  195.         char        buf[80];
  196.                 
  197.         *ctrl = FALSE;
  198.  
  199.         ted = (TEDINFO *)get_obspec(tree, obj);
  200.         ptext    = ted->te_ptext;
  201.  
  202.         scan = (kreturn & 0xff00) >> 8;
  203.         if (kstate & K_CTRL)
  204.         {
  205.             switch (scan)
  206.             {
  207.                 case 0x2D:                            /* ^X -> Cut */
  208.                     scrap_wtxt(ptext);
  209.                     objc_edit(tree, obj, 0x11B, idx, ED_CHAR);        /* ESC: löschen */
  210.                     *ctrl = TRUE;
  211.                     break;
  212.                 
  213.                 case 0x2E:                            /* ^C -> Copy */
  214.                     scrap_wtxt(ptext);
  215.                     *ctrl = TRUE;
  216.                     break;
  217.                     
  218.                 case 0x2F:                            /* ^V -> Paste */
  219.                     objc_edit(tree, obj, 0x11B, idx, ED_CHAR);        /* ESC: löschen */
  220.                     scrap_rtxt(buf, &l, 80);
  221.                     for (i = 0; i < min(l, ted->te_txtlen-1); i++)
  222.                         objc_edit(tree, obj, buf[i], idx, ED_CHAR);
  223.                     *ctrl = TRUE;
  224.                     break;
  225.             }
  226.         }
  227.         else
  228.         {
  229.             switch (scan)
  230.             {
  231.                 case 0x52:                            /* INS -> ASCII-Tabelle */
  232. /*                    i = ascii_table(1, 13);*/
  233.                     i = ascii_table(sys_big_id, sys_big_pts);
  234.                     if (i > 0)
  235.                         kreturn = i & 0xff;
  236.                     break;
  237.             }
  238.         }
  239.     }
  240.     if (!(kstate & K_CTRL))                    /* keine Ctrl-Codes durchlassen */
  241.         objc_edit(tree, obj, kreturn, idx, mode);
  242. }
  243.  
  244.  
  245. int cf_form_do(OBJECT *tree, int *ed_start)
  246. {
  247.     int    edit_obj, cont, idx, next_obj;
  248.     int    m_x, m_y, m_button, breturn,
  249.             kstate, kreturn, which,    msg[8];
  250.     int    b, doppel = FALSE;
  251. #ifdef __MTAES__
  252.     EVNTDATA    ev;
  253.     GRECT        null = {0,0,0,0};
  254. #endif
  255.  
  256.     wind_update(BEG_MCTRL);
  257.     if ((ed_start == NULL) || (*ed_start == 0) || !edit_valid(tree, *ed_start))
  258.         next_obj = find_edit(tree, 0, FMD_FORWARD);
  259.     else
  260.         next_obj = *ed_start;
  261.     edit_obj = 0;
  262.     cont = TRUE;
  263.     while (cont)
  264.     {
  265.         if (next_obj && (edit_obj != next_obj))
  266.         {
  267.             edit_obj = next_obj;
  268.             next_obj = 0;
  269.             objc_edit(tree, edit_obj, 0, &idx, ED_INIT);
  270.         }
  271. #ifdef __MTAES__
  272.         which = evnt_multi(MU_KEYBD|MU_BUTTON,
  273.                                 2, 1, 1,
  274.                                 0, &null, 0, &null,
  275.                                 msg,
  276.                                 0L,
  277.                                 &ev, &kreturn, &breturn);
  278.         m_x = ev.x;
  279.         m_y = ev.y;
  280.         m_button = ev.bstate;
  281.         kstate = ev.kstate;
  282. #else
  283.         which = evnt_multi(MU_KEYBD|MU_BUTTON,
  284.                                 2, 1, 1,
  285.                                 0,0,0,0,0,0,0,0,0,0,
  286.                                 msg,
  287.                                 0L,
  288.                                 &m_x, &m_y,
  289.                                 &m_button, &kstate,
  290.                                 &kreturn, &breturn);
  291. #endif
  292.  
  293.         if (which & MU_KEYBD)
  294.         {
  295.             cont = cf_form_keybd(tree, edit_obj, kstate, &kreturn, &next_obj);
  296.             if (kreturn)
  297.                 cf_objc_edit(tree, edit_obj, kreturn, &idx, ED_CHAR, kstate, &b);
  298.         }
  299.         if (which & MU_BUTTON)
  300.         {
  301.             next_obj = cf_objc_find(tree, ROOT, MAX_DEPTH, m_x, m_y);
  302.             if (next_obj == -1)
  303.             {
  304.                 Bconout(2, 7);        /* beep */
  305.                 next_obj = 0;
  306.             }
  307.             else
  308.             {
  309.                 doppel = (breturn == 2);
  310.                 cont = form_button(tree, next_obj, breturn, &next_obj);
  311.             }
  312.         }
  313.         if (!cont || (next_obj && (next_obj != edit_obj)))
  314.             objc_edit(tree, edit_obj, 0, &idx, ED_END);
  315.     }
  316.  
  317.     if (ed_start != NULL)
  318.         *ed_start = edit_obj;
  319.     wind_update(END_MCTRL);
  320.  
  321.     if (doppel)
  322.         next_obj |= 0x8000;            /* bit 15 für Doppelklick */
  323.  
  324.     return next_obj;
  325. }
  326.  
  327. /* --------------------------------------------------------------------------- */
  328. int simple_dial(OBJECT *tree, int start_edit)
  329. {
  330.       int    exit_obj;
  331.     GRECT    r;
  332. #ifdef __MTAES__
  333.     GRECT    n = {0,0,0,0};
  334. #endif
  335.  
  336.     graf_mouse(ARROW, NULL);
  337.     wind_update(BEG_UPDATE);
  338. #ifdef __MTAES__
  339.     form_center(tree, &r);
  340.     form_dial(FMD_START, &n, &r);
  341.     graf_mouse(M_OFF, NULL);
  342.     objc_draw(tree, ROOT, MAX_DEPTH, &r); 
  343.     graf_mouse(M_ON, NULL);
  344.     exit_obj = cf_form_do(tree, &start_edit) & 0x7FFF;
  345.     form_dial(FMD_FINISH, &n, &r);
  346. #else
  347.     form_center(tree, &r.g_x, &r.g_y, &r.g_w, &r.g_h);
  348.     form_dial(FMD_START, 0, 0, 0, 0, r.g_x, r.g_y, r.g_w, r.g_h);
  349.     graf_mouse(M_OFF, NULL);
  350.     objc_draw(tree, ROOT, MAX_DEPTH, r.g_x, r.g_y, r.g_w, r.g_h); 
  351.     graf_mouse(M_ON, NULL);
  352.     exit_obj = cf_form_do(tree, &start_edit) & 0x7FFF;
  353.     form_dial(FMD_FINISH, 0, 0, 0, 0, r.g_x, r.g_y, r.g_w, r.g_h);
  354. #endif
  355.     wind_update(END_UPDATE);
  356.     set_state(tree, exit_obj, SELECTED, FALSE);
  357.     return exit_obj;
  358. }
  359.  
  360. KEY_CB set_formdo_keycb(KEY_CB new)
  361. {
  362.     KEY_CB    old;
  363.     
  364.     old = key_cb;
  365.     key_cb = new;
  366.     return old;
  367. }
  368.