Author Topic: PCL: how do I get DynamicMouseMove called?  (Read 5788 times)

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
PCL: how do I get DynamicMouseMove called?
« on: 2009 May 05 21:16:37 »

Hi,

The code below never gets called even when I'm dragging the mouse over the active view. The same routine is used in the DynamicCrop module so I must be doing something wrong or missing some kind of flag. The PCL documentation doesn't mention any prerequisites.

Code: [Select]
void ProfileInterface::DynamicMouseMove( View& v, const DPoint& p, int button, unsigned buttons, unsigned modifiers )
{
   if ( button != MouseButton::Left )
      return;

   if ( view != 0 ) {
   if ( v != *view )
   return;
   if (dragging ) {
   // we're dragging, update the end of the line
pEnd =  p;
UpdateControls();
   }
   }
}



It seems I need to trap the MouseEnter event and set some flags but the code in DC is rather cryptic for what should be a simple operation:

Code: [Select]
   struct Flags
   {
      bool moving       :  1; // moving the cropping rectangle
      bool movingCenter :  1; // moving the center of rotation
      bool rotating     :  1; // rotating the cropping rectangle
      bool resizing     :  1; // resizing the cropping rectangle
      bool resizeLeft   :  1; // resizing on left edge
      bool resizeTop    :  1; // resizing on top edge
      bool resizeRight  :  1; // resizing on right edge
      bool resizeBottom :  1; // resizing on bottom edge
      int               : 24;

      Flags() { *reinterpret_cast<uint32*>( this ) = 0; }
      Flags( const Flags& x )
      { *reinterpret_cast<uint32*>( this ) = *reinterpret_cast<const uint32*>( &x ); }

      bool operator ==( const Flags& x ) const
      { return *reinterpret_cast<const uint32*>( this ) == *reinterpret_cast<const uint32*>( &x ); }
   };

and

Code: [Select]
void DynamicCropInterface::DynamicMouseEnter( View& v )
{
   if ( view == 0 || v != *view )
      return;

   // Force a dynamic cursor update upon subsequent mouse move event.
   flags = Flags();
}


Can this be simplified? It seems flags is used internally by the DC module and doesn't tell PI anything yet the comment suggests otherwise.

Thanks for any help.
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL: how do I get DynamicMouseMove called?
« Reply #1 on: 2009 May 06 00:57:49 »
Hi Sander,

Code: [Select]
void ProfileInterface::DynamicMouseMove( View& v, const DPoint& p, int button, unsigned buttons, unsigned modifiers )
The signature of this function is different from ProcessingInterface::DynamicMouseMove(). Hence, you're overloading that function with a non-virtual member function of your ProfileInterface class, which the core won't call because it doesn't know anything about it.

The correct signature is:

Code: [Select]
void ProfileInterface::DynamicMouseMove( View& v, const DPoint& p, unsigned buttons, unsigned modifiers )
where there is no "int button" argument (which doesn't make sense in a mouse move event handler). When reimplementing PCL's virtual functions, you must be careful not to overload them with different function signatures; the number, order and type of parameters must be exactly the same as in the original members.

Code: [Select]
   struct Flags
   {
      bool moving       :  1; // moving the cropping rectangle
      bool movingCenter :  1; // moving the center of rotation
      bool rotating     :  1; // rotating the cropping rectangle
      bool resizing     :  1; // resizing the cropping rectangle
      bool resizeLeft   :  1; // resizing on left edge
      bool resizeTop    :  1; // resizing on top edge
      bool resizeRight  :  1; // resizing on right edge
      bool resizeBottom :  1; // resizing on bottom edge
      int               : 24;

      Flags() { *reinterpret_cast<uint32*>( this ) = 0; }
      Flags( const Flags& x )
      { *reinterpret_cast<uint32*>( this ) = *reinterpret_cast<const uint32*>( &x ); }

      bool operator ==( const Flags& x ) const
      { return *reinterpret_cast<const uint32*>( this ) == *reinterpret_cast<const uint32*>( &x ); }
   };

Phew! :D Sorry, I usually tend to be a bit less cryptic. The above code is indeed tricky. But it has nothing to do with communication between the module and PI; it's just an internal control structure of DC.

This is a less wild version of the above code:

Code: [Select]
   union Flags
   {
      struct
      {
         bool moving       :  1; // moving the cropping rectangle
         bool movingCenter :  1; // moving the center of rotation
         bool rotating     :  1; // rotating the cropping rectangle
         bool resizing     :  1; // resizing the cropping rectangle
         bool resizeLeft   :  1; // resizing on left edge
         bool resizeTop    :  1; // resizing on top edge
         bool resizeRight  :  1; // resizing on right edge
         bool resizeBottom :  1; // resizing on bottom edge
         int               : 24;
      }
      bits;

      uint32 allBits;

      Flags() { allBits = 0; }
      Flags( const Flags& x ) { allBits = x.allBits; }

      bool operator ==( const Flags& x ) const { return allBits == x.allBits; }
   };

which of course requires changing all instances of "flags." to "flags.bits." in DynamicCropInterface.cpp.

Code: [Select]
void DynamicCropInterface::DynamicMouseEnter( View& v )
{
   if ( view == 0 || v != *view )
      return;

   // Force a dynamic cursor update upon subsequent mouse move event.
   flags = Flags();
}

By assigning a default Flags instance to flags (which actually clears all flags) we ensure that this code:

Code: [Select]
      Flags f = OperationInfo( p );
      if ( f != flags )
      {
         flags = f;
         UpdateDynamicCursor();
      }

will call UpdateDynamicCursor() if necessary to keep the cursor's shape coherent with its current position. Just a graphics workflow technique that I often use. As you say, this has no repercussion to communication with PI core.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
Re: PCL: how do I get DynamicMouseMove called?
« Reply #2 on: 2009 May 06 06:25:33 »
Thanks Juan. I copied the signature from the sample rather than the PCL docs. Will be more careful with that next time.
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
Re: PCL: how do I get DynamicMouseMove called?
« Reply #3 on: 2009 May 06 06:45:54 »
Thanks Juan. I copied the signature from the sample rather than the PCL docs. Will be more careful with that next time.

Sorry, that isn't true. I copied from my own code. It was late and the signatures looked the same. Had I copied from the sample it would have worked :)
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity