In order to convert the legacy viewports to XClip view clips, four new methods has been added to the Viewport2D
class:
public XClipWormholeSnapper2D createXClipFromViewport() { ... } public XClipWormholeSnapper2D createXClipFromWormholeCollapsed(Space space = null) { ... } public void copyConfiguration(XClipWormholeSnapper2D wh) { ... } public void createCompanionsFromViewport(XClipWormholeSnapper2D wh, XClipWormholeCompanionSnapper[] companions) { ... }
The first two methods generates a XClipWormholeSnapper2D
object from the current ViewportSnapper2D
instance and can be overridden in case your extended Viewport2D
requires some intricate conversion logic.
If your viewport has some additional configuration, this can be converted by simply overriding the copyConfiguration()
method, which is called in both viewport conversion methods. Let's look at the base method:
/** * Copy configuration. */ extend public void copyConfiguration(XClipWormholeSnapper wh) { if (!wh.settings) return; if (blackAndWhite) wh."whBlackWhite" = true; if (ViewMode vm = getRegisteredViewMode(this.?viewModeKey.str)) { wh.setViewMode(vm); } else { wh.setViewMode(ViewMode("cm.core.visibility","newViewModeName", viewModeLayers)); } if (ViewContentFilter filter = viewContentFilter) { wh.setViewContentFilter(copyContentFilter(filter)); } }
The ViewportSnapper2D
class has a member called blackAndWhite
, indicating whether the viewport should be without colors. This corresponds to the whBlackAndWhite
property of the XClip view clip. The conversion transfers this configuration option to the new view clip in line 3.
In some cases, some of your extended viewport functionality can be abstracted into a companion. If this is the case, the method createCompanionsFromViewport()
can be extended to automatically create and attach companions to the new XClip view clip based on the current ViewportSnapper2D
. Let's look at the implementation of the base method:
/** * Create companions from the give viewport. * XClipWormholeSnapper wh currently unused, still kept since subclass might need it. * XClipWormholeCompanionSnapper[] companions is the list which should be populated with new companions by this method. */ extend public void createCompanionsFromViewport(XClipWormholeSnapper wh, XClipWormholeCompanionSnapper[] companions) { if (!frameType.none) { XClipWormholeFrameCompanionSnapper frame(); frame."frameType" = frameType; frame."lStyle" = usedLineStyle; frame."lineWidth" = lineWidth; frame."lineColor" = lineColor; companions << frame; } if (showScale) { XClipWormholeScaleCompanionSnapper scale(); scale."frame" = !frameType.none; companions << scale; } }
The ViewportSnapper2D
object uses the frametype
member to indicate its frame. In XClip view clips, however, the frame functionality exists in a companion object which is attached to the viewport. So, in the conversion, if the ViewportSnapper2D
instance has a frame, an XClipWormholeFrameCompanion
instance is created, the frame type is set, and the companion gets appended to the companions
list. That list will later be used to attach all companions to the new XClip view clip. The creation of the frame companion is implemented on lines 7-15.
The XClip view clip supports showing contents from other spaces then the main 2D space. If multiple spaces exists in the drawing (e.g. alternatives, elevation views, etc.), the user will see a dropdown option for selecting other spaces than the main 2D space when inserting a new view clip. In order to add your own custom spaces to the list of available spaces you need to add an XClipWarpSpaceDomainEnv
for your type of space.
The code below illustrates how the XClipWarpSpaceDomainEnv
looks for elevation spaces.
public class ElevWarpSpaceDomainEnv extends XClipWarpSpaceDomainEnv { public constructor() { spaceClass = ElevSpace; } /** * Return the name of the space. * if the return string is null the space will not be added. */ public Str spaceName(Space space) { if (space as ElevSpace) { if (space.arrow) { return space.arrow.label(); } } return null; } }
Once your XClipWarpSpaceDomain
subclass has been implemented, it has to be registered in the xclip system. This is done using the global method xclipAddWarpSpaceDomain(XClipWarpSpaceDomain env)
.
xclipAddWarpSpaceDomain(ElevWarpSpaceDomainEnv());
Your specific space might also want a specific XClipSpaceManager
that has some special logic for handling XClip-related events in your space. Refer to XClipSpaceManager
and ElevXClipSpaceManager
for further details on the class implementation. Once your space manager is implemented, connect it to your space by overriding the initXClips()
method in your space.
public class ElevSpace extends Space { ... /** * init Elevation xclip space manager. */ public void initXClips() { if (!xclips) xclips = ElevXClipSpaceManager(this); } ... }
There are currently 2 types of Companions for XClip view clips:
1.Graph additions - Changes the graphic of the view clip snapper, but does not alter the content (e.g. add a frame around the view clip, draw out the used scale of the view clip, etc.).
The Companion connects to the XClip Wormhole using normal connectors. They connect at (0, 0, 0) and shares rotation. This means the XClip Wormhole and the Companions connected have the same local coordinate systems (I.e. 5mm x-axis into the XClip Wormhole is 5mm x-axis into the Companion.
All Companions must inherit from XClipWormholeCompanionSnapper
and the class must be registered using the registerXClipWormholeCompanionClass()
function. When registered the Companion will show up in the same box in the Paperspace Toolbox under the XClipWormhole icon.
To create a Graphical Companion implement as a normal GraphSnapper usingG2() = true
subclassing the base class directly XClipWormholeCompanionSnapper
.
To create an Editor Companion inherit from the XClipWormholeEditor2DCompanionSnapper
class and override the createEditor()
method.
Standard CET Wormhole Companions:
XClipWormholeScaleCompanionSnapper
- Shows the scale of the XClip Wormhole.XClipWormholeFrameCompanionSnapper
- Creates a border around the clipped area in the XClip Wormhole.XClipColumnBalloonCompanion
- Shows and dimensions Column balloons outside edge of XClip Wormhole.XClipWormholeTagCompanionSnapper
- Colors content of XClip Wormhole with tagged Part Tags from chosen Part Tag Category.Starting from version 11.0, it is possible to give graphs a black fill color when using the BlackAndWhite companion. To do this, add a property called blackAndWhiteAllowFill
to your snapper and set it to true. This will fill all graphs in that snapper where the line color is the same as the fill color.
Column balloons are reference balloons for Columns in the drawing. They can be named and are interfacing with the XClip Column Balloon Companion.
If your Extension has Column Balloons it is strongly recommended to subclass the CET standard Column Balloon for future compatibility.
If you have auto papers that previously generated viewports, these will now be automatically converted to view clips. All configuration and functionality of the AbsAPViewport2D
will be transferred to the view clip through a companion called AbsXClipApWormholeSettingsCompanionSnapper
. However, since the conversion is performed by the makePapers()
method, you need to manually add the code line below in your subclass if this method has been overridden. The code below shows how and where the conversion is made in the BasicAPPaperMaker
class.
/** * Create paper(s) from the env. */ public PaperSpace[] makePapers(AbsAPGroupEnv env) { StreamPaper stream(templateUrl); PaperSpace newSpace = stream.load(env.world); if (!newSpace) return null; if (paperGroup) newSpace.group = paperGroup; for (z in newSpace.snappers) { if (developMode) { // Not needed in release. // FIXME: Will be unneeded when StreamPaper is fixed. z.initEntityId(newSpace); } if (z as ImageSnapper) { str fileName = z.originalFilename; Url imUrl; for (im in filesIn(templateUrl, fileName # ".*")) { imUrl = im; break; } z.file = imUrl; z.createGImage(); } z.propDefs; if (PropDef def = z.propDef(cAbsAPPushEnvProp)) { def.put(z, this, env); z.invalidate(dirty2D.rebuild); } if (z as AbsAPViewport2D) z.replaceWithXClip(); // <================ This line converts the viewport } return [newSpace]; }
If you want to create a button for inserting a view clip that automatically modifies the view clip in some fashion (e.g. attaching companions, changing some configuration etc.) you can use the method xclipWormholeSnapperLimb()
. This method has one parameter called configureCallback
which will be invoked once the view clip has been created, providing a straight-forward method of editing your newly created view clip. For instance, the function createCustomXClipLimb
below creates a button which starts the animation for inserting a view clip and automatically attaches an AbsXClipAPWormholeSettingsCompanionSnapper
to each.
use cm.core.xclip; package const symbol pkgXClip = #"cm.core.xclip"; /** * Configure the wormhole however you like */ package void configureWormhole(XClipWormholeSnapper wh) { AbsXClipAPWormholeSettingsCompanionSnapper c(); c.z2m = apViewportZoomMode.group; wh.connectCompanion(c); } /** * Create our own button which lets us configure the wormhole snapper using the method above. */ package ComponentLimb createCustomXClipLimb(LibraryLimb parent, symbol pkg, str key, UIHint hint=null) { return xclipWormholeSnapperLimb(parent, pkg, key, hint, function configureWormhole); }