SOHANDLEBOXDRAGGER(3iv)

πŸ’– SoHandleBoxDragger(3IV) πŸ’–

okay bestie, gather round, because today we're talking about SoHandleBoxDragger(3IV) β€” yes the (3IV) is part of the name, it's giving library-section energy, we love that for her. This is the box you can scale, stretch and translate by dragging with the mouse. no cap. let's get into it πŸŽ€


🌈 NAME 🌈

SoHandleBoxDragger β€” a box you can scale, stretch and translate by dragging with the mouse. literally what it says on the tin, she's an icon, she's a legend, and she IS the moment πŸ’…


🧬 INHERITS FROM 🧬

ok so this is her whole family tree, from the great-great-grandparents down to her:

SoBase > SoFieldContainer > SoNode > SoBaseKit > SoInteractionKit >
SoDragger > SoHandleBoxDragger

she inherited everything and honestly? good for her πŸ‘‘


✨ SYNOPSIS ✨

first things first, you gotta include her header, or she simply will not appear:

#include <Inventor/draggers/SoHandleBoxDragger.h>

πŸ¦‹ Fields from class SoHandleBoxDragger

SoSFVec3f           scaleFactor
SoSFVec3f           translation

πŸ¦‹ Fields from class SoDragger

SoSFBool            isActive

πŸ¦‹ Fields from class SoInteractionKit

SoSFEnum            renderCaching
SoSFEnum            boundingBoxCaching
SoSFEnum            renderCulling
SoSFEnum            pickCulling

πŸ¦‹ Parts from class SoBaseKit

(SoNodeKitListPart)  callbackList

πŸ¦‹ Methods from class SoHandleBoxDragger

                     SoHandleBoxDragger()
static const SoNodekitCatalog *
                     getClassNodekitCatalog() const
static SoType       getClassTypeId()

πŸ¦‹ Methods from class SoDragger

void                addStartCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                removeStartCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                addMotionCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                removeMotionCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                addFinishCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                removeFinishCallback(SoDraggerCB *f, void *userData =
                         NULL)
void                addValueChangedCallback(SoDraggerCB *f, void *userData
                         = NULL)
void                removeValueChangedCallback(SoDraggerCB *f, void
                         *userData = NULL)
SbBool              enableValueChangedCallbacks()
void                setMinGesture(int pixels)
int                 getMinGesture() const
static void         setMinScale(float newMinScale)
static float        getMinScale()

πŸ¦‹ Methods from class SoInteractionKit

virtual SbBool      setPartAsPath(const SbName &partName, SoPath
                         *surrogatePath )

πŸ¦‹ Methods from class SoBaseKit

virtual const SoNodekitCatalog *
                         getNodekitCatalog() const
virtual SoNode *         getPart(const SbName &partName, SbBool
                              makeIfNeeded)
SbString                 getPartString(const SoBase *part)
virtual SoNodeKitPath *  createPathToPart(const SbName &partName, SbBool
                              makeIfNeeded, const SoPath *pathToExtend =
                              NULL)
virtual SbBool           setPart(const SbName &partName, SoNode *newPart)
SbBool                   set(char *partName, char *parameters)
SbBool                   set(char *nameValuePairs)
static SbBool            isSearchingChildren()
static void              setSearchingChildren(SbBool newVal)

πŸ¦‹ Methods from class SoNode

void                setOverride(SbBool state)
SbBool              isOverride() const
SoNode *            copy(SbBool copyConnections = FALSE) const
virtual SbBool      affectsState() const
static SoNode *     getByName(const SbName &name)
static int          getByName(const SbName &name, SoNodeList &list)

πŸ¦‹ Methods from class SoFieldContainer

void                setToDefaults()
SbBool              hasDefaultValues() const
SbBool              fieldsAreEqual(const SoFieldContainer *fc) const
void                copyFieldValues(const SoFieldContainer *fc, SbBool
                         copyConnections = FALSE)
void                get(SbString &fieldDataString)
virtual int         getFields(SoFieldList &resultList) const
virtual SoField *   getField(const SbName &fieldName) const
SbBool              getFieldName(const SoField *field, SbName &fieldName)
                         const
SbBool              isNotifyEnabled() const
SbBool              enableNotify(SbBool flag)

πŸ¦‹ Methods from class SoBase

void                ref()
void                unref() const
void                unrefNoDelete() const
void                touch()
virtual SoType      getTypeId() const
SbBool              isOfType(SoType type) const
virtual void        setName(const SbName &name)
virtual SbName      getName() const

πŸ¦‹ Macros from class SoBaseKit

SO_GET_PART(kit, partName, partClass)
SO_CHECK_PART(kit, partName, partClass)

🌸 DESCRIPTION 🌸

ok so picture this: SoHandleBoxDragger is a dragger shaped like a wireframe box, and it's got little corner cubes mounted on each corner. click and drag any of those cubes and the box scales uniformly. slay ✨

then there's six other center cubes β€” these ones are centered on the sides of the box β€” and white lines connect them to the center of the dragger. drag one of those center cubes along its line and you stretch the box in that direction. and if you drag a face of the box? that translates the dragger within that plane. three whole moods, one dragger πŸ’…

while you're dragging a face of the box, purple feedback arrows show up displaying the possible directions of motion. hit the <Shift> key and the motion gets constrained to one of the two major directions in the plane β€” and the constraint direction is chosen based on the next user gesture, so it's lowkey reading your mind. hit the <Control> key instead and the dragger translates perpendicular to that plane. the translation field gets modified as the face is dragged.

by default, dragging any of the small cubes scales about the center of the object. but press the <Control> key and everything changes, bestie: a corner cube will scale about its opposite corner, and a center cube will scale about the center of its opposite face. dragging one of the small cubes will usually change both the scaleFactor and translation fields β€” and there's a reason for that! it's because any scale about a point other than the origin has a translation element. math said periodt. πŸ“

as with all draggers, if you change the fields, the dragger will move to match the new settings. she's responsive like that.

🚨 REMEMBER: This is not an SoTransform! 🚨

if you wanna move other objects with this dragger, you've got two options, and you gotta pick one:

  • [a] Use an SoHandleBoxManip, which is subclassed from SoTransform. it creates one of these draggers and uses it as the interface to change its fields. (see the SoHandleBoxManip reference page).
  • [b] Use field-to-field connections to connect the fields of this dragger to those of any SoTransformation node.

you can change the parts in any instance of this dragger using setPart(). the default part geometries are defined as resources for this SoHandleBoxDragger class, and they're detailed in the Dragger Resources section of the online reference page for this class. wanna make your program use different default resources for the parts? easy:

  1. copy the file /usr/share/data/draggerDefaults/handleBoxDragger.iv into your own directory
  2. edit the file
  3. set the environment variable SO_DRAGGER_DIR to be a path to that directory

and boom, custom resources, you're basically a wizard now 🧚


πŸ’œ FIELDS πŸ’œ

  • SoSFVec3f scaleFactor β€” scale of the dragger.
  • SoSFVec3f translation β€” position of the dragger.

🫢 METHODS 🫢

  • SoHandleBoxDragger() β€” constructor. she's born ✨
  • static const SoNodekitCatalog * getClassNodekitCatalog() const β€” returns an SoNodekitCatalog for this class.
  • static SoType getClassTypeId() β€” returns the type identifier for this class.

and bestie, we're not done yet β€” there's more where this came from πŸ’–

✨ CATALOG PARTS ✨

okay bestie, this is the part where we meet the whole cast πŸ’– every single part in the catalog, what type it is, and whether it's NULL by default. Spoiler: literally all of them are "yes" on that last one, no cap. The default type column is just -- for everybody, so don't come for me about it 🫢

Here's the full roster, no skipping, every last one of them:

  • callbackList β€” Part Type: NodeKitListPart, Default Type: --, NULL by default: yes
  • surroundScale β€” Part Type: SurroundScale, Default Type: --, NULL by default: yes
  • translator1 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator1Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator2 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator2Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator3 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator3Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator4 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator4Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator5 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator5Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator6 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • translator6Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder1 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder1Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder2 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder2Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder3 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder3Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder4 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder4Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder5 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder5Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder6 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • extruder6Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform1 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform1Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform2 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform2Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform3 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform3Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform4 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform4Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform5 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform5Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform6 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform6Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform7 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform7Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform8 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • uniform8Active β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow1 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow2 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow3 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow4 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow5 β€” Part Type: Separator, Default Type: --, NULL by default: yes
  • arrow6 β€” Part Type: Separator, Default Type: --, NULL by default: yes

πŸŽ€ Extra info for the list parts from that table up there

so most of those parts are just plain Separator vibes, but a couple of them are list parts and they got ✨range✨ β€” here's the tea:

  • callbackList
    • Container Type: Separator
    • Permissible Types: Callback, EventCallback
that's literally it for the extras, bestie. one list part, two permissible types. she's small but she's mighty πŸ’…

🌈 DRAGGER RESOURCES 🌈

alright, now the main character section 😀 this is every resource you can poke at, what part it maps to, what it looks like, and what happens when you pick it. eyes on the prize, we're going through all of them.

πŸ’œ Translator handles

  • handleBoxTranslator1
    • Part: translator1
    • Appearance: White Line-Style Square
    • Description: Top face of handleBox. Picking this initiates scaling in x-z plane.
  • handleBoxTranslator2
    • Part: translator2
    • Appearance: White Line-Style Square
    • Description: Bottom face of handleBox. Picking this initiates scaling in x-z plane.
  • handleBoxTranslator3
    • Part: translator3
    • Appearance: White Line-Style Square
    • Description: Left face of handleBox. Picking this initiates scaling in y-z plane.
  • handleBoxTranslator4
    • Part: translator4
    • Appearance: White Line-Style Square
    • Description: Right face of handleBox. Picking this initiates scaling in y-z plane.
  • handleBoxTranslator5
    • Part: translator5
    • Appearance: White Line-Style Square
    • Description: Front face of handleBox. Picking this initiates scaling in x-y plane.
  • handleBoxTranslator6
    • Part: translator6
    • Appearance: White Line-Style Square
    • Description: Back face of handleBox. Picking this initiates scaling in x-y plane.

πŸ’› Translator handles but they're active (the glow-up versions)

  • handleBoxTranslator1Active
    • Part: translator1Active
    • Appearance: Yellow version of handleBoxTranslator1
    • Description: Replaces handleBoxTranslator1 during dragging.
  • handleBoxTranslator2Active
    • Part: translator2Active
    • Appearance: Yellow version of handleBoxTranslator2
    • Description: Replaces handleBoxTranslator2 during dragging.
  • handleBoxTranslator3Active
    • Part: translator3Active
    • Appearance: Yellow version of handleBoxTranslator3
    • Description: Replaces handleBoxTranslator3 during dragging.
  • handleBoxTranslator4Active
    • Part: translator4Active
    • Appearance: Yellow version of handleBoxTranslator4
    • Description: Replaces handleBoxTranslator4 during dragging.
  • handleBoxTranslator5Active
    • Part: translator5Active
    • Appearance: Yellow version of handleBoxTranslator5
    • Description: Replaces handleBoxTranslator5 during dragging.
  • handleBoxTranslator6Active
    • Part: translator6Active
    • Appearance: Yellow version of handleBoxTranslator6
    • Description: Replaces handleBoxTranslator6 during dragging.

πŸ¦‹ Extruder cubes (1-D scaling girlies)

  • handleBoxExtruder1
    • Part: extruder1
    • Appearance: Small white cube at (0,1.25,0) with line to origin
    • Description: Selecting this part initiates 1-D scaling along Y axis.
  • handleBoxExtruder2
    • Part: extruder2
    • Appearance: Small white cube at (0,-1.25,0) with line to origin
    • Description: Selecting this part initiates 1-D scaling along Y axis.
  • handleBoxExtruder3
    • Part: extruder3
    • Appearance: Small white cube at (-1.25,0,0) with line to origin
    • Description: Selecting this part initiates 1-D scaling along X axis.
  • handleBoxExtruder4
    • Part: extruder4
    • Appearance: Small white cube at (1.25,0,0) with line to origin
    • Description: Selecting this part initiates 1-D scaling along X axis.
  • handleBoxExtruder5
    • Part: extruder5
    • Appearance: Small white cube at (0,0,1.25) with line to origin
    • Description: Selecting this part initiates 1-D scaling along Z axis.
  • handleBoxExtruder6
    • Part: extruder6
    • Appearance: Small white cube at (0,0,-1.25) with line to origin
    • Description: Selecting this part initiates 1-D scaling along Z axis.

πŸ“ Extruder cubes but active (again, the yellow era)

  • handleBoxExtruder1Active
    • Part: extruder1Active
    • Appearance: Yellow version of handleBoxExtruder1
    • Description: Replaces handleBoxExtruder1 during dragging.
  • handleBoxExtruder2Active
    • Part: extruder2Active
    • Appearance: Yellow version of handleBoxExtruder1
    • Description: Replaces handleBoxExtruder1 during dragging.
  • handleBoxExtruder3Active
    • Part: extruder3Active
    • Appearance: Yellow version of handleBoxExtruder3
    • Description: Replaces handleBoxExtruder3 during dragging.
  • handleBoxExtruder4Active
    • Part: extruder4Active
    • Appearance: Yellow version of handleBoxExtruder4
    • Description: Replaces handleBoxExtruder4 during dragging.
πŸ‘€ yes bestie, handleBoxExtruder2Active really does say "Yellow version of handleBoxExtruder1" and "Replaces handleBoxExtruder1" β€” that's exactly what the page says, and I am not the one editing the source, iykyk. reporting it as-is, no cap.
  • handleBoxExtruder5Active β€” Part: extruder5Active ✨ Appearance: yellow version of handleBoxExtruder5 πŸ“ Description: replaces handleBoxExtruder5 during dragging.
  • handleBoxExtruder6Active β€” Part: extruder6Active ✨ Appearance: yellow version of handleBoxExtruder6 πŸ“ Description: replaces handleBoxExtruder6 during dragging.

okay now the uniform cubes, the little white corner gremlins that do the scaling πŸ’…

  • handleBoxUniform1 β€” Part: uniform1 ✨ Appearance: small white cube in the (+x+y+z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform2 β€” Part: uniform2 ✨ Appearance: small white cube in the (+x+y-z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform3 β€” Part: uniform3 ✨ Appearance: small white cube in the (+x-y+z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform4 β€” Part: uniform4 ✨ Appearance: small white cube in the (+x-y-z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform5 β€” Part: uniform5 ✨ Appearance: small white cube in the (-x+y+z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform6 β€” Part: uniform6 ✨ Appearance: small white cube in the (-x+y-z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform7 β€” Part: uniform7 ✨ Appearance: small white cube in the (-x-y+z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform8 β€” Part: uniform8 ✨ Appearance: small white cube in the (-x-y-z) corner of handleBox πŸŽ€ Description: picking this initiates uniform scaling.
  • handleBoxUniform1Active β€” Part: uniform1Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging. (yes bestie, that's exactly how the page says it β€” I'm reading it to you character for character πŸ’…)
  • handleBoxUniform2Active β€” Part: uniform2Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform3Active β€” Part: uniform3Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform4Active β€” Part: uniform4Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform5Active β€” Part: uniform5Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform6Active β€” Part: uniform6Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform7Active β€” Part: uniform7Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.
  • handleBoxUniform8Active β€” Part: uniform8Active ✨ Appearance: yellow version of handleBoxUniform1Active 🌼 Description: replaces handleBoxUniform1Active during dragging.

and the arrows, the purple directional besties 🏹

  • handleBoxArrow1 β€” Part: arrow1 πŸ’œ Appearance: purple arrow, pointing up ⬆️ Description: displayed when translating if Y direction is permitted.
  • handleBoxArrow2 β€” Part: arrow2 πŸ’œ Appearance: purple arrow, pointing down ⬇️ Description: displayed when translating if Y direction is permitted.
  • handleBoxArrow3 β€” Part: arrow3 πŸ’œ Appearance: purple arrow, pointing left ⬅️ Description: displayed when translating if X direction is permitted.
  • handleBoxArrow4 β€” Part: arrow4 πŸ’œ Appearance: purple arrow, pointing right ➑️ Description: displayed when translating if X direction is permitted.
  • handleBoxArrow5 β€” Part: arrow5 πŸ’œ Appearance: purple arrow, pointing forward πŸ”₯ Description: displayed when translating if Z direction is permitted.
  • handleBoxArrow6 β€” Part: arrow6 πŸ’œ Appearance: purple arrow, pointing backward πŸ”₯ Description: displayed when translating if Z direction is permitted.

πŸ“¦ FILE FORMAT/DEFAULTS πŸ“¦

here's the whole default vibe, verbatim, don't @ me:

HandleBoxDragger {
   renderCaching       AUTO
   boundingBoxCaching  AUTO
   renderCulling       AUTO
   pickCulling         AUTO
   isActive            FALSE
   translation         0 0 0
   scaleFactor         1 1 1
   callbackList        NULL
   surroundScale       NULL
   translator1         <handleBoxTranslator1 resource>
   translator1Active   <handleBoxTranslator1Active resource>
   translator2         <handleBoxTranslator2 resource>
   translator2Active   <handleBoxTranslator2Active resource>
   translator3         <handleBoxTranslator3 resource>
   translator3Active   <handleBoxTranslator3Active resource>
   translator4         <handleBoxTranslator4 resource>
   translator4Active   <handleBoxTranslator4Active resource>
   translator5         <handleBoxTranslator5 resource>
   translator5Active   <handleBoxTranslator5Active resource>
   translator6         <handleBoxTranslator6 resource>
   translator6Active   <handleBoxTranslator6Active resource>
   extruder1           <handleBoxExtruder1 resource>
   extruder1Active     <handleBoxExtruder1Active resource>
   extruder2           <handleBoxExtruder2 resource>
   extruder2Active     <handleBoxExtruder2Active resource>
   extruder3           <handleBoxExtruder3 resource>
   extruder3Active     <handleBoxExtruder3Active resource>
   extruder4           <handleBoxExtruder4 resource>
   extruder4Active     <handleBoxExtruder4Active resource>
   extruder5           <handleBoxExtruder5 resource>
   extruder5Active     <handleBoxExtruder5Active resource>
   extruder6           <handleBoxExtruder6 resource>
   extruder6Active     <handleBoxExtruder6Active resource>
   uniform1            <handleBoxUniform1 resource>
   uniform1Active      <handleBoxUniform1Active resource>
   uniform2            <handleBoxUniform2 resource>
   uniform2Active      <handleBoxUniform2Active resource>
   uniform3            <handleBoxUniform3 resource>
   uniform3Active      <handleBoxUniform3Active resource>
   uniform4            <handleBoxUniform4 resource>
   uniform4Active      <handleBoxUniform4Active resource>
   uniform5            <handleBoxUniform5 resource>
   uniform5Active      <handleBoxUniform5Active resource>
   uniform6            <handleBoxUniform6 resource>
   uniform6Active      <handleBoxUniform6Active resource>
   uniform7            <handleBoxUniform7 resource>
   uniform7Active      <handleBoxUniform7Active resource>
   uniform8            <handleBoxUniform8 resource>
   uniform8Active      <handleBoxUniform8Active resource>
   arrow1              <handleBoxArrow1 resource>
   arrow2              <handleBoxArrow2 resource>
   arrow3              <handleBoxArrow3 resource>
   arrow4              <handleBoxArrow4 resource>
   arrow5              <handleBoxArrow5 resource>
   arrow6              <handleBoxArrow6 resource>
}

⚠️ NOTE ⚠️

okay so this is the tea and it's kind of iconic actually:

Unlike most multi-function draggers, SoHandleBoxDragger is not a compound dragger made up of other draggers that perform its smaller tasks. This is not because it was inappropriate, but because was written before implementation of the methods that synchronize multiple child draggers. The younger SoTransformBoxDragger has similarities to the handle box dragger, but the transform box dragger is a compound dragger.

so basically: it's a lone wolf 🐺, not a friend group. not because the friend group was a bad idea β€” it just got written before the friend-group-syncing code existed. the newer SoTransformBoxDragger is similar but does do the compound thing. growth πŸ’…


πŸ‘€ SEE ALSO πŸ‘€

go read these next, bestie, they're all part of the same family 🫢

  • SoInteractionKit
  • SoDragger
  • SoCenterballDragger
  • SoDirectionalLightDragger
  • SoDragPointDragger
  • SoJackDragger
  • SoPointLightDragger
  • SoRotateCylindricalDragger
  • SoRotateDiscDragger
  • SoRotateSphericalDragger
  • SoScale1Dragger
  • SoScale2Dragger
  • SoScale2UniformDragger
  • SoScaleUniformDragger
  • SoSpotLightDragger
  • SoTabBoxDragger
  • SoTabPlaneDragger
  • SoTrackballDragger
  • SoTransformBoxDragger
  • SoTransformerDragger
  • SoTranslate1Dragger
  • SoTranslate2Dragger

and that's the whole page, no cap πŸŽ€ footer says SoHandleBoxDragger(3IV)() β€” so it's the 3IV version, and the date slot is just... vibes and empty parens πŸ™ˆ which honestly is its own kind of iconic. go forth and drag, you gorgeous genius βœ¨πŸ¦‹πŸ’–