home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / archivers / mpackppc-wos / src / macnte.c < prev    next >
C/C++ Source or Header  |  1998-04-27  |  12KB  |  453 lines

  1. /* macnte.c -- TextEdit Utilities for nifty application library
  2.  */
  3. /* (C) Copyright 1995 by Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software
  7.  * and its documentation for any purpose is hereby granted without
  8.  * fee, provided that the above copyright notice appear in all copies
  9.  * and that both that copyright notice and this permission notice
  10.  * appear in supporting documentation, and that the name of Carnegie
  11.  * Mellon University not be used in advertising or publicity
  12.  * pertaining to distribution of the software without specific,
  13.  * written prior permission.  Carnegie Mellon University makes no
  14.  * representations about the suitability of this software for any
  15.  * purpose.  It is provided "as is" without express or implied
  16.  * warranty.
  17.  *
  18.  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
  19.  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  20.  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
  21.  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  22.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  23.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  24.  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25.  * SOFTWARE.
  26.  */
  27. /* (C) Copyright 1990-1995 by Christopher J. Newman
  28.  * All Rights Reserved.
  29.  *
  30.  * Permission to use, copy, modify, distribute, and sell this software and its
  31.  * documentation for any purpose is hereby granted without fee, provided that
  32.  * the above copyright notice appear in all copies and that both that
  33.  * copyright notice and this permission notice appear in supporting
  34.  * documentation, and that the name of Christopher J. Newman not be used in
  35.  * advertising or publicity pertaining to distribution of the software without
  36.  * specific, written prior permission.  Christopher J. Newman makes no
  37.  * representations about the suitability of this software for any purpose.  It
  38.  * is provided "as is" without express or implied warranty.
  39.  *
  40.  * CHRISTOPHER J. NEWMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  41.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
  42.  * SHALL CHRISTOPHER J. NEWMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  43.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  44.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  45.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  46.  * OF THIS SOFTWARE.
  47.  *
  48.  * Author:    Christopher J. Newman
  49.  * Message:    This is a nifty program.
  50.  */
  51.  
  52. #include "macnapp.h"
  53. #ifndef THINK_C
  54. #include <Fonts.h>
  55. #include <Scrap.h>
  56. #include <ToolUtils.h>
  57. #endif
  58.  
  59. #define DOCWIDTH 2047
  60. #define teinfo    ((nate_win *)winp)
  61.  
  62. /* prototypes for private procedures */
  63. static pascal void vscroll(ControlHandle, short);
  64. static pascal void hscroll(ControlHandle, short);
  65.  
  66. /* initialize a premade window as a TextEdit window with options
  67.  */
  68. void NATEinit(na_win *winp, long flags, short docwidth, Ptr data, long len)
  69. {
  70.     Rect        rtemp, vtemp;
  71.     
  72.     winp->flags = (winp->flags & ~NATE_FLAGS) | flags;
  73.     if (!docwidth)    docwidth = DOCWIDTH;
  74.     teinfo->docwidth = docwidth;
  75.     rtemp = winp->pwin->portRect;
  76.     rtemp.top += teinfo->topoff;
  77.     vtemp = rtemp;
  78.     if (!(flags & NATE_NOHSCROLL)) {
  79.         vtemp.right = vtemp.left + docwidth;
  80.     }
  81.     if (!(flags & NATE_READONLY)) {
  82.         winp->keyp = NATEkeyp;
  83.     }
  84.     if (!(flags & NATE_NOMOUSE)) {    
  85.         winp->mousep = NATEmousep;
  86.         winp->idlep = NATEidlep;
  87.     }
  88.     winp->menup = NATEmenup;
  89.     winp->activep = NATEactivep;
  90.     winp->updatep = NATEupdatep;
  91.     winp->ctrlp = NATEctrlp;
  92.     winp->closep = NATEclosep;
  93.     winp->cursorRgn = NewRgn();
  94.     teinfo->vctrl = teinfo->hctrl = NULL;
  95.     
  96.     TEAutoView(true, teinfo->hTE = TENew(&vtemp, &rtemp));    
  97.     if (len > 0 && data != (Ptr) NULL) {
  98.         TESetText(data, len, teinfo->hTE);
  99.         TESetSelect(0, 0, teinfo->hTE);
  100.     }
  101.     teinfo->lheight = (*teinfo->hTE)->lineHeight;
  102. }
  103.  
  104. /* initialize a new TextEdit window
  105.  */
  106. short NATEinitp(na_win *winp, long *datap)
  107. #ifndef THINK_C
  108. #pragma unused (datap)
  109. #endif
  110. {
  111.     teinfo->topoff = 0;
  112.     NATEinit(winp, winp->flags, 0, NULL, 0);
  113.     
  114.     return (NA_PROCESSED);
  115. }
  116.  
  117. /* set the controls in the TextEdit window correctly
  118.  */
  119. void NATEsetscroll(na_win *winp, Boolean moved, Rect *hrect, Rect *vrect)
  120. {
  121.     short        vmax, vvalue, hmax, hvalue;
  122.     TEPtr        te = *teinfo->hTE;
  123.     ControlHandle    vctrl, hctrl;
  124.         
  125.  
  126.     vmax = te->nLines + (*(*te->hText + te->teLength - 1) == '\015' ? 1 : 0)
  127.         - (te->viewRect.bottom - te->viewRect.top) / teinfo->lheight;
  128.     hmax = (short) teinfo->docwidth - (te->viewRect.right - te->viewRect.left);
  129.     if (vmax < 0) vmax = 0;
  130.     if (hmax < 0) hmax = 0;
  131.     vvalue = (te->viewRect.top - te->destRect.top) / teinfo->lheight;
  132.     hvalue = te->viewRect.left - te->destRect.left;
  133.     if (!(winp->flags & NATE_NOVSCROLL)) {
  134.         if (teinfo->vctrl == (ControlHandle) NULL) {
  135.             teinfo->vctrl = NewControl(winp->pwin, vrect, "\p", true, vvalue, 0, vmax,
  136.                 scrollBarProc, 0);
  137.             if (winp->pwin != FrontWindow()) HiliteControl(teinfo->vctrl, 255);
  138.         } else {
  139.             if (vvalue < 0) vvalue = 0;
  140.             if (vvalue > vmax) vvalue = vmax;
  141.             SetCtlMax(vctrl = teinfo->vctrl, vmax);
  142.             SetCtlValue(vctrl, vvalue);
  143.             if (moved) {
  144.                 MoveControl(vctrl, vrect->left, vrect->top);
  145.                 SizeControl(vctrl, vrect->right - vrect->left,
  146.                     vrect->bottom - vrect->top);
  147.                 ShowControl(vctrl);
  148.             }
  149.         }
  150.     }
  151.     if (!(winp->flags & NATE_NOHSCROLL)) {
  152.         if (teinfo->hctrl == (ControlHandle) NULL) {
  153.             teinfo->hctrl = NewControl(winp->pwin, hrect, "\p", true, hvalue, 0, hmax,
  154.                 scrollBarProc, 0);
  155.             if (winp->pwin != FrontWindow()) HiliteControl(teinfo->hctrl, 255);
  156.         } else {
  157.             if (hvalue < 0) hvalue = 0;
  158.             if (hvalue > hmax) hvalue = hmax;
  159.             SetCtlMax(hctrl = teinfo->hctrl, hmax);
  160.             SetCtlValue(hctrl, hvalue);
  161.             if (moved) {
  162.                 MoveControl(hctrl, hrect->left, hrect->top);
  163.                 SizeControl(hctrl, hrect->right - hrect->left,
  164.                     hrect->bottom - hrect->top);
  165.                 ShowControl(hctrl);
  166.             }
  167.         }
  168.     }
  169. }
  170.  
  171. /* track procedure for the vertical scroll bar
  172.  */
  173. static pascal void vscroll(ControlHandle ctrl, short part)
  174. {
  175.     short        amount, value, max, lh;
  176.     na_win        *winp;
  177.     TEHandle    hTE;
  178.     
  179.     if (part == 0) return;
  180.     winp = * (na_win**) GetWRefCon((*ctrl)->contrlOwner);
  181.     hTE = teinfo->hTE;
  182.     value = ((*hTE)->viewRect.bottom - (*hTE)->viewRect.top) /
  183.         (lh = teinfo->lheight);
  184.     switch (part) {
  185.         case inUpButton:
  186.             amount = -1;
  187.             break;
  188.         case inDownButton:
  189.             amount = 1;
  190.             break;
  191.         case inPageUp:
  192.             amount = - value;
  193.             break;
  194.         case inPageDown:
  195.             amount = value;
  196.             break;
  197.     }
  198.     if ((amount += (value = GetCtlValue(ctrl))) < 0) amount = 0;
  199.     if (amount > (max = GetCtlMax(ctrl))) amount = max;
  200.     SetCtlValue(ctrl, amount);
  201.     TEScroll(0, (value - amount) * lh, hTE);
  202. }
  203.  
  204. /* track procedure for the horizontal scroll bar
  205.  */
  206. static pascal void hscroll(ControlHandle ctrl, short part)
  207. {
  208.     short        amount, value, max;
  209.     
  210.     if (part) {
  211.         TEHandle hTE = (* (nate_win**) GetWRefCon((*ctrl)->contrlOwner))->hTE;
  212.         
  213.         value = (*hTE)->viewRect.right - (*hTE)->viewRect.left;
  214.         switch (part) {
  215.             case inUpButton:
  216.                 amount = -6;
  217.                 break;
  218.             case inDownButton:
  219.                 amount = 6;
  220.                 break;
  221.             case inPageUp:
  222.                 amount = - value;
  223.                 break;
  224.             case inPageDown:
  225.                 amount = value;
  226.                 break;
  227.         }
  228.         if ((amount += (value = GetCtlValue(ctrl))) < 0) amount = 0;
  229.         if (amount > (max = GetCtlMax(ctrl))) amount = max;
  230.         SetCtlValue(ctrl, amount);
  231.         TEScroll(value - amount, 0, hTE);
  232.     }
  233. }
  234.  
  235. /* activate procedure for TextEdit
  236.  */
  237. short NATEactivep(na_win *winp, Boolean on)
  238. {
  239.     if (on) {
  240.         TEActivate(teinfo->hTE);
  241.     } else {
  242.         TEDeactivate(teinfo->hTE);
  243.     }
  244.     
  245.     return (NA_NOTPROCESSED);
  246. }
  247.  
  248. /* Update procedure for textedit window
  249.  */
  250. short NATEupdatep(na_win *winp, Boolean newsize)
  251. {
  252.     TEHandle    hTE = teinfo->hTE;
  253.     WindowPtr    window = winp->pwin;
  254.     Rect        prect, vrect, hrect, drect;
  255.     
  256.     prect = window->portRect;
  257.     prect.top += teinfo->topoff;
  258.     EraseRect(&prect);
  259.     hrect = vrect = prect;
  260.     vrect.top--;
  261.     hrect.left--;
  262.     vrect.left = ++vrect.right - 16;
  263.     hrect.top = ++hrect.bottom - 16;
  264.     vrect.bottom -= 14;
  265.     hrect.right -= 14;
  266.     InsetRect(&prect, 4, 4);
  267.     prect.right -= 15;
  268.     if (!(winp->flags & NATE_NOHSCROLL)) prect.bottom -= 15;
  269.     prect.bottom -= (prect.bottom - prect.top) % teinfo->lheight;
  270.     if (newsize) {
  271.         drect = (*hTE)->viewRect = prect;
  272.         drect.right = drect.left + (short) teinfo->docwidth;
  273.         (*hTE)->destRect = drect;
  274.         RectRgn(winp->cursorRgn, &prect);
  275.         OffsetRgn(winp->cursorRgn, -window->portBits.bounds.left,
  276.             -window->portBits.bounds.top);
  277.         TECalText(hTE);
  278.         TESelView(hTE);
  279.         if (teinfo->hctrl != (ControlHandle) NULL) HideControl(teinfo->hctrl);
  280.         if (teinfo->vctrl != (ControlHandle) NULL) HideControl(teinfo->vctrl);
  281.     }
  282.     TEUpdate(&prect, hTE);
  283.     if (newsize) NATEsetscroll(winp, true, &hrect, &vrect);
  284.     
  285.     return (NA_NOTPROCESSED);
  286. }
  287.  
  288. /* control processing procedure for TextEdit
  289.  */
  290. short NATEctrlp(na_win *winp, Point p, short part, short mods, ControlHandle ctrl)
  291. #ifndef THINK_C
  292. #pragma unused (mods)
  293. #endif
  294. {
  295.     short            value;
  296.     
  297.     if (part) {
  298.         value = GetCtlValue(ctrl);
  299.         switch (part) {
  300.             case inThumb:
  301.                 part = TrackControl(ctrl, p, (ProcPtr) NULL);
  302.                 if (part && (value -= GetCtlValue(ctrl))) {
  303.                     TEHandle    hTE = teinfo->hTE;
  304.                     
  305.                     if (ctrl == teinfo->vctrl) {
  306.                         TEScroll(0, value * teinfo->lheight, hTE);
  307.                     } else if (ctrl == teinfo->hctrl) {
  308.                         TEScroll(value, 0, hTE);
  309.                     }
  310.                 }
  311.                 break;
  312.             
  313.             default:
  314.                 (void) TrackControl(ctrl, p,
  315.                     (ProcPtr) (ctrl == teinfo->vctrl ? vscroll : hscroll));
  316.                 break;
  317.         }
  318.     }
  319.     
  320.     return (NA_PROCESSED);
  321. }
  322.  
  323. /* idle procedure for TextEdit
  324.  */
  325. short NATEidlep(na_win *winp)
  326. {
  327.     TEIdle(teinfo->hTE);
  328.     
  329.     return (NA_PROCESSED);
  330. }
  331.  
  332. /* key press procedure for TextEdit
  333.  */
  334. short NATEkeyp(na_win *winp, long c, short mods)
  335. {
  336.     short status = NA_NOTPROCESSED;
  337.     
  338.     if (!(mods & cmdKey)) {
  339.         status = NA_PROCESSED;
  340.         ObscureCursor();
  341.         TEKey(c, teinfo->hTE);
  342.         NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  343.     }
  344.     
  345.     return (status);
  346. }
  347.  
  348. /* an edit menu handler for TextEdit
  349.  */
  350. short NATEmenup(na_win *winp, WORD menuid, WORD itemno)
  351. {
  352.     MenuHandle    mh = NAmenuh(mEdit);
  353.     TEHandle    hTE = teinfo->hTE;
  354.     TEPtr        pte;
  355.     short        status = NA_NOTPROCESSED;
  356.     
  357.     switch (menuid) {
  358.         case 0:
  359.             pte = *hTE;
  360.             if (pte->selStart != pte->selEnd) {
  361.                 EnableItem(mh, iCopy);
  362.                 if (!(winp->flags & NATE_READONLY)) {
  363.                     EnableItem(mh, iCut);
  364.                     EnableItem(mh, iClear);
  365.                 }
  366.             } else {
  367.                 DisableItem(mh, iCopy);
  368.                 if (!(winp->flags & NATE_READONLY)) {
  369.                     DisableItem(mh, iCut);
  370.                     DisableItem(mh, iClear);
  371.                 }
  372.             }
  373.             EnableItem(mh, iSelAll);
  374.             if (!(winp->flags & NATE_READONLY)) {
  375.                 EnableItem(mh, iPaste);
  376.             }
  377.             break;
  378.  
  379.         case mEdit:
  380.             switch (itemno) {
  381.                 case iCut:
  382.                     TECut(hTE);
  383.                     goto DOSCRAP;
  384.                     
  385.                 case iCopy:
  386.                     TECopy(hTE);
  387.                 DOSCRAP:
  388.                     ZeroScrap();
  389.                     TEToScrap();
  390.                     goto EDITDONE;
  391.                     
  392.                 case iPaste:
  393.                     TEFromScrap();
  394.                     TEPaste(hTE);
  395.                     goto EDITDONE;
  396.                     
  397.                 case iClear:
  398.                     TEDelete(hTE);
  399.                     goto EDITDONE;
  400.                 
  401.                 case iSelAll:
  402.                     TESetSelect(0, 32767, hTE);
  403.                     TESelView(hTE);
  404.                 EDITDONE:
  405.                     status = NA_PROCESSED;
  406.                     NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  407.                     break;
  408.             }
  409.         default:
  410.             DisableItem(mh, iSelAll);
  411.             break;
  412.     }
  413.     
  414.     return (status);
  415. }
  416.  
  417. /* mouse procedure for TextEdit
  418.  */
  419. short NATEmousep(na_win *winp, Point p, short type, short mods)
  420. {
  421.     TEHandle    hTE = teinfo->hTE;
  422.     
  423.     if (!PtInRect(p, &(*hTE)->viewRect)) return (NA_NOTPROCESSED);
  424.     if (type == NA_DOWN1 || type == NA_DOWN2 || type == NA_DOWNN) {
  425.         TEClick(p, mods & shiftKey ? true : false, hTE);
  426.         NAmousetime = TickCount();
  427.         NAlastmouse++;
  428.     }
  429.     
  430.     return (NA_PROCESSED);
  431. }
  432.  
  433. /* close procedure for TextEdit
  434.  */
  435. short NATEclosep(na_win *winp)
  436. {
  437.     TEDispose(teinfo->hTE);
  438.     
  439.     return (NA_CLOSED);
  440. }
  441.  
  442. /* append text at the end of a TextEdit window
  443.  */
  444. void NATEappend(na_win *winp, char *data, long len)
  445. {
  446.     TEHandle    hTE = ((nate_win*) winp)->hTE;
  447.     
  448.     TESetSelect(32767, 32767, hTE);
  449.     TEInsert(data, len, hTE);
  450.     TESelView(hTE);
  451.     NATEsetscroll(winp, false, (Rect*) NULL, (Rect*) NULL);
  452. }
  453.