home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 1 / FFMCD01.bin / bbs / libdisks / d700t799 / disk762.lha / PlotMap / source.lha / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-09  |  25.0 KB  |  943 lines

  1. /* routines for edit menu */
  2.  
  3. #include "PlotMap.h"
  4.  
  5. #define MIN_GRID_X 1
  6. #define MAX_GRID_X 30
  7. #define MIN_GRID_Y 1
  8. #define MAX_GRID_Y 30
  9.  
  10. #define GRID_X 1
  11. #define GRID_Y 2
  12. #define GRID_OK 3
  13. #define GRID_CANCEL 4
  14.  
  15. #define TEXT_STRING 1
  16. #define TEXT_OK 2
  17. #define TEXT_CANCEL 3
  18.  
  19. #define ANZ_FILL_OCEANS 12
  20.  
  21. /********** externals **********/
  22.  
  23. extern struct config config;
  24. extern struct TextAttr myfont;
  25. extern struct Screen *screen;
  26. extern struct RastPort *rp;
  27. extern PLANEPTR tmpras_mem;
  28. extern UWORD old_maptype;
  29. extern UWORD centerx, centery;
  30. extern double act_vfactor, m_vfactor;
  31. extern WORD box_x1, box_x2, box_y1, box_y2;
  32. extern APTR vinfo;
  33. extern struct Window *wd;
  34. extern struct Gadget *gad_list;
  35.  
  36. extern void refresh_coord(WORD, WORD);
  37. extern BOOL open_window(int, int, char *);
  38. extern void close_window(void);
  39.  
  40. /********** Variablen, Daten **********/
  41.  
  42. static WORD fill_oceans_lon[] =
  43. {
  44.    -60*60+0,
  45.    14*60+0,
  46.    6*60+0,
  47.    0*60+0,
  48.    30*60+0,
  49.    35*60+0,
  50.    37*60+0,
  51.    50*60+0,
  52.    5*60+0,
  53.    -5*60+0,
  54.    40*60+0,
  55.    52*60+0,
  56. };
  57.  
  58. static WORD fill_oceans_lat[] =
  59. {
  60.    40*60+0,
  61.    44*60+0,
  62.    40*60+0,
  63.    38*60+0,
  64.    35*60+0,
  65.    43*60+0,
  66.    46*60+0,
  67.    43*60+0,
  68.    55*60+0,
  69.    45*60+0,
  70.    17*60+0,
  71.    27*60+0,
  72. };
  73.  
  74. /********** Routinen **********/
  75.  
  76. static void swap(WORD *a, WORD *b)
  77. {
  78.    WORD h = *a;
  79.    *a = *b;
  80.    *b = h;
  81. }
  82.  
  83.  
  84. static void drawbox(WORD x1, WORD y1, WORD x2, WORD y2, BOOL filled)
  85. {
  86.    if (x1 > x2)                  /* get coords into the right order */
  87.       swap(&x1, &x2);
  88.    if (y1 > y2)
  89.       swap(&y1, &y2);
  90.  
  91.    if (filled)
  92.       RectFill(rp, x1,y1, x2,y2);
  93.    else
  94.    {
  95.       Line(rp, x1,y1, x2,y1);
  96.       if (y1 != y2)
  97.       {
  98.          LineTo(rp, x2,y2);
  99.          if (x1 != x2)
  100.          {
  101.             LineTo(rp, x1,y2);
  102.             LineTo(rp, x1,y1+1);
  103.          }
  104.       }
  105.    } /* else (filled) */
  106. }
  107.  
  108.  
  109. WORD calc_lon(WORD x)
  110. /* returns rounded longitude for screen coord x */
  111. {
  112.    LONG t = ((x - centerx) * (box_x2 - box_x1) << 1) / screen->Width +
  113.             ((box_x1 + box_x2) << 1) / 2;
  114.    if (t >= 0)
  115.       t = t + 1 >> 1;
  116.    else
  117.       t = t >> 1;
  118.    return((WORD)t);
  119. }
  120.  
  121.  
  122. WORD calc_lat(WORD y)
  123. /* returns rounded lattitude for screen coord y */
  124. {
  125.    LONG t = ( (LONG)((centery - y) * (box_y1 - box_y2) * act_vfactor)
  126.             << 1) / screen->Height + ((box_y2 + box_y1) << 1) / 2;
  127.    if (t >= 0)
  128.       t = t + 1 >> 1;
  129.    else
  130.       t = t >> 1;
  131.    return((WORD)t);
  132. }
  133.  
  134.  
  135. LONG calc_x(WORD lon)
  136. /* return rounded screen x-coord. for longitude lon */
  137. {
  138.    LONG t = ((lon - (box_x1 + box_x2) / 2) * screen->Width << 1) /
  139.             (box_x2 - box_x1);
  140.    if (t >= 0)
  141.       t = t + 1 >> 1;
  142.    else
  143.       t = t >> 1;
  144.    t += centerx;
  145.    return(t);
  146. }
  147.  
  148.  
  149. LONG calc_y(WORD lat)
  150. /* return rounded screen y-coord for. lattitude lat */
  151. {
  152.    LONG t = - ((lat - (box_y2 + box_y1) / 2) * screen->Height << 1) /
  153.             (box_y1 - box_y2) / act_vfactor;
  154.    if (t >= 0)
  155.       t = t + 1 >> 1;
  156.    else
  157.       t = t >> 1;
  158.    t += centery;
  159.    return(t);
  160. }
  161.  
  162.  
  163. static BOOL calc_box_coord(WORD x1, WORD y1, WORD x2, WORD y2)
  164. /* => FALSE: box too small, => TRUE: all ok */
  165. {
  166.    WORD b_x1, b_x2, b_y1, b_y2;
  167.  
  168.    if (x1 > x2)
  169.       swap(&x1, &x2);
  170.    if (y1 > y2)
  171.       swap(&y1, &y2);
  172.  
  173.    if ((x1 == x2) || (y1 == y2))
  174.    {
  175.       TITLE_ERROR("Box too small!");
  176.       return(FALSE);
  177.    }
  178.    else
  179.    {
  180.       b_x1 = calc_lon(x1);       /* nicht box_.. zuweisen, wird in */
  181.       b_x2 = calc_lon(x2);       /* calc_lon() gebraucht */
  182.       if ((old_maptype & MAP_MASK) == MAP_MERCATOR)
  183.       {
  184.          b_y1 = -90 + 2 * atan(exp((FLOAT)((centery - y1) / m_vfactor))) / RAD;
  185.          b_y2 = -90 + 2 * atan(exp((FLOAT)((centery - y2) / m_vfactor))) / RAD;
  186.       }
  187.       else
  188.       {
  189.          b_y1 = calc_lat(y1);
  190.          b_y2 = calc_lat(y2);
  191.       }
  192.       TITLE_NORMAL;
  193.  
  194.       box_x1 = b_x1;
  195.       box_x2 = b_x2;
  196.       box_y1 = b_y1;
  197.       box_y2 = b_y2;
  198.       return(TRUE);
  199.    }
  200. }
  201.  
  202.  
  203. void fill_oceans(void)
  204. /* fills oceans of current map with ocean color */
  205. {
  206.    UWORD i;
  207.    LONG x,y;
  208.  
  209.    if (!tmpras_mem)                       /* just for savety */
  210.    {
  211.       TITLE_ERROR("No TmpRas allocated, can`t fill oceans!");
  212.       return;
  213.    }
  214.    if (config.bg_color == config.ocean_color)
  215.    {
  216.       TITLE_ERROR("Background color = ocean color, can`t fill oceans!");
  217.       return;
  218.    }
  219.  
  220.    RMBTRAP_ON;
  221.    MOUSE_WAIT;
  222.    TITLE_MSG("Filling oceans, please wait");
  223.  
  224.    SetAPen(rp, config.ocean_color);
  225.    for (i = 0; i < ANZ_FILL_OCEANS; i++)
  226.    {
  227.       x = calc_x(fill_oceans_lon[i]);
  228.       y = calc_y(fill_oceans_lat[i]);
  229.       if (x >= 0 && x < screen->Width && y >= 0 && y < screen->Height)
  230.          if (ReadPixel(rp, x,y) == config.bg_color)
  231.             Flood(rp, 1, x,y);
  232.    } /* for (i) */
  233.  
  234.    TITLE_NORMAL;
  235.    MOUSE_NORMAL;
  236.    RMBTRAP_OFF;
  237. }
  238.  
  239.  
  240. static BOOL get_grid_steps(WORD *xstep, WORD *ystep)
  241. /* => TRUE: cancelled or error, => FALSE: all ok, draw grid */
  242. {
  243.    struct NewGadget new_gad;
  244.    struct Gadget *gad, *xstep_gad, *ystep_gad;
  245.    int font_h, char_w;
  246.    BOOL wd_ende = FALSE, ret = FALSE;
  247.  
  248.    font_h = myfont.ta_YSize;
  249.    char_w = TextLength(rp, "M", 1);
  250.  
  251.    gad_list = NULL;
  252.    gad = CreateContext(&gad_list);
  253.  
  254.    new_gad.ng_LeftEdge = screen->WBorLeft + 4 + 11*char_w;
  255.    new_gad.ng_TopEdge = screen->WBorTop + myfont.ta_YSize + 3;
  256.    new_gad.ng_Width = 90;
  257.    new_gad.ng_Height = font_h + 4;
  258.    new_gad.ng_GadgetText = "_XStep:    ";
  259.    new_gad.ng_GadgetID = GRID_X;
  260.    new_gad.ng_TextAttr = &myfont;
  261.    new_gad.ng_Flags = PLACETEXT_LEFT;
  262.    new_gad.ng_VisualInfo = vinfo;
  263.    new_gad.ng_UserData = NULL;
  264.    xstep_gad = gad = CreateGadget(SLIDER_KIND, gad, &new_gad,
  265.             GT_Underscore,'_',  GTSL_Min,MIN_GRID_X,  GTSL_Max,MAX_GRID_X,
  266.             GTSL_Level,*xstep,  GTSL_LevelFormat,"%2ld°",
  267.             GTSL_MaxLevelLen,3,  GA_RelVerify,TRUE,
  268.             TAG_DONE);
  269.  
  270.    new_gad.ng_TopEdge += font_h + 4 + INTERHEIGHT;
  271.    new_gad.ng_GadgetText = "_YStep:    ";
  272.    new_gad.ng_GadgetID = GRID_Y;
  273.    ystep_gad = gad = CreateGadget(SLIDER_KIND, gad, &new_gad,
  274.             GT_Underscore,'_',  GTSL_Min,MIN_GRID_Y,  GTSL_Max,MAX_GRID_Y,
  275.             GTSL_Level,*ystep,  GTSL_LevelFormat,"%2ld°",
  276.             GTSL_MaxLevelLen,3,  GA_RelVerify,TRUE,
  277.             TAG_DONE);
  278.  
  279.    new_gad.ng_LeftEdge -= 11*char_w;
  280.    new_gad.ng_TopEdge += font_h + 4 + INTERHEIGHT;
  281.    new_gad.ng_Width = 6*char_w + 8;
  282.    new_gad.ng_Height = font_h + 4;
  283.    new_gad.ng_GadgetText = "_Ok";
  284.    new_gad.ng_GadgetID = GRID_OK;
  285.    new_gad.ng_Flags = PLACETEXT_IN;
  286.    gad = CreateGadget(BUTTON_KIND, gad, &new_gad,
  287.             GT_Underscore,'_',  TAG_DONE);
  288.  
  289.    new_gad.ng_LeftEdge += 5*char_w + 82;
  290.    new_gad.ng_GadgetText = "_Cancel";
  291.    new_gad.ng_GadgetID = GRID_CANCEL;
  292.    gad = CreateGadget(BUTTON_KIND, gad, &new_gad,
  293.             GT_Underscore,'_',  TAG_DONE);
  294.  
  295.    if (!gad)
  296.    {
  297.       FreeGadgets(gad_list);
  298.       TITLE_ERROR("Can`t create gadgets!");
  299.       return(TRUE);
  300.    }
  301.  
  302.    if (!open_window(98 + 11*char_w, 3*font_h + 16 + 2*INTERHEIGHT,
  303.             "Select grid steps"))
  304.       return(TRUE);
  305.  
  306.    while (!wd_ende)
  307.    {
  308.       struct IntuiMessage *msg;
  309.       ULONG class;
  310.       UWORD code;
  311.  
  312.       WaitPort(wd->UserPort);
  313.       while (!wd_ende && (msg = GT_GetIMsg(wd->UserPort)))
  314.       {
  315.          class = msg->Class;
  316.          code = msg->Code;
  317.          gad = (struct Gadget *)msg->IAddress; /* need not to be a gadget! */
  318.          GT_ReplyIMsg(msg);
  319.  
  320.          switch (class)
  321.          {
  322.             case IDCMP_GADGETUP:
  323.                switch (gad->GadgetID)
  324.                {
  325.                   case GRID_X:
  326.                      *xstep = code;
  327.                      break;
  328.                   case GRID_Y:
  329.                      *ystep = code;
  330.                      break;
  331.                   case GRID_OK:
  332.                      wd_ende = TRUE;
  333.                      break;
  334.                   case GRID_CANCEL:
  335.                      wd_ende = TRUE;
  336.                      ret = TRUE;
  337.                      break;
  338.                } /* switch (GadgetID) */
  339.                break;
  340.             case IDCMP_VANILLAKEY:
  341.                switch (code)
  342.                {
  343.                   case 'x':
  344.                      if (++*xstep > MAX_GRID_X)
  345.                         *xstep = MAX_GRID_X;
  346.                      GT_SetGadgetAttrs(xstep_gad, wd, NULL,
  347.                            GTSL_Level,*xstep,  TAG_DONE);
  348.                      break;
  349.                   case 'X':
  350.                      if (--*xstep < MIN_GRID_X)
  351.                         *xstep = MIN_GRID_X;
  352.                      GT_SetGadgetAttrs(xstep_gad, wd, NULL,
  353.                            GTSL_Level,*xstep,  TAG_DONE);
  354.                      break;
  355.                   case 'y':
  356.                      if (++*ystep > MAX_GRID_Y)
  357.                         *ystep = MAX_GRID_Y;
  358.                      GT_SetGadgetAttrs(ystep_gad, wd, NULL,
  359.                            GTSL_Level,*ystep,  TAG_DONE);
  360.                      break;
  361.                   case 'Y':
  362.                      if (--*ystep < MIN_GRID_Y)
  363.                         *ystep = MIN_GRID_Y;
  364.                      GT_SetGadgetAttrs(ystep_gad, wd, NULL,
  365.                            GTSL_Level,*ystep,  TAG_DONE);
  366.                      break;
  367.                   case 'o':
  368.                   case 'O':
  369.                      wd_ende = TRUE;
  370.                      break;
  371.                   case 'c':
  372.                   case 'C':
  373.                      wd_ende = TRUE;
  374.                      ret = TRUE;
  375.                      break;
  376.                } /* switch (code) */
  377.                break;
  378.             case IDCMP_REFRESHWINDOW:
  379.                GT_BeginRefresh(wd);
  380.                GT_EndRefresh(wd, TRUE);
  381.                break;
  382.          } /* switch (class) */
  383.       } /* while (GT_GetIMsg) */
  384.    } /* while (!wd_ende) */
  385.  
  386.    close_window();
  387.    if (ret)
  388.       TITLE_ERROR("Draw grid cancelled");
  389.    return(ret);
  390. }
  391.  
  392.  
  393. void draw_grid(void)
  394. /* draw grid on curr. map */
  395. {
  396.    WORD lon,lat;
  397.    static WORD xstep=15,ystep=15;
  398.    LONG x1,x2,y1,y2;
  399.  
  400.    if (get_grid_steps(&xstep, &ystep))
  401.       return;
  402.  
  403.    RMBTRAP_ON;
  404.    MOUSE_WAIT;
  405.    TITLE_MSG("Drawing grid, please wait");
  406.  
  407.    y1 = max(0, calc_y(90*60));
  408.    y2 = min(screen->Height-1, calc_y(-90*60));
  409.    for (lon = 0; lon <= 180*60; lon += xstep*60)
  410.    {
  411.       if (lon == 0)
  412.          SetAPen(rp, config.gridhigh_color);
  413.       else
  414.          SetAPen(rp, config.grid_color);
  415.  
  416.       x1 = calc_x(lon);
  417.       if (x1 >= 0 && x1 < screen->Width)
  418.          Line(rp, x1,y1, x1,y2);
  419.    }
  420.    for (lon = 0; lon >= -180*60; lon -= xstep*60)
  421.    {
  422.       if (lon == 0)
  423.          SetAPen(rp, config.gridhigh_color);
  424.       else
  425.          SetAPen(rp, config.grid_color);
  426.  
  427.       x1 = calc_x(lon);
  428.       if (x1 >= 0 && x1 < screen->Width)
  429.          Line(rp, x1,y1, x1,y2);
  430.    }
  431.  
  432.    x1 = max(0, calc_x(-180*60));
  433.    x2 = min(screen->Width-1, calc_x(180*60));
  434.    for (lat = 0; lat <= 90*60; lat += ystep*60)
  435.    {
  436.       if (lat == 0)
  437.          SetAPen(rp, config.gridhigh_color);
  438.       else
  439.          SetAPen(rp, config.grid_color);
  440.  
  441.       y1 = calc_y(lat);
  442.       if (y1 >= 0 && y1 < screen->Height)
  443.          Line(rp, x1,y1, x2, y1);
  444.    }
  445.    for (lat = 0; lat >= -90*60; lat -= ystep*60)
  446.    {
  447.       if (lat == 0)
  448.          SetAPen(rp, config.gridhigh_color);
  449.       else
  450.          SetAPen(rp, config.grid_color);
  451.  
  452.       y1 = calc_y(lat);
  453.       if (y1 >= 0 && y1 < screen->Height)
  454.          Line(rp, x1,y1, x2, y1);
  455.    }
  456.  
  457.    TITLE_NORMAL;
  458.    MOUSE_NORMAL;
  459.    RMBTRAP_OFF;
  460. }
  461.  
  462.  
  463. void draw_shadow(void)
  464. /* shadow curr. map */
  465. {
  466.  
  467.    RMBTRAP_ON;
  468.    MOUSE_WAIT;
  469.    TITLE_MSG("Drawing shadow, please wait");
  470.  
  471.  
  472.    TITLE_NORMAL;
  473.    MOUSE_NORMAL;
  474.    RMBTRAP_OFF;
  475. }
  476.  
  477.  
  478. void draw_line(void)
  479. {
  480.    struct IntuiMessage *msg;
  481.    ULONG class;
  482.    UWORD code;
  483.    WORD mx=0,my=0, x1=-1,y1=-1, oldx,oldy;
  484.    BOOL draw_ende = FALSE;
  485.  
  486.    IDCMP(IDCMP_INTUITICKS | IDCMP_MOUSEBUTTONS);
  487.    RMBTRAP_ON;
  488.    MOUSE_CROSS;
  489.    TITLE_MSG("Draw line: press LMB, move mouse, release LMB; RMB = cancel");
  490.    SetDrMd(rp, COMPLEMENT);
  491.    SetWrMsk(rp, 0x01);
  492.  
  493.    while(!draw_ende)
  494.    {
  495.       WaitPort(main_wd->UserPort);
  496.       while (!draw_ende && (msg = (struct IntuiMessage *)GetMsg(main_wd->UserPort)))
  497.       {
  498.          class = msg->Class;
  499.          code = msg->Code;
  500.          oldx = mx;
  501.          oldy = my;
  502.          mx = msg->MouseX;
  503.          my = msg->MouseY;
  504.          ReplyMsg((struct Message *)msg);
  505.  
  506.          switch (class)
  507.          {
  508.             case IDCMP_INTUITICKS:
  509.                if ((mx != oldx) || (my != oldy))      /* avoid flicker */
  510.                {
  511.                   if (x1 != -1)
  512.                   {
  513.                      Line(rp, x1,y1, oldx,oldy);      /* delete old line */
  514.                      mx = main_wd->MouseX;
  515.                      my = main_wd->MouseY;
  516.                      Line(rp, x1,y1, mx,my);          /* draw new line */
  517.                   }
  518.                   refresh_coord(mx,my);
  519.                }
  520.                break;
  521.             case IDCMP_MOUSEBUTTONS:
  522.                switch (code)
  523.                {
  524.                   case SELECTDOWN:
  525.                      oldx = x1 = mx;
  526.                      oldy = y1 = my;
  527.                      WritePixel(rp, x1,y1);     /* set first point */
  528.                      break;
  529.                   case SELECTUP:
  530.                      if (x1 != -1)  /* MB might be pressed on RELVERIFY- */
  531.                      {              /* gad but released somewhere else */
  532.                         Line(rp, x1,y1, oldx,oldy);   /* delete old line */
  533.                         SetAPen(rp, config.line_color);
  534.                         SetDrMd(rp, JAM2);
  535.                         SetWrMsk(rp, 0xff);
  536.                         Line(rp, x1,y1, mx,my);
  537.                         draw_ende = TRUE;
  538.                         TITLE_NORMAL;
  539.                      }
  540.                      break;
  541.                   case MENUDOWN:
  542.                      if (x1 != -1)
  543.                         Line(rp, x1,y1, oldx,oldy);   /* delete old line */
  544.                      draw_ende = TRUE;
  545.                      TITLE_ERROR("Draw line cancelled");
  546.                      break;
  547.                } /* switch (code) */
  548.                break;
  549.          } /* switch (class) */
  550.       } /* while (GetMsg()) */
  551.    } /* while (!draw_ende) */
  552.  
  553.    SetWrMsk(rp, 0xff);
  554.    SetDrMd(rp, JAM2);
  555.    MOUSE_NORMAL;
  556.    RMBTRAP_OFF;
  557.    IDCMP(NORMAL_IDCMP);
  558. }
  559.  
  560.  
  561. BOOL draw_box(BOOL flag, int selectbox)
  562. /* => FALSE if selected box was too small or cancelled, else => TRUE */
  563. {
  564.    struct IntuiMessage *msg;
  565.    ULONG class;
  566.    UWORD code;
  567.    WORD mx=0,my=0, x1=-1,y1=-1, oldx,oldy;
  568.    BOOL draw_ende = FALSE, ret = TRUE;
  569.  
  570.    IDCMP(IDCMP_INTUITICKS | IDCMP_MOUSEBUTTONS);
  571.    RMBTRAP_ON;
  572.    MOUSE_CROSS;
  573.    if (selectbox > 0)
  574.       TITLE_MSG("Select box: press LMB, move mouse, release LMB; RMB = cancel");
  575.    else
  576.       TITLE_MSG("Draw box: press LMB, move mouse, release LMB; RMB = cancel");
  577.    SetDrMd(rp, COMPLEMENT);
  578.    SetWrMsk(rp, 0x01);                          /* for a bit more speed */
  579.  
  580.    while(!draw_ende)
  581.    {
  582.       WaitPort(main_wd->UserPort);
  583.       while (!draw_ende && (msg = (struct IntuiMessage *)GetMsg(main_wd->UserPort)))
  584.       {
  585.          class = msg->Class;
  586.          code = msg->Code;
  587.          oldx = mx;
  588.          oldy = my;
  589.          mx = msg->MouseX;
  590.          my = msg->MouseY;
  591.          ReplyMsg((struct Message *)msg);
  592.  
  593.          if ((selectbox == 1) && (x1 != -1))       /* ohne Verzerrungen */
  594.          {
  595.             WORD box_w, box_h;
  596.             box_w = abs(mx - x1);
  597.             box_h = ((box_w * screen->Height << 1) / screen->Width + 1) >> 1;
  598.             if (my >= y1)
  599.                my = y1 + box_h;
  600.             else
  601.                my = y1 - box_h;
  602.          }
  603.  
  604.          switch (class)
  605.          {
  606.             case IDCMP_INTUITICKS:
  607.                if ((mx != oldx) || (my != oldy))      /* avoid flicker */
  608.                {
  609.                   if (x1 != -1)
  610.                   {
  611.                      drawbox(x1,y1, oldx,oldy, flag);
  612.                      if (selectbox != 1)
  613.                      {
  614.                         mx = main_wd->MouseX;
  615.                         my = main_wd->MouseY;
  616.                      }
  617.                      drawbox(x1,y1, mx,my, flag);
  618.                   } /* if () */
  619.                   refresh_coord(mx,my);
  620.                }
  621.                break;
  622.             case IDCMP_MOUSEBUTTONS:
  623.                switch (code)
  624.                {
  625.                   case SELECTDOWN:
  626.                      oldx = x1 = mx;
  627.                      oldy = y1 = my;
  628.                      WritePixel(rp, x1,y1);     /* set first point */
  629.                      break;
  630.                   case SELECTUP:
  631.                      if (x1 != -1)
  632.                      {
  633.                         drawbox(x1,y1, oldx,oldy, flag);
  634.                         SetAPen(rp, config.box_color);
  635.                         SetDrMd(rp, JAM2);
  636.                         SetWrMsk(rp, 0xff);
  637.                         if (selectbox > 0)
  638.                            ret = calc_box_coord(x1,y1, mx,my);
  639.                         else
  640.                         {
  641.                            drawbox(x1,y1, mx,my, flag);
  642.                            TITLE_NORMAL;
  643.                         }
  644.                         draw_ende = TRUE;
  645.                      }
  646.                      break;
  647.                   case MENUDOWN:
  648.                      if (x1 != -1)
  649.                         drawbox(x1,y1, oldx,oldy, flag);
  650.                      draw_ende = TRUE;
  651.                      ret = FALSE;
  652.                      if (selectbox > 0)
  653.                      {  /* { } must be here */
  654.                         TITLE_ERROR("Select box cancelled");
  655.                      }
  656.                      else
  657.                         TITLE_ERROR("Draw box cancelled");
  658.                      break;
  659.                } /* switch (code) */
  660.                break;
  661.          } /* switch (class) */
  662.       } /* while (GetMsg()) */
  663.    } /* while (!draw_ende) */
  664.  
  665.    SetWrMsk(rp, 0xff);
  666.    SetDrMd(rp, JAM2);
  667.    MOUSE_NORMAL;
  668.    RMBTRAP_OFF;
  669.    IDCMP(NORMAL_IDCMP);
  670.    return(ret);
  671. }
  672.  
  673.  
  674. static BOOL get_text(char *str)
  675. /* => TRUE: cancelled, => FALSE: all ok, print text */
  676. {
  677.    struct NewGadget new_gad;
  678.    struct Gadget *gad, *str_gad;
  679.    int font_h, char_w;
  680.    BOOL wd_ende = FALSE, ret = FALSE;
  681.  
  682.    font_h = myfont.ta_YSize;
  683.    char_w = TextLength(rp, "M", 1);
  684.  
  685.    gad_list = NULL;
  686.    gad = CreateContext(&gad_list);
  687.  
  688.    new_gad.ng_LeftEdge = screen->WBorLeft + 4 + 6*char_w;
  689.    new_gad.ng_TopEdge = screen->WBorTop + myfont.ta_YSize + 3;
  690.    new_gad.ng_Width = 20*char_w + 12;
  691.    new_gad.ng_Height = font_h + 6;
  692.    new_gad.ng_GadgetText = "_Text:";
  693.    new_gad.ng_GadgetID = TEXT_STRING;
  694.    new_gad.ng_TextAttr = &myfont;
  695.    new_gad.ng_Flags = PLACETEXT_LEFT;
  696.    new_gad.ng_VisualInfo = vinfo;
  697.    new_gad.ng_UserData = NULL;
  698.    str_gad = gad = CreateGadget(STRING_KIND, gad, &new_gad,
  699.             GT_Underscore,'_',  GTST_String,str,  GTST_MaxChars,79,
  700.             TAG_DONE);
  701.  
  702.    new_gad.ng_LeftEdge -= 6*char_w;
  703.    new_gad.ng_TopEdge += font_h + 6 + INTERHEIGHT;
  704.    new_gad.ng_Width = 6*char_w + 8;
  705.    new_gad.ng_Height = font_h + 4;
  706.    new_gad.ng_GadgetText = "_Ok";
  707.    new_gad.ng_GadgetID = TEXT_OK;
  708.    new_gad.ng_Flags = PLACETEXT_IN;
  709.    gad = CreateGadget(BUTTON_KIND, gad, &new_gad,
  710.             GT_Underscore,'_',  TAG_DONE);
  711.  
  712.    new_gad.ng_LeftEdge += 20*char_w + 4;
  713.    new_gad.ng_GadgetText = "_Cancel";
  714.    new_gad.ng_GadgetID = TEXT_CANCEL;
  715.    gad = CreateGadget(BUTTON_KIND, gad, &new_gad,
  716.             GT_Underscore,'_',  TAG_DONE);
  717.  
  718.    if (!gad)
  719.    {
  720.       FreeGadgets(gad_list);
  721.       TITLE_ERROR("Can`t create gadgets!");
  722.       return(TRUE);
  723.    }
  724.  
  725.    if (!open_window(26*char_w + 12 + 8, 2*font_h + 10 + INTERHEIGHT + 4,
  726.                      "Enter text"))
  727.       return(TRUE);
  728.  
  729.    while (!wd_ende)
  730.    {
  731.       struct IntuiMessage *msg;
  732.       ULONG class;
  733.       UWORD code;
  734.  
  735.       WaitPort(wd->UserPort);
  736.       while (!wd_ende && (msg = GT_GetIMsg(wd->UserPort)))
  737.       {
  738.          class = msg->Class;
  739.          code = msg->Code;
  740.          gad = (struct Gadget *)msg->IAddress; /* need not to be a gadget! */
  741.          GT_ReplyIMsg(msg);
  742.  
  743.          switch (class)
  744.          {
  745.             case IDCMP_ACTIVEWINDOW:
  746.                ActivateGadget(str_gad, wd, NULL);
  747.                break;
  748.             case IDCMP_GADGETUP:
  749.                switch (gad->GadgetID)
  750.                {
  751.                   case TEXT_OK:
  752.                      wd_ende = TRUE;
  753.                      break;
  754.                   case TEXT_CANCEL:
  755.                      wd_ende = TRUE;
  756.                      ret = TRUE;
  757.                      break;
  758.                } /* switch (GadgetID) */
  759.                break;
  760.             case IDCMP_VANILLAKEY:
  761.                switch (code)
  762.                {
  763.                   case 't':
  764.                   case 'T':
  765.                      ActivateGadget(str_gad, wd, NULL);
  766.                      break;
  767.                   case 'o':
  768.                   case 'O':
  769.                      wd_ende = TRUE;
  770.                      break;
  771.                   case 'c':
  772.                   case 'C':
  773.                      wd_ende = TRUE;
  774.                      ret = TRUE;
  775.                      break;
  776.                } /* switch (code) */
  777.                break;
  778.             case IDCMP_REFRESHWINDOW:
  779.                GT_BeginRefresh(wd);
  780.                GT_EndRefresh(wd, TRUE);
  781.                break;
  782.          } /* switch (class) */
  783.       } /* while (GT_GetIMsg) */
  784.    } /* while (!wd_ende) */
  785.  
  786.    strcpy(str, ((struct StringInfo *)str_gad->SpecialInfo)->Buffer);
  787.    close_window();                  /* also frees gadgets */
  788.    if (ret)
  789.       TITLE_ERROR("Text cancelled");
  790.    return(ret);
  791. }
  792.  
  793. void text(void)
  794. {
  795.    struct IntuiMessage *msg;
  796.    ULONG class;
  797.    UWORD code;
  798.    WORD mx=0,my=0, oldx,oldy, txtlen;
  799.    static char txt[80] = "";
  800.    BOOL draw_ende = FALSE;
  801.  
  802.    if (get_text(txt))
  803.       return;
  804.    txtlen = strlen(txt);
  805.  
  806.    IDCMP(IDCMP_INTUITICKS | IDCMP_MOUSEBUTTONS);
  807.    RMBTRAP_ON;
  808.    MOUSE_CROSS;
  809.    TITLE_MSG("Text: LMB = put text, RMB = cancel");
  810.    SetDrMd(rp, JAM1 | COMPLEMENT);
  811.    SetWrMsk(rp, 0x01);
  812.  
  813.    while(!draw_ende)
  814.    {
  815.       WaitPort(main_wd->UserPort);
  816.       while (!draw_ende && (msg = (struct IntuiMessage *)GetMsg(main_wd->UserPort)))
  817.       {
  818.          class = msg->Class;
  819.          code = msg->Code;
  820.          oldx = mx;
  821.          oldy = my;
  822.          mx = msg->MouseX;
  823.          my = msg->MouseY;
  824.          ReplyMsg((struct Message *)msg);
  825.  
  826.          switch (class)
  827.          {
  828.             case IDCMP_INTUITICKS:
  829.                if ((mx != oldx) || (my != oldy))      /* avoid flicker */
  830.                {
  831.                   if (oldx != -1)               /* for first draw */
  832.                   {
  833.                      Move(rp, oldx,oldy);
  834.                      Text(rp, txt, txtlen);
  835.                   }
  836.                   mx = main_wd->MouseX;
  837.                   my = main_wd->MouseY;
  838.                   Move(rp, mx,my);
  839.                   Text(rp, txt, txtlen);
  840.                   refresh_coord(mx,my);
  841.                }
  842.                break;
  843.             case IDCMP_MOUSEBUTTONS:
  844.                switch (code)
  845.                {
  846.                   case SELECTDOWN:
  847.                      Move(rp, oldx,oldy);
  848.                      Text(rp, txt, txtlen);
  849.                      SetAPen(rp, config.text_color);
  850.                      SetDrMd(rp, JAM1);
  851.                      SetWrMsk(rp, 0xff);
  852.                      Move(rp, mx,my);
  853.                      Text(rp, txt, txtlen);
  854.                      draw_ende = TRUE;
  855.                      TITLE_NORMAL;
  856.                      break;
  857.                   case MENUDOWN:
  858.                      Move(rp, oldx,oldy);
  859.                      Text(rp, txt, txtlen);
  860.                      draw_ende = TRUE;
  861.                      TITLE_ERROR("Text cancelled");
  862.                      break;
  863.                } /* switch (code) */
  864.                break;
  865.          } /* switch (class) */
  866.       } /* while (GetMsg()) */
  867.    } /* while (!draw_ende) */
  868.  
  869.    SetWrMsk(rp, 0xff);
  870.    SetDrMd(rp, JAM2);
  871.    MOUSE_NORMAL;
  872.    RMBTRAP_OFF;
  873.    IDCMP(NORMAL_IDCMP);
  874. }
  875.  
  876.  
  877. void flood_fill(void)
  878. {
  879.    struct IntuiMessage *msg;
  880.    ULONG class;
  881.    UWORD code;
  882.    WORD mx=0,my=0, oldx,oldy;
  883.    BOOL draw_ende = FALSE;
  884.  
  885.    if (!tmpras_mem)                       /* just for savety */
  886.    {
  887.       TITLE_ERROR("No TmpRas allocated, can`t flood fill!");
  888.       return;
  889.    }
  890.  
  891.    IDCMP(IDCMP_INTUITICKS | IDCMP_MOUSEBUTTONS);
  892.    RMBTRAP_ON;
  893.    MOUSE_CROSS;
  894.    TITLE_MSG("Flood fill: LMB = fill, RMB = cancel");
  895.  
  896.    while(!draw_ende)
  897.    {
  898.       WaitPort(main_wd->UserPort);
  899.       while (!draw_ende && (msg = (struct IntuiMessage *)GetMsg(main_wd->UserPort)))
  900.       {
  901.          class = msg->Class;
  902.          code = msg->Code;
  903.          oldx = mx;
  904.          oldy = my;
  905.          mx = msg->MouseX;
  906.          my = msg->MouseY;
  907.          ReplyMsg((struct Message *)msg);
  908.  
  909.          switch (class)
  910.          {
  911.             case IDCMP_INTUITICKS:
  912.                if ((mx != oldx) || (my != oldy))
  913.                   refresh_coord(mx,my);
  914.                break;
  915.             case IDCMP_MOUSEBUTTONS:
  916.                switch (code)
  917.                {
  918.                   case SELECTDOWN:
  919.                      if (ReadPixel(rp, mx,my) != config.flood_color)
  920.                      {
  921.                         MOUSE_WAIT;
  922.                         SetAPen(rp, config.flood_color);
  923.                         Flood(rp, 1, mx,my);
  924.                      }
  925.                      draw_ende = TRUE;
  926.                      TITLE_NORMAL;
  927.                      break;
  928.                   case MENUDOWN:
  929.                      draw_ende = TRUE;
  930.                      TITLE_ERROR("Flood fill cancelled");
  931.                      break;
  932.                } /* switch (code) */
  933.                break;
  934.          } /* switch (class) */
  935.       } /* while (GetMsg()) */
  936.    } /* while (!draw_ende) */
  937.  
  938.    MOUSE_NORMAL;
  939.    RMBTRAP_OFF;
  940.    IDCMP(NORMAL_IDCMP);
  941. }
  942.  
  943.