home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / gui / precog2_1.lha / Precognition2_1 / src / src.lha / Precognition / toolwindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-18  |  12.6 KB  |  485 lines

  1. #include "ToolWindow.h"
  2. #include "BuilderWindow.h"
  3. #include "BuilderMethods.h"
  4. #ifndef __GNUC__
  5. #include <clib/exec_protos.h>
  6. #include <clib/intuition_protos.h>
  7. #include <clib/graphics_protos.h>
  8. #endif
  9. #ifdef __GNUC__
  10. #include <proto/exec.h>
  11. #include <proto/intuition.h>
  12. #include <proto/graphics.h>
  13. #endif
  14. #ifdef __SASC
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <proto/graphics.h>
  18. #endif
  19. #include "amigamem.h"
  20. #include "project.h"
  21. #include "funclists.h"
  22.  
  23. #define BOB_WAITING  0
  24. #define BOB_DRAGGING 1
  25. #define KEYUP        0x80L
  26.  
  27. #define SELF &self->pw
  28.  
  29. extern struct MinList DeferredResponses;
  30.  
  31. void ToolWindow_BeSelfish( ToolWindow *self );
  32. void ToolWindow_DragBack( ToolWindow *self, short x, short y );
  33. void ToolWindow_StopDragging( ToolWindow *self );
  34.  
  35.  
  36. void ToolWindow_SetBobLocation( ToolWindow *self, PIXELS x, PIXELS y )
  37. {
  38.  
  39.    /* use Screen relative coordinates. */
  40.  
  41.    self->ibob.VSprite.X = x + self->offset.x;
  42.    self->ibob.VSprite.Y = y + self->offset.y;
  43.  
  44. }
  45.  
  46. void ToolWindow_StartDragging( ToolWindow *self, PIXELS x, PIXELS y )
  47. {
  48.    Point location;
  49.  
  50.    if( self->state == BOB_WAITING )
  51.    {
  52.       /* Install bob. */
  53.       if( InitImageBob( self->archetype, &self->ibob ) )
  54.       {
  55.          location = Location( (struct GraphicObject *)SELF );
  56.          self->offset.x = location.x - self->ibob.Image.Width  + 1;
  57.          self->offset.y = location.y - self->ibob.Image.Height + 1;
  58.          self->dragback.x = x;
  59.          self->dragback.y = y;
  60.  
  61.          /* printf("got image bob\n"); */
  62.          ToolWindow_SetBobLocation( self, x, y );
  63.          /* printf("set its location\n"); */
  64.  
  65.          AddBob( &self->ibob.Bob, self->GelsRPort );
  66.          /* printf("added bob to list.\n"); */
  67.          DrawGList( self->GelsRPort, self->GelsVPort );
  68.          /* printf("drew list.\n");  */
  69.          self->state = BOB_DRAGGING;
  70.  
  71.          self->IDCMPbuf = IDCMPFlags( (struct Interactor *)SELF );
  72.          SetIDCMPFlags( SELF, self->IDCMPbuf | MOUSEMOVE );
  73.  
  74.          Forbid();
  75.          self->pw.Window->Flags |= RMBTRAP; /* right mouse trap. */
  76.          Permit();
  77.  
  78.          QueueFunc( &DeferredResponses,
  79.                      (ptr2func) ToolWindow_BeSelfish, self );
  80.       }
  81.       else
  82.          printf( "couldn't get Imagery for %s\%n", ClassName( (struct PObject *)self->archetype ) );
  83.    }
  84. }
  85.  
  86. Window *ToolWindow_FindDropWindow( Screen *screen, short x, short y )
  87. /* NOTE: x&y are in SCREEN space, not WINDOW space! */
  88. {
  89.    Window *w;
  90.    Window *dropwindow = NULL;
  91.  
  92.    /* traverse screen's window list. */
  93.    Forbid();
  94.    for (w = screen->FirstWindow; w != NULL; w=w->NextWindow)
  95.    {
  96.       /* check for hit on this window */
  97.       if (  ( x >= w->LeftEdge ) && ( x < (w->LeftEdge + w->Width) )
  98.          && ( y >= w->TopEdge )  && ( y < (w->TopEdge + w->Height) ) )
  99.       {
  100.          dropwindow = w;
  101.          break;
  102.       }
  103.    }
  104.    Permit();
  105.  
  106.    return dropwindow;
  107. }
  108.  
  109. void ToolWindow_HandleDrop( ToolWindow *self, IntuiMessage *event )
  110. {
  111.    Screen         *screen;
  112.    Window         *dropwindow;
  113.    BuilderWindow  *bw;
  114.    GraphicObject  *new_object;
  115.    Point           p,
  116.                    location,
  117.                    size,
  118.                    drop_coords;
  119.    int drop_ok = FALSE;
  120.  
  121.    screen = self->pw.Window->WScreen;
  122.  
  123.    location = Location( (struct GraphicObject *)SELF );
  124.  
  125.    p.x = event->MouseX + location.x;
  126.    p.y = event->MouseY + location.y;
  127.  
  128.    dropwindow = ToolWindow_FindDropWindow( screen, p.x, p.y );
  129.    if (dropwindow)
  130.    {
  131.       bw = (BuilderWindow *)dropwindow->UserData;
  132.  
  133.       if( isa( (struct PObject *)bw, BuilderWindowClass() ) )
  134.       {
  135.          drop_ok = TRUE;
  136.       }
  137.       if( !drop_ok ) /* Window is not a BuilderWindow -- EDB */
  138.  
  139.          ToolWindow_DragBack( self, event->MouseX, event->MouseY );
  140.  
  141.    }
  142.    else /* If !dropwindow = no Window! return home -- EDB */
  143.    {
  144.       ToolWindow_DragBack( self, event->MouseX, event->MouseY );
  145.    }
  146.  
  147.    ToolWindow_StopDragging(self);
  148.  
  149.    if (drop_ok)
  150.    {
  151.       if( new_object = (struct GraphicObject *)New( (struct PObject *)self->archetype ) )
  152.       {
  153.          location      = Location( (struct GraphicObject *)bw );
  154.          size          = Size( new_object );
  155.          drop_coords.x = p.x - location.x - size.x +1;
  156.          drop_coords.y = p.y - location.y - size.y +1;
  157.          SetLocation( new_object, drop_coords.x, drop_coords.y );
  158.          BuilderWindow_AddPObject( bw, new_object );
  159.          Project_Modify();
  160.       }
  161.       else
  162.       {
  163.          printf("Couldn't copy archetype object %s\n",
  164.             ClassName( (struct PObject *)self->archetype ) );
  165.       }
  166.    }
  167.  
  168. }
  169.  
  170.  
  171. void ToolWindow_RemoveBob( ToolWindow *self )
  172. {
  173.    RemBob( &self->ibob.Bob );
  174.    DrawGList( self->GelsRPort, self->GelsVPort );
  175. }
  176.  
  177. void ToolWindow_CleanUpFromDragging( ToolWindow *self )
  178. {
  179.    RastPort *rport;
  180.    Point location, size;
  181.    ToolButton *button;
  182.  
  183.    SetIDCMPFlags( SELF, self->IDCMPbuf );
  184.  
  185.    Forbid();
  186.    self->pw.Window->Flags &= ~RMBTRAP; /* right mouse trap OFF. */
  187.    Permit();
  188.  
  189.    button = self->selected_button;
  190.    SetValue( (Valuator *)button, FALSE ); /* turn off button. */
  191.  
  192.    /* clear area of button to erase highlight. */
  193.    rport = RPort( &self->pw );
  194.    SetDrMd( rport, JAM1 );
  195.    SetAPen( rport, 0 );
  196.    location = Location( (struct GraphicObject *)button );
  197.    size     = Size( (struct GraphicObject *)button );
  198.  
  199.    RectFill( rport, location.x, location.y,
  200.             location.x+size.x-1, location.y+size.y-1 );
  201.  
  202.    Refresh( (struct Interactor *)button );
  203.  
  204.    /* release memory of image. */
  205.    CleanUpImageBob( self->archetype, &self->ibob );
  206.    self->state = BOB_WAITING;
  207. }
  208.  
  209. void ToolWindow_StopDragging( ToolWindow *self )
  210. {
  211.    if (self->state == BOB_DRAGGING)
  212.    {
  213.       ToolWindow_RemoveBob(self);
  214.       ToolWindow_CleanUpFromDragging(self);
  215.    }
  216. }
  217.  
  218.  
  219.  
  220. void ToolWindow_Drag( ToolWindow *self, short x, short y )
  221. {
  222.    if (self->state == BOB_DRAGGING)
  223.    {
  224.       ToolWindow_SetBobLocation( self, x, y );
  225.       DrawGList( self->GelsRPort, self->GelsVPort );
  226.    }
  227. }
  228.  
  229. #define CONVERGE_BY 20
  230. #define CONVERGE_ON(n,m) \
  231. if (n>m){ n -=((n>m+CONVERGE_BY)?CONVERGE_BY:n-m); } \
  232. else if (n<m){ n +=((n<m-CONVERGE_BY)?CONVERGE_BY:m-n); }
  233.  
  234. void ToolWindow_DragBack( ToolWindow *self, short x, short y )
  235. {
  236.    int home_x, home_y;
  237.  
  238.    home_x = self->dragback.x;
  239.    home_y = self->dragback.y;
  240.  
  241.    for(;;)
  242.    {
  243.       if (x == home_x && y== home_y) break;
  244.       ToolWindow_SetBobLocation( self, x, y );
  245.       DrawGList( self->GelsRPort, self->GelsVPort );
  246.       CONVERGE_ON(x, home_x);
  247.       CONVERGE_ON(y, home_y);
  248.       /* printf("Bob=(%d,%d), home=(%d,%d)\n", x,y, home_x, home_y );  */
  249.    }
  250.    /* Draw once more at home location */
  251.    ToolWindow_SetBobLocation( self, x, y );
  252.    DrawGList( self->GelsRPort, self->GelsVPort );
  253. }
  254.  
  255. USHORT ToolWindow_Respond( ToolWindow *self, IntuiMessage *event )
  256. {
  257.    USHORT response =0;
  258.    ToolButton *tb;
  259.  
  260.    if (event->IDCMPWindow == iWindow(&self->pw))
  261.    {
  262.       response |= RESPONDED;
  263.  
  264.       switch (event->Class)
  265.       {
  266.          case MOUSEMOVE:
  267.             ToolWindow_Drag( self, event->MouseX, event->MouseY );
  268.             break;
  269.  
  270.          case REFRESHWINDOW:
  271.             BeginRefresh( self->pw.Window );
  272.             Refresh( (struct Interactor *)&self->pw );
  273.             if (self->state == BOB_DRAGGING)
  274.                DrawGList( self->GelsRPort, self->GelsVPort );
  275.  
  276.             EndRefresh( self->pw.Window, TRUE );
  277.             break;
  278.  
  279.          case GADGETDOWN:
  280.             for (tb  = (ToolButton*) self->pw.FirstInteractor;
  281.                  tb != NULL;
  282.                  tb  = tb->Next)
  283.             {
  284.                if( Respond( (struct Interactor *)tb, event ) & CHANGED_STATE )
  285.                {
  286.                   /* start dragging. */
  287.                   self->selected_button = tb;
  288.                   self->archetype       = Archetype(tb);
  289.  
  290.  
  291.                   ToolWindow_StartDragging( self, event->MouseX, event->MouseY );
  292.                   break; /* end loop. */
  293.                }
  294.             }
  295.             break;
  296.  
  297.          case GADGETUP:
  298.             /* cancel. */
  299.                      if (self->state == BOB_DRAGGING)
  300.                      {
  301.                       ToolWindow_DragBack( self, event->MouseX, event->MouseY );
  302.                       ToolWindow_StopDragging( self );
  303.                      }
  304.                   break;
  305.  
  306.  
  307.          case MOUSEBUTTONS:
  308.             switch (event->Code)
  309.             {
  310.                case MENUDOWN:
  311.                   /* Cancel Movement. */
  312.                   ToolWindow_DragBack( self, event->MouseX, event->MouseY );
  313.                   ToolWindow_StopDragging( self );
  314.                   break;
  315.  
  316.                case SELECTUP:
  317.                   /* Accept Movement. */
  318.                   if (self->state == BOB_DRAGGING)
  319.                   {
  320.                      ToolWindow_HandleDrop( self, event );
  321.                   }
  322.                   break;
  323.             }
  324.             break;
  325.       }
  326.    }
  327.    return response;
  328. }
  329.  
  330.  
  331. Window *pcgWindow_OpenWindow( pcgWindow *self );
  332.  
  333. Window *ToolWindow_OpenWindow( ToolWindow *self )
  334. {
  335.    Window *w = NULL;
  336.  
  337.    if (w = pcgWindow_OpenWindow( &self->pw ))
  338.    {
  339.       /* Adjust size and location to window border. */
  340.       ;
  341.  
  342.       /* Initialize gels. */
  343.       self->GelsRPort   = &w->WScreen->RastPort;
  344.       self->GelsVPort   = &w->WScreen->ViewPort;
  345.       GelsSystem_Init( &self->gelssystem, self->GelsRPort, 0 );
  346.    }
  347.    return w;
  348. }
  349.  
  350. void ToolWindow_CleanUp( ToolWindow *self )
  351. {
  352.    Interactor *iactor;
  353.  
  354.    while ((iactor=self->pw.FirstInteractor) != NULL)
  355.    {
  356.       RemoveWindowPObject( (struct pcgWindow *)self, (struct GraphicObject *)iactor );
  357.       CleanUp( (struct PObject *)iactor );
  358.       Free( (struct PObject *)iactor );
  359.    }
  360. }
  361.  
  362.  
  363. BOOL ToolWindow_elaborated = FALSE;
  364.  
  365. struct pcgWindowClass ToolWindow_Class;
  366.  
  367. void ToolWindowClass_Init( struct pcgWindowClass *class )
  368. {
  369.    pcgWindowClass_Init( (struct pcgWindowClass *) class );
  370.    class->isa                 = pcgWindowClass();
  371.    class->ClassName           = "ToolWindow";
  372.    class->Respond             = (USHORT(*)(Interactor *, IntuiMessage *))ToolWindow_Respond;
  373.    class->OpenWindow          = (Window *(*)(pcgWindow *))ToolWindow_OpenWindow;
  374.    class->CleanUp             = (void(*)(PObject *))ToolWindow_CleanUp;
  375. }
  376.  
  377.  
  378. struct pcgWindowClass *ToolWindowClass( void )
  379. {
  380.    if( ! ToolWindow_elaborated )
  381.    {
  382.       ToolWindowClass_Init( &ToolWindow_Class );
  383.       ToolWindow_elaborated = TRUE;
  384.    }
  385.  
  386.    return &ToolWindow_Class;
  387. }
  388.  
  389.  
  390. void ToolWindow_AddArchetype( ToolWindow     *self,
  391.                               GraphicObject  *archetype )
  392. {
  393.    ToolButton *tb;
  394.    Point size, wsize;
  395.  
  396.    if (tb = (ToolButton*) Amalloc( sizeof(ToolButton) ) )
  397.    {
  398.       wsize = Size( (struct GraphicObject *)SELF );
  399.  
  400.       ToolButton_Init( tb, 4, self->y, wsize.x-8, self->pens, archetype );
  401.  
  402.       size     = Size( (struct GraphicObject *)tb );
  403.       self->y += size.y;
  404.  
  405.       SetSize( (struct GraphicObject *)SELF, wsize.x, self->y+2 );
  406.  
  407.       AddWindowPObject( (struct pcgWindow *)SELF, (struct GraphicObject *)tb );
  408.    }
  409.    else
  410.       printf("couldn't allocate toolbutton\n");
  411. }
  412.  
  413.  
  414.  
  415. void ToolWindow_Init( ToolWindow     *self,
  416.                       USHORT          leftedge,
  417.                       USHORT          topedge,
  418.                       Screen         *screen,
  419.                       struct MsgPort *SharedPort,
  420.                       pcg_3DPens      pens,
  421.                       char           *title )
  422. {
  423.  
  424.    pcgWindow_Init( &self->pw, leftedge, topedge, 120, 200, 1, 1, 65535, 65535, title,
  425.       REFRESHWINDOW | MOUSEBUTTONS | MENUPICK | MENUVERIFY,
  426.       SIMPLE_REFRESH | WINDOWDRAG | WINDOWDEPTH | REPORTMOUSE,
  427.       screen );
  428.  
  429.    self->pw.isa            = ToolWindowClass();
  430.    self->pw.SharedUserPort = SharedPort;
  431.  
  432.    self->state     = BOB_WAITING;
  433.    self->IDCMPbuf  = NULL;
  434.    self->GelsRPort = NULL;
  435.    self->GelsVPort = NULL;
  436.  
  437.    self->selected_button = NULL;
  438.    self->archetype       = NULL;
  439.  
  440.    self->y = 12;
  441.    self->pens = pens;
  442.    self->builder = NULL;
  443. }
  444.  
  445.  
  446. extern struct MsgPort *shared_port;
  447.  
  448. void ToolWindow_BeSelfish( ToolWindow *self )
  449. {
  450.    struct IntuiMessage *message, local_msg;
  451.    BOOL got_a_msg;
  452.  
  453.    while( self->state != BOB_WAITING )
  454.    {
  455.       got_a_msg = FALSE;
  456.  
  457.       for (;;) /* Strip all events from message queue. */
  458.       {
  459.          message = (struct IntuiMessage*) GetMsg( shared_port );
  460.  
  461.          if (message)
  462.          {
  463.             local_msg = *message;
  464.             ReplyMsg( (struct Message *)message );
  465.             /* EDB -- bug fix
  466.              * Need to respond to all messages or we lose GADGETUPs
  467.              * while dragging image.
  468.              */
  469.             ToolWindow_Respond( self, &local_msg );
  470.             got_a_msg = TRUE;
  471.          }
  472.          else /* No message */
  473.          {
  474.             if (got_a_msg) /* We responded to all of them */
  475.                {
  476.                break; /* Get out of for loop */
  477.                }
  478.             else           /* no message to respond to yet */
  479.                WaitPort( shared_port );
  480.          }
  481.       }
  482.    }
  483.  
  484. }
  485.