SDK:Tool with Default Behavior

From Vectorworks Developer
Jump to navigation Jump to search

.SDK|SDK ..SDK:Types|SDK Types ..SDK:Using the SDK|Using the SDK ..VCOM:VCOM (Vectorworks Component Object Model)|VCOM Basics ..VCOM:Class Reference|VCOM Class Reference

Default Tool

A default tool (see SDK:Parametric Object Default Tool) may be created for parametric plug-ins which will handle creation of the parametric.

The default tool puts standard symbol insert like mode bar:

  • Mode Group -- determines the object insertion mode;
    • Normal Insertion Mode -- The user creates an object and specifies rotation;
    • Offset Insertion Mode -- Works only for wall insertion. The user specifies control point by single click, is allowed to hover over a wall so the object will be inserted in the wall. Then the user is allowed to specify the offset distance from the control point;
  • Insert in Wall Group -- determines if the tool should insert the object into a wall if the user places the object over a wall. This is always on for "Offset Insertion Mode";
  • Alignment Group -- Which part of the object is placed on the user click point;
    • Left -- the left part is aligned to the user click point;
    • Center -- the center part is aligned to the user click point;
    • Right -- the right part is aligned to the user click point;
    • Symbol Insertion Point -- the symbol insertion point is aligned to the user click point;
  • Properties -- invokes properties dialog for the parametric;

Tool with Default Behavior

Any tool can act as default tool by calling VCOM:VectorWorks:ISDK::CallDefaultTool.

Here is example of custom tool that implemented default behavior for hard-coded (by string name) object.

On kToolInitGlobals event the tool specifies the object name that is to be created by the default tool. After that all the tool should do is call VCOM:VectorWorks:ISDK::CallDefaultTool passing on all tool events.

// ----------------------------------------------------------------------------------------------------
long ToolMain(long action, long message1, long message2, long& userData)
{
  GSExternalSetup(gCBP);

  long returnVal = 0L;

  switch (action) {
    case kToolInitGlobals : {
      InternalName	objName;
      TXString("TestObjectName").CopyInto( objName );

      gSDK->CallDefaultTool( kToolInitGlobals, (long) & objName, 0, userData );
      break;
    }

    case kToolDisposeGlobals : {
      gSDK->CallDefaultTool( kToolDisposeGlobals, 0, 0, userData );
      break;
    }

    default:
      returnVal = gSDK->CallDefaultTool( action, message1, message2, userData );
      break;
  }

  GSExternalSetdown (0L);

  return returnVal;
}

Overriding the Mode Bar

The custom tool may modify the mode bar but still retain the default tool behavior.

Note Is should call VCOM:VectorWorks:ISDK::CallDefaultTool for all events in order to get the default tool behavior.

To customize the mode bar the tool must get the kToolDoSetup and kToolDoModeEvent events.

The tool uses the structure SDefaultToolSettings (see below) to describe the mode bar button IDs for the default toll behavior to work. This should be done on kToolDoSetup and kToolDoModeEvent events.

struct SDefaultToolSettings
{
  short fModeGroup;		// radio group
  short fAllowInsertGroup;	// button group
  short fAlignmentGroup;	// radio group

  // insertModeGroup choice indices
  short fRegularInsChoiceIndex;
  short fOffsetInsChoiceIndex;
  short fPickUpChoiceIndex;

  // alignmentGroup choice indices
  short fLeftChoiceIndex;
  short fCenterChoiceIndex;
  short fRightChoiceIndex;
  short fNaturalChoiceIndex;
};

The tool is responsible for storing the mode bar buttons state in between tool calls. See user data in the example below.

The tool may not implement all default tool buttons. Then it should initialize with -1 value the fields of the structure. Here are the rules:

  • fModeGroup SHOULD NEVER BE -1 -- there should always be mode group
fRegularInsChoiceIndex -- should always contain index to the regular choice button ID;
fOffsetInsChoiceIndex -- should always contain index to the offset choice button ID;
fPickUpChoiceIndex = -1 This is reserved and always should be -1.
  • fAllowInsertGroup = -1 -- no allow insert into wall check button;
  • fAlignmentGroup = -1 -- no alignment group buttons. The default tool always works in 'Symbol Insertion Point' mode;
Then fLeftChoiceIndex = -1, fCenterChoiceIndex = -1, fRightChoiceIndex = -1 and fNaturalChoiceIndex = -1

As you can see the mode buttons should always be inside single radio group. And all alignment buttons should all be inside single radio group.

Example

The example uses build-in icons:

  • 2489 -
  • 2490 -
  • 2500 -
  • 2501 -
  • 2502 -
  • 2503 -

However it is recommended that you specify your own images because VectorWorks does not guarantee those constants to be those images.

WallInsertTool.h

#pragma once

//----------------------------------------------------------------------------
// Default tool settings
// Allow us to use the default insertion tool as base for all tools
struct SDefaultToolSettings
{
  short fModeGroup;		// radio group
  short fAllowInsertGroup;	// button group
  short fAlignmentGroup;	// radio group

  // insertModeGroup choice indices
  short fRegularInsChoiceIndex;
  short fOffsetInsChoiceIndex;
  short fPickUpChoiceIndex;

  // alignmentGroup choice indices
  short fLeftChoiceIndex;
  short fCenterChoiceIndex;
  short fRightChoiceIndex;
  short fNaturalChoiceIndex;

  SDefaultToolSettings() {
    fModeGroup = fAllowInsertGroup = fAlignmentGroup = -1;
    fRegularInsChoiceIndex = fOffsetInsChoiceIndex = fPickUpChoiceIndex = -1;
    fLeftChoiceIndex = fCenterChoiceIndex = fRightChoiceIndex = fNaturalChoiceIndex = -1;
  }
};

//----------------------------------------------------------------------------
class CPersistentData
{
public:
          CPersistentData();
          ~CPersistentData();

public:
  SDefaultToolSettings  SetupBar(bool bInitOnly);
  void                  OnBarEvent(short groupID, short buttonID, short oldButtonID);


  long&          GetToolData();
  short          GetBarState(size_t groupID) const;
  void           SetBarState(size_t groupID, short state);

private:
  long       fToolData;
  short      fBarState[10];
};

WallInsertTool.cpp

#include "StdAfx.h"

#include "WallInsertTool.h"

// ----------------------------------------------------------------------------------------------------
CPersistentData::CPersistentData()
{
  fToolData    = 0;
  for(size_t i=0; i<10; i++) {
    fBarState[i]  = 0;
  }
}

CPersistentData::~CPersistentData()
{
}

long& CPersistentData::GetToolData()
{
  return fToolData;
}

short CPersistentData::GetBarState(size_t groupID) const
{
  return fBarState[ groupID ];
}

void CPersistentData::SetBarState(size_t groupID, short state)
{
  fBarState[ groupID ]  = state;
}

SDefaultToolSettings CPersistentData::SetupBar(bool bInitOnly)
{
  SDefaultToolSettings  defToolSettings;

  if ( this->GetBarState( 1 ) == 0 )  this->SetBarState( 1, 1 );
  if ( this->GetBarState( 2 ) == 0 )  this->SetBarState( 2, 1 );
  if ( this->GetBarState( 3 ) == 0 )  this->SetBarState( 3, 4 );

  if ( ! bInitOnly ) {
    // if not initializing then build the mode bar
    gSDK->AddRadioMode( this->GetBarState( 1 ), 2, 11001, 11002 );
    gSDK->AddRadioMode( this->GetBarState( 2 ), 5, 2489, 2490, 11003, 11004, 11005, 0 );
    gSDK->AddRadioMode( this->GetBarState( 3 ), 4, 2500, 2501, 2502, 2503, 0, 0 );
    gSDK->AddButtonMode( 11006 );
    gSDK->AddButtonMode( 11007 );
  }

  defToolSettings.fModeGroup              = 2;  // mode change group ID
  defToolSettings.fAlignmentGroup         = 3;  // alignment change group ID
  defToolSettings.fRegularInsChoiceIndex  = 1;  // fModeGroup indices
  defToolSettings.fOffsetInsChoiceIndex   = 2;    //
  defToolSettings.fLeftChoiceIndex        = 1;  // fAlignmentGroup indices
  defToolSettings.fCenterChoiceIndex      = 2;    //
  defToolSettings.fRightChoiceIndex       = 3;    //
  defToolSettings.fNaturalChoiceIndex     = 4;    //

  return defToolSettings;
}

void CPersistentData::OnBarEvent(short groupID, short buttonID, short oldButtonID)
{
}

// ----------------------------------------------------------------------------------------------------
long ToolMain(long action, long message1, long message2, long &userData)
{
  GSExternalSetup(gCBP);

  long returnVal = 0L;


  CPersistentData*  pInfo  = (CPersistentData*) userData;

  switch (action) {

    case kToolInitGlobals : {
      void* pRawMem  = gSDK->GSNewPtr( sizeof(CPersistentData) );
      pInfo      = new ( pRawMem ) CPersistentData();
      if ( pInfo ) {
        InternalName  objName;
        TXString("#VSObjectWithWidgets").CopyInto( objName );

        SDefaultToolSettings settings  = pInfo->SetupBar( true );

        gSDK->CallDefaultTool( kToolInitGlobals, (long) & objName, (long) & settings, pInfo->GetToolData() );
      }

      break;
    }
    case kToolDisposeGlobals : {
      if ( pInfo ) {
        gSDK->CallDefaultTool( kToolDisposeGlobals, 0, 0, pInfo->GetToolData() );

        pInfo->~CPersistentData();
        gSDK->GSDisposePtr( pInfo );
      }

      break;
    }
    case kToolDoSetup : {
      SDefaultToolSettings settings  = pInfo->SetupBar( false );

      gSDK->CallDefaultTool( kToolDoSetup, message1, (long) & settings, pInfo->GetToolData() );
      break;
    }
    case kToolDoSetDown : {
      gSDK->CallDefaultTool( kToolDoSetDown, message1, message2, pInfo->GetToolData() );
      break;
    }
    case kToolDoModeEvent : {
      short    groupID     = DemoteTo<short>( kVStanev, (message1 > 0 ? message1 : 0) );
      short    buttonID    = DemoteTo<short>( kVStanev, ((message2 > 0 ? message2 : 0) & 0x0000FFFF) );
      short    oldButtonID = DemoteTo<short>( kVStanev, (((message2 > 0 ? (size_t)(message2) : 0) & 0xFFFF0000) >> 24) );

      pInfo->SetBarState( groupID, buttonID );


      returnVal  = gSDK->CallDefaultTool( kToolDoModeEvent, message1, message2, pInfo->GetToolData() );
      break;
    }
    default:
      returnVal  = gSDK->CallDefaultTool( action, message1, message2, pInfo->GetToolData() );
      break;
  }

  userData  = (long) pInfo;

  GSExternalSetdown (0L);

  return returnVal;
}

See Also

SDK:Parametric Object Default Tool