A warning has been added when passing a str->Object with the same name as the props argument name. This to make the developer aware that this will NOT pass your value as argument. Keyword and value will be added to props.
public class MyClass { public constructor() { } extend public void put(str key, props: args) { pln(#args); } } { str->Object args = {str->Object: "a"->1}; MyClass myclass(); myclass.put("key", args=args);// props argument value has the same name as the props argument name } args={"args"->{"a"->1}}
Two new constructors have been added to the AbsItemTagInfo
class.
str articleCode
parameter has been addedstr articleCode
field on constructionNew: public constructor(str text, str k, AbsDwgLayerInfo info, str articleCode, double textHeight=4inch) {} New: public constructor(str text, str k, AbsDwgLayerInfo info, str textType, str articleCode) {}
The following resizing interfaces have been replaced:
Old: public DibImage dsDibResize3(DibImage im, sizeI newSize, str filter=null) : deprecated { New: public void dibResize(DibImage im, sizeI newSize, str filter=null) {
The basePrice
method was refactored to remove the final
and inline
modifiers and is now declared as an extend public
method.
Old:
final
→ could not be overridden by subclasses.inline
→ compiler inlined the method for performance optimization.New:
extend public
→ method can now be extended/overridden.inline
removed → no longer enforced as an inline method.styleProduct
price if present.The DsPart
class constructors have been expanded and split to support the new part pricing system (introduced in 16.5).
New constructors now accept basePrice
and optionPriceSum
separately.
Old constructors that use list price remain available but are marked for future deprecation.
constructor(Snapper, DsPData, double listPrice, …)
constructor(Snapper, DsPData, str articleCode, str description, double listPrice, …)
constructor(Snapper, DsPData, double basePrice, Double optionPriceSum, …)
constructor(Snapper, DsPData, str articleCode, str description, double basePrice, Double optionPriceSum, …)
cm.core.part.Part
compile-time section for more migration tipsThe following functions were introduced or modified to support the transition to the new part pricing system.
Find more documentation on the new pricing system in the compile-time section for cm.core.part.Part
.
Added: public Double generateOptionPriceSum() {} Removed: public double basePrice() {} Removed: public void performPriceConversions(ProjectInformation projectInfo) {}
Old:
New:
pData.optionPriceSum(specOptions, this)
generateOptionPriceSum()
in your extended Part class.invalidateOptionPriceSum()
) when option state changes to trigger regeneration.The basePrice
method was expanded to support the new pricing framework by adding parameters and delegating to the superclass when new pricing is enabled.
Old: public double basePrice() {} New: public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
Old:
public double basePrice()
PartSpecial
(replace or append)_data.basePrice
New:
public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
useNewPricing
is enabled → delegates directly to super()_data.basePrice
with PartSpecial
adjustments)ProdPart
).As of 16.5, a new interface for lead time has been added to core Part
and overridden in DsPart
. It's value is displayed in the new LeadTimeColumn
implemented in cm/core/init/leadTimeColumn.cm
.
In cm/abstract/dataSymbol/parts.cm /** * Get lead time string. * Ex. 20 days, 3 weeks, etc. */ public str leadTime() { DsProductType product = pData.product(); if (!product) return super(); int days; for (ref in product.leadTimeProgramRefs()) { DsLeadTimeProgramType ltp = pData.leadTimeProgram(ref); if (!ltp) continue; days = max(days, ltp.days); } return days > 0 ? spnn(days, ' ', days == 1 ? $day : $days) : ""; }
The abstract ProdPart
interface for generateOptAdjustmentSifRows
has been changed to accept PartOptionItem
s instead of SpecOption
s.
As a result, the empty override of this function in DsPart
has been removed entirely.
Old: public void generateOptAdjustmentSifRows(SpecOption opt, str[] lines) {}
The abstract ProdPart
interface for optSpecialKey
has been changed to accept PartOptionItem
s instead of SpecOption
s.
Old: public str optSpecialKey(SpecOption opt) {} New: public str optSpecialKey(PartOptionItem opt) {}
When collecting PartInfoTree
s on DsPart
s, the specOptions
sequence is no longer filtered by DsSpecOption
s. All options
within the specOptions
sequence will have a tree constructed.
public PartInfoTree[] infoTrees() { PartInfoTree[] items(); PartInfoTree[] parents(); Old: for (DsSpecOption tp in specOptions, index=i) { New: for (tp in specOptions, index=i) { ... } return items; }
With the addition of the new part attribute description/notes system, DsPart
s now
need to be differentiable/split by their attribute values.
The following change has been made in flattenableKey
to account for this:
public str flattenableKey() { StrBuf buf(uniqueKey()); ... New: buf << annotationFlattenableKey(); return buf.retireToS(); }
The basePrice
method was expanded to support the new pricing framework by adding parameters and delegating to the superclass when new pricing is enabled.
Old: public double basePrice() {} New: public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true) {}
Old:
public double basePrice()
item.price()
PartSpecial
(replace or append)New:
public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
useNewPricing
is enabled → delegates directly to super()item.price()
with PartSpecial
adjustments)The following functions were added to support base price for DsFreeformItem
s.
Added: extend public str currentCurrencyKey(str key) {} Added: extend public double basePrice() {} Added: extend public double basePrice=(double value) {}
The handling of currency-based pricing was refactored to make currentCurrencyKey
more flexible.
Old:
currentCurrencyKey()
directly constructed a key using cDsFPriceKey
and the current currency symbolNew:
currentCurrencyKey()
now delegates to a new overload:
currentCurrencyKey(str key)
→ builds a unique freeform key from the given key and currency symbol.Explicit support for base price has been added to DsFreeformItem
.
Old:
New:
basePrice
field accessors:
basePrice()
→ retrieves the base price using cDsFBasePriceKey
basePrice=(double value)
→ sets the base price.We have removed the field info
field from CatalogTocLimbBuilder. You can get relevant information from code
and versionCode
fields.
Old: private DsSqlImportActiveCatsInfo info : public readable; New: private str code : public readable; New: private str versionCode : public readable;
The following methods with bool retDibImage=true
have been removed. DibImage are now used by default for performance reasons.
Old: extend public Image getThumbImage(Url url, sizeI size=sizeI(), DsCommunicationCB callback=null, int priority=2, bool retDibImage=false) { New: extend public Image getThumbImage(Url url, sizeI size=sizeI(), DsCommunicationCB callback=null, int priority=2) { Old: extend public Image getThumbImage(DsiPData data, sizeI size=sizeI(), DsCommunicationCB callback=null, bool useCache=false, int priority=2, bool retDibImage=false) { New: extend public Image getThumbImage(DsiPData data, sizeI size=sizeI(), DsCommunicationCB callback=null, bool useCache=false, int priority=2) {
We have improved handling of DibImage by the system. It can now draw DibImage that have transparency. This means we no longer need convert a DibImage into a MemoryImage and cache it. The following interfaces have been removed:
Removed: public MemoryImage dsThumbnailMemImageCache(DibImage dib) { Removed: public void startDsMemImageCacheIdle() { Removed: public int dsMemoryImageCount() {
Old: extend public View currentView() { New: public WindowView currentView() {
The visibility of many interfaces across the whole abstract have been changed from public to package or private, as they were not intended to be used elsewhere. If you require any of the changed interfaces, consider making a local copy of it or contact developer support.
The following function has been removed from K2ApplianceLibrary:
Removed: public void addSchemeLimb(LibraryLimb parent)
The following function has been removed from K2SinkLibrary:
Removed: public void addSchemeLimb(LibraryLimb parent)
Global dimension functions removed:
Removed: public double getCabinetWidth(XpShape shape) Removed: public double getCabinetDepth(XpShape shape) Removed: public double getMeasureWidth(XpShape shape) Removed: public double getMeasureDepth(XpShape shape) Removed: public double getMeasureHeight(XpShape shape)
Use these methods instead:
public double nominalHeight() public double nominalWidth() public double nominalHeight()
The WgApplianceEnvSnapperDibButton
class has been removed as LazySnapper3DMemoryButton has been updated to use DibImage.
Old: public class WgApplianceEnvSnapperDibButton extends SnapperImageButton { New: public class WgApplianceEnvSnapperButton extends LazySnapper3DMemoryButton {
When adding a measure to the group, the snapper which the measure belongs to needs to be passed along with it.
Old: final public void add(KitchenAutoMeasure measure) { New: final public void add(Snapper snapper, KitchenAutoMeasure measure) {
createAutoMeasures
now returns which snapper
that are mapped to which AutoMeasure
s.
Old: public KitchenAutoMeasure{} createAutoMeasures(Snapper{} snappers) { New: public Snapper->KitchenAutoMeasure{} createAutoMeasures(Snapper{} snappers) {
accept
now requires the AutoMeasure
which belongs to the snapper.
Old: final public bool accept(Snapper z) { New: final public bool accept(Snapper z, KitchenAutoMeasure measure) {
autoMeasureToGroups
now requires the AutoMeasure
s to be mapped from their Snapper
.
Old: public KitchenAutoMeasureGroup[] autoMeasuresToGroups(KitchenAutoMeasure{} measures, symbol category=null) { New: public KitchenAutoMeasureGroup[] autoMeasuresToGroups(Snapper->KitchenAutoMeasure{} measures, symbol category=null) {
The global public function updateAutoMeasures
now have closeElevationDialog=false
as a default argument.
Old: public void updateAutoMeasures(Space space) { New: public void updateAutoMeasures(Space space, bool closeElevationDialog=false)
The following function has been removed from DesignDialog:
Removed: public void parentClientBoundChanged()
The pricing override in COMPart shifted from a custom list price implementation to a standardized basePrice override.
Old: public double customListPrice(bool includeChildren=false, str currency=null, Space space=null) {} New: public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true) {}
Old:
New:
COMPart
with the new part pricing API (basePrice + optionPriceSum).In class MhEngineEntryBase
, removed argument MhEngine engine
from method parent
as it is no longer required (explained below).
public class MhEngineEntryBase { Old: extend public MhEngineEntry parent(MhEngine engine) { return null; } New: extend public MhEngineEntry parent() { return null; } }
Moved a field MhEngineEntry parent
from child class MhEngineConstructionEntry
up to the parent class MhEngineSnapperEntry
.
public class MhEngineSnapperEntry extends MhEngineBoxEntry { New: public MhEngineEntry parent : copy=reference; } public class MhEngineConstructionEntry extends MhEngineSnapperEntry { Removed: public MhEngineEntry parent : copy=reference; }
With this, MhEngineSnapperEntry
now has a direct reference to its parent entry. The parent()
method (previously parent(MhEngine engine)
) no longer needs to refer to its snapper's parent.
public class MhEngineSnapperEntry extends MhEngineBoxEntry { Old: /** * Parent. */ public MhEngineEntry parent(MhEngine engine) { ?MhSnapper parent = z.parent; return engine.?entry(parent); } New: /** * Parent. */ public MhEngineEntry parent() { return parent; } }
For your info, there is now a proper interface to change the parent of an engine entry.
public class MhEngineEntryBase { New: extend public void changeParent(MhEngine engine, MhEngineEntry newParent) { }
In class MhEngineBoxEntry
renamed methods box unmodifedBound()
to box unmodifiedBound()
and Transform unmodifedTransform()
to Transform unmodifiedTransform()
.
public class MhEngineBoxEntry extends MhEngineCollisionEntry { Old: extend public box unmodifedBound() { New: extend public box unmodifiedBound() { Old: extend public Transform unmodifedTransform() { New: extend public Transform unmodifiedTransform() { }
The public function box unmodifedBoundIncludingChildren(MhEngineBoxEntry entry, MhEngine engine)
has been renamed to box unmodifiedBoundIncludingChildren(MhEngineBoxEntry entry, MhEngine engine)
.
Old: public box unmodifedBoundIncludingChildren(MhEngineBoxEntry entry, MhEngine engine) { New: public box unmodifiedBoundIncludingChildren(MhEngineBoxEntry entry, MhEngine engine) {
The method box unmodifedLocalBoundIncludingChildren(MhEngineEntry entry, Transform t, MhEngine engine)
has been renamed to box unmodifiedLocalBoundIncludingChildren(MhEngineEntry entry, Transform t, MhEngine engine)
.
public class MhAlignLoadsToAisleFunction extends MhSystemEngineFunction { Old: extend public box unmodifedLocalBoundIncludingChildren(MhEngineEntry entry, Transform t, MhEngine engine) { New: extend public box unmodifiedLocalBoundIncludingChildren(MhEngineEntry entry, Transform t, MhEngine engine) { }
Added new argument runMultiChildrenLink
to this engine function. The purpose of this argument is to link nested bays/frames together (bays within bay, frames within frame). See "Multi-bay and multi-frame support" in New Features for more info.
public class MhMasterLinkFinalizeFunction extends MhSystemEngineFunction { /** * Run multi children link. */ public Bool runMultiChildrenLink;
Added new argument flattenedFill
to this engine function. The purpose of this argument is for racking systems with multi-bay/multi-frame structure (see "Multi-bay and multi-frame support" in New Features for more info). Set this argument to true
if you want to fill empty bay space depth-wise when you have a multi-bay. Control this argument with MhBayRowEngineBehavior.shouldFlattenRowForFill(symbol event="", Object env=null)
.
public class MhBayRowEngineBehavior extends MhEngineBehavior { /** * Should flatten row for fill voids? */ extend public bool shouldFlattenRowForFill(symbol event="", Object env=null) { return true; } }
We've also broken up the existing logic in fillVoidEntries(MhEngineEntryBlock block)
into several new methods for easier override.
public class MhRowFillVoidEntriesFunction extends MhSystemEngineFunction { /** * Fill removed snappers void entries. */ extend public void fillRemovedSnappersVoidEntries(MhEngineEntryBlock block) { ... } /** * Fill gaps between entries with void entries. */ extend public void fillGapsVoidEntries(MhEngineEntryBlock block, sorted int->MhEngineVoidEntry[] voidEntries) { ... }
Added argument MhEngineEntry{} bayEntries
to the method shouldRemoveEntry
.
public class MhRowRemoveLoneFramesFunction extends MhSystemEngineFunction { Old: extend public bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry) { New: extend public bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry, MhEngineEntry{} bayEntries) { }
Added argument SnapperFilter filter
to the method getBay
.
public class MhBayConfigurationItem extends MhStorageConfigurationItem { Old: extend public MhSnapper getBay() { New: extend public MhSnapper getBay(SnapperFilter filter) { }
Added argument MhSnapperGroup group
to the method applyPickedUpSnappers
.
public class MhRowApplyAnimation extends MhSnapperApplyAnimation { Old: extend public void applyPickedUpSnappers(Snapper[] groupSnappers, Snapper firstS, Snapper first, box oldBound, bool needToRotateChildren) { New: extend public void applyPickedUpSnappers(MhSnapperGroup group, Snapper[] groupSnappers, Snapper firstS, Snapper first, box oldBound, bool needToRotateChildren) { }
Added argument SnapperFilter childFilter
to the public function basicConfigEq
.
Old: public bool basicConfigEq(MhSnapper a, MhSnapper b) : inline { New: public bool basicConfigEq(MhSnapper a, MhSnapper b, SnapperFilter childFilter=null) : inline {
Added argument SnapperFilter childFilter
to the public function childrenConfigEq
.
Old: public bool childrenConfigEq(MhSnapper a, MhSnapper b, function(mhConfigSortEntry, mhConfigSortEntry, Object):int sortFunc, Object env=null) { New: public bool childrenConfigEq(MhSnapper a, MhSnapper b, function(mhConfigSortEntry, mhConfigSortEntry, Object):int sortFunc, Object env=null, SnapperFilter childFilter=null) {
These work together with MhStorageConfigBehavior
now having a new method Snapper childrenFilter()
that is used in the existing method configEq(MhSnapper a, MhSnapper b, Object env=null)
to now be able to filter out specific children from the equality comparison.
The class MhUnitLoadOffsetBehavior
has been deleted as well as the global singleton mhUnitLoadOffsetBehavior
.
As such, we have also updated MhRowAnimationInfo
and removed the method Point unitLoadPopulateOffset(MhSnapper snapper)
which used this removed class.
public class MhRowAnimationInfo extends CoreObject { Removed: /** * Unit load populate offset. * Override here if you have different overhang values. */ extend public Point unitLoadPopulateOffset(MhSnapper snapper) { for (MhUnitLoadOffsetBehavior b in snapper.behaviors) { if (Point p = b.unitLoadPopulateOffset(snapper, configuration())) { return p; } } return null; } }
Removed method void removeOldMeasurements(Space space)
as it is not used.
public class MhBayEditorMeasurementsBehavior extends MhBehavior { /** * Remove old measurement. */ extend public void removeOldMeasurements(Space space) { for (s in space.?snappers) if (s in MhBayEditorMeasureDimension) space.remove(s); } }
This logic already exists in MhBayEditConfiguration
and this class handles the removal and insertion of dimensions (e.g. re-inserting dimensions when pulling props from snappers).
public class MhBayEditConfiguration extends MhStorageEditorConfiguration { /** * Remove old measurement. * Will be added on validate. */ extend public void removeOldMeasurements(Space space) { SpaceSelection sel = space.?selection; for (MhBayEditorMeasureDimension s in space.?snappers) { if (!s.isActive) continue; if (s in sel) sel.remove(s); space.undoableRemove(s); } } /** * Pull props from snappers. */ public void pullPropsFromSnappers() { removeOldMeasurements(space); for (s in snappers) { forChildrenRecursive(MhSnapper c in s) { if (c.isBay and hasRealConfig(c)) { pullPropsFromSnapper(c); insertMeasurements(c, space); } } } } }
Updated interface of method Object{} pullPropsFromSnapper
. The argument MhSnapper snapper
has been widened to Snapper snapper
.
public class MhStorageEditorConfiguration extends MhSystemConfiguration { Old: extend public Object{} pullPropsFromSnapper(MhSnapper snapper, Object env=null) { New: extend public Object{} pullPropsFromSnapper(Snapper snapper, Object env=null) { }
Updated interface of method MhSnapper{} applyToSnappers
. The return value MhSnapper{}
has been widened to Snapper{}
.
public class MhStorageEditorItem extends MhSystemConfigurationItem { Old: extend public MhSnapper{} applySnappers(Space space, CoreProperty property=null) { New: extend public Snapper{} applySnappers(Space space, CoreProperty property=null) { }
The interface of various methods in this class have been updated such that their arguments MhSnapper
or MhSnapper{}
have been widened to Snapper
or Snapper{}
. See below for the full list.
public class MhSystemConfiguration extends CoreObject { Old: extend public PushPropsVisitor pushPropsVisitor(MhSnapper snapper) { New: extend public PushPropsVisitor pushPropsVisitor(Snapper snapper) { Old: extend public PushPropsVisitor pullPropsVisitor(MhSnapper snapper) { New: extend public PushPropsVisitor pullPropsVisitor(Snapper snapper) { Old: extend public void applyTo(MhSnapper{} snappers) { New: extend public void applyTo(Snapper{} snappers) { Old: extend public void beforeApply(MhSnapper{} snappers, World w=null) { New: extend public void beforeApply(Snapper{} snappers, World w=null) { Old: extend public void afterApply(MhSnapper{} snappers, MhSnapperChangedEnv[] changedEnvs, World w=null) { New: extend public void afterApply(Snapper{} snappers, MhSnapperChangedEnv[] changedEnvs, World w=null) { Old: extend public Object{} executeApply(MhSnapper{} snappers) { New: extend public Object{} executeApply(Snapper{} snappers) { Old: extend public bool allowPush(MhSnapper snapper) { New: extend public bool allowPush(Snapper snapper) { }
Updated interface of method bool pulledFromSnapper
. The argument MhSnapper snapper
has been widened to Snapper snapper
.
public class MhSystemConfigurationItem extends CoreObject { Old: extend public bool pulledFromSnapper(MhSnapper snapper) { return false; } New: extend public bool pulledFromSnapper(Snapper snapper) { return false; } }
The method void putAisleUpdateFunctions(MhEngine engine, MhSnapper snapper, MhSnapper aisleRow, MhSnapper topRow, MhSnapper downRow)
has been removed as it is no longer used.
public class MhBayRowStretchEngineBehavior extends MhEngineBehavior { Removed: /** * Put connected aisle update function. */ extend public void putAisleUpdateFunctions(MhEngine engine, MhSnapper snapper, MhSnapper aisleRow, MhSnapper topRow, MhSnapper downRow) { SnapperSet set(); set <<? topRow; set <<? downRow; mhPutEngineRunFunction(engine, "aisleUpdateShape", snapper=aisleRow, connectedRows=set); } }
The method bool isFirstFrame(MhSnapper z)
has been removed as it is no longer used and moved to custom package.
public class MhFrameConfigBehavior extends MhStorageConfigBehavior { Removed: /** * Is first frame in selection? */ extend public bool isFirstFrame(MhSnapper z) { Snapper root = z.rootParent; SnapperSelection sel = z.singleSelection(null); if (sel.count > 1) { bool rotated = false; forChildren(MhSnapper c in root) if (c.isBay) { rotated = c.rot != 0deg; break; } Snapper[] snappers = sel.snappers.seq; snappers.sort(function snapperYPosSort, null); if (rotated) snappers.reverse(); return z == snappers.first; } return true; } }
Following the removal of the method in abstract, please proceed to implement this within the custom logic for the case of this mething being overriden.
public class DrFrameConfigBehavior extends MhDeepStorageFrameConfigBehavior { /** * Should put the config to the config manager? */ public bool shouldPutConfigToManager(MhSnapper z) { if (!isFirstFrame(z)) return false; return true; } /** * Skip config ID? */ public bool skipConfigId(MhSnapper z) { if (!isFirstFrame(z)) return true; return super(..); } /** * Is first frame in selection? */ extend public bool isFirstFrame(MhSnapper z) { ... }
The method void levelPopulate()
has been removed as it is no longer used. Replace calls with the following method void levelPopulate(MhSnapper s)
instead.
public class MhBayStretchFunction extends MhSystemEngineFunction { Removed: extend public void levelPopulate() { Replace: extend public void levelPopulate(MhSnapper s) { }
The field Rect systemRect
has been removed as it is no longer used.
public class MhRowFillVoidEntriesFunction extends MhSystemEngineFunction { Removed: public Rect systemRect; }
The method bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry)
has been removed as it is no longer used. A new method bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry, MhEngineEntry{} bayEntries)
has been added so replace calls to this method instead.
public class MhRowRemoveLoneFramesFunction extends MhSystemEngineFunction { Removed: extend public bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry) { New: extend public bool shouldRemoveEntry(MhEngine engine, MhEngineEntry frameEntry, MhEngineEntry{} bayEntries) { }
The method void initFrameVessel
has been removed as it is no longer used. Replace calls with the following method void initApplyColorFrameVessel()
from parent class MhSnapperToolAnimationG2
instead.
public class MhFlueGapAnimation extends MhSnapperSpreadToolAnimation { Removed: extend public void initFrameVessel() { New: public void initApplyColorFrameVessel() { }
The method void initFrameVessel
has been removed as it is no longer used. Replace calls with the following method void initApplyColorFrameVessel()
from parent class MhSnapperToolAnimationG2
instead.
public class MhRowApplyAnimation extends MhSnapperApplyAnimation { Removed: extend public void initFrameVessel() { New: public void initApplyColorFrameVessel() { }
The method void validateWaitingList()
has been removed as it is no longer used. A new method MhConfigRef[] validateSortedWaitingList()
has been added so replace calls to this method instead.
public class MhConfigManager { Removed: extend public void validateWaitingList() { New: extend public MhConfigRef[] validateSortedWaitingList() { }
The method MhSnapperInsertedEnv inserted(MhSnapper z, MhSnapperInsertedEnv insertedEnv)
has been removed as it is no longer used. Replace calls with the following method MhSnapperInsertedEnv inserted(MhSnapper z, MhSnapperInsertedEnv insertedEnv, SpaceSelection sel)
instead.
public class MhSnapperInsertToolAnimation extends MhSnapperSpreadToolAnimation { Removed: extend public MhSnapperInsertedEnv inserted(MhSnapper z, MhSnapperInsertedEnv insertedEnv) { Replace: extend public MhSnapperInsertedEnv inserted(MhSnapper z, MhSnapperInsertedEnv insertedEnv, SpaceSelection sel) { }
Example usage:
SpaceSelection sel = initSelectionForApply(); for (entry in insertEntries) { ... // insert snapppers code insertedEnv = inserted(insertSnapper, insertedEnv, sel); } if (insertedEnv) insertedEnv.owner.invalidateBehaviorsIfRequired(sSnapperInserted, insertedEnv); if (sel) space.select(sel);
Removed field propagateFrames
. It was used to block propagating width changes to frame entries. This ability has now been moved out to a new method bool shouldPropagateToEntry(MhEngineEntry entry, MhEngineEntry refEntry)
to better control which entry we propagate to.
public class MyRowChildWidthChangePropagateFunction extends MyRowChildChangePropagateFunction { Removed: public Bool propagateFrames; /** * Props. */ public props : cached=true { Removed: "propagateFrames"; } Added: /** * Should propagate to entry? */ extend public bool shouldPropagateToEntry(MhEngineEntry entry, MhEngineEntry refEntry) { return refEntry.isBay and entry.isBay; }
The propagation mechanism within the racking system has undergone minor revisions. Previously, propagation functions would attempt to reposition the row based on the directional vector of the noticer
or refEntry
, aiming to maintain alignment across operations. However, this approach proved limiting in multi-bay or multi-frame configurations, where entries within the same row may have differing orientations. Moreover, the previous behavior introduced unnecessary overhead by performing additional row movements solely for alignment purposes.
The rationale behind these changes is to ensure that updates and propagation to affected snappers occur prior to any row adaptation or alignment. This sequencing improves clarity and control over the propagation process, allowing adjustments to be applied more predictably.
During depth propagation changes, when the system collecting snappers needed to be propagated, the method now will only try to populate affected snappers that will get the changes instead of having additional filter during function execution to filter out non-propagatable snappers.
/** * Append propagation for row children? */ extend public void appendPropagationRowChildren(MhSnapper row, MhSnapperChangedEnv env, str key, MhSnapper{} res) { if (key == "d") { MhSnapper owner = env.owner; if (!owner.isBay and !owner.isFrame) return; ?MhSnapper parent = owner.parent; Transform t = parent.?isMulti ? parent.?toSpaceTransform() : null; forChildrenRecursive(MhSnapper c in row) { if (c.isFrame or c.isBay) { if (!t) { res << c; } else if (c.shapeBound.d == env.oldValue.safeDouble) { point p = point0.transformed(c.toSpaceTransform() - t); if (p.y == env.lastPos.y) res << c; } } } } }
As for the function arguments, the flag moveRow
is set to false
by default. We're expecting only to update row position and shape during MhRowAlignToChildrenFunction
and MhRowUpdateShapeFunction
.
case "rowChildWidthPropagate", "rowChildDepthPropagate", "rowChildHeightPropagate" : { if (env as MhSnapperChangedEnv) { SnapperSet rows(); for (s in propagatingRows(snapper, env)) { // should probably handle aisles in the aisle/flue gap engine behavior. //if (s.rootParent.isAisle) continue; rows << s; } return props { snapper=snapper, noticer=env.owner, rows=rows, moveRow=false }; //moveRow=animation.?isStretchAnimation() }; } }
Row child propagation will no longer implicitly trigger row movement. Instead, during width propagation, the function now attempts to reposition the propagated entry based on the directional vector of the refEntry
. This adjustment clarifies the function’s intent by explicitly aligning movement behavior with reference-based directionality.
public class MyRowChildWidthChangePropagateFunction extends MyRowChildChangePropagateFunction { public Object exec() { ... double diff = refEntry.w - e.w; e.setW(refEntry.w); angle eRot = e.toSpaceTransform(engine).rot.yaw; if (eRot != rot) { // Get the sign direction to move this entry. double v = eRot.v - rot.v; v /= |v|; if (refEntry.pDiff == point0) { e.move((v*diff, 0, 0)); } } else { e.move(refEntry.pDiff); } ... }
Similarly, the depth propagation function will no longer initiate row movement by default during propagation. To streamline its execution and clarify its intended behavior, a new method has been introduced and to opt out from this new approach, please set the return type for this useNewPropagate
to false.
public class MyRowChildDepthChangePropagateFunction extends MyRowChildChangePropagateFunction { /** * Return true if use new depth propagate. */ extend public bool useNewPropagate() { return true; } /** * Propagate depth. */ extend public void propagateDepth2(MhEngine engine, Snapper{} set, MhEngineRowChildEntry refEntry) { MhEngineEntry rootParent = refEntry.rootParent(engine); Transform parentT = refEntry.parent().toSpaceTransform(engine); box refB = refEntry.bound(); for (MhSnapper s in set) { ?MhEngineBoxEntry entry = engine.entry(s); if (!mhFrameOrBayEntryFilter.accepts(entry)) continue; entry.setD(refEntry.d); if (entry.rootParent(engine) == rootParent) { box b = entry.localBound(); b.transform(entry.toSpaceTransform(engine) - parentT); double diff = b.p0.y - refB.p0.y; entry.move((0, -diff, 0)); } } }
With these changes, the depth propagation function will no longer attempt to rearrange deep racking frame configurations. Its execution is now limited strictly to applying depth changes, minimizing unnecessary operations. Consequently, extensions utilizing deep racking frame setups must explicitly exclude these frames from propagation by applying the following filter when collecting affected objects.
public class DrBayRowEngineBehavior extends MhBayRowEngineBehavior { /** * Propagating filter. */ public SnapperFilter propagatingFilter(MhSnapper noticer, str key) { SnapperFilter res = super(..); if (key == "d") { if (noticer.isFrame) { // Exclude selection snappers from propagate. return makeCombinedFilter(res, NotSnapperFilter(CurrentSelectionFilter())); } else { // Added this filter so depth change will not be applied to the frame. return makeCombinedFilter(res, NotSnapperFilter(frameFilter)); } } return res; }
The current alignment implementation is no longer compatible with the newly introduced multi-bay and multi-frame configurations together with non-movable row during propagation. With that, we introduced new concept in the MhRowChildrenAlignFunction
class to anchor the affected object and only push next or previous objects while maintaining the position of changed object.
X-axis alignment:
/** * Align X. */ extend public void alignX(sorted double->(MhEngineEntry[]) groupedEntries) { // This is anchor index. int index = { if (ignoreAnchor.?v) result 0; for (k, entries in groupedEntries, index=i) { for (MhEngineBoxEntry e in entries) { if (e in tempList) ?e = tempList.get(e); if (e.wDiff != 0) result i; } } result 0; }; ... for (x in xs, start=index + 1) { // Push objects to the right of index } for (x in xs, reverse, start=index - 1) { // Push object to the left of index. } }
Y-axis alignment:
/** * Align Y. */ extend public void alignY(sorted double->(MhEngineEntry[]) groupedEntries) { // This is anchor index. int index = { if (ignoreAnchor.?v) result 0; for (k, entries in groupedEntries, index=i) { for (MhEngineBoxEntry e in entries) { if (e in tempList) ?e = tempList.get(e); if (e.dDiff != 0) result i; } } result 0; }; double[] xs = groupedEntries.keys; box bound; for (e in groupedEntries.get(xs[index])) if (first) bound = e.bound; else bound += e.bound; // Will prioritize to align on the object that changed. }
These alignments now can also be performed on different groups (blocks). All the populated entries of the row can be grouped into distinct blocks based on their y-position. This grouping by default will be conditional, only done if a difference in the y-bound of entries at the same x-position is found between entries of the same classification. However the grouping can be always done or always skipped, controlled with the groupByY
argument and Bool shouldGroupByY()
method. There may be cases where you would want to turn off this grouping, such as deep racking implemented with a non-multiframe structure (one row owns multiple child frames).
/** * Align rows. */ extend public void alignRows(MhEngineRowEntry row) { ... if (MhSystemEngineEnvironment env = systemEnvironment()) { MhEngineEntryBlock[] blocks = env.getPopulatedBlocks(snapper); MhEngineEntryBlock[] blocksToAlign = blocksToAlign(blocks); populateDistancesBetweenBlocks(blocksToAlign); for (block in blocksToAlign, index=i) { sorted double->(MhEngineEntry[]) groupedEntries(); MhEngineEntry[] entries = mhYSortedEntries(block.entries, unmodify=true); // Group entries based on x-location. for (e in entries) { ... groupedEntries.put(x, es); es << e; } // Align along x-axis. alignX(groupedEntries); // Align along y-axis. alignY(groupedEntries); } // Align filtered imported block. alignBlocks(blocksToAlign); // Move back to original parent. resetToParentTransform(engine, row, blocksToAlign); } } /** * Blocks to be align. */ extend public MhEngineEntryBlock[] blocksToAlign(MhEngineEntryBlock[] populated) { ... MhEngineEntry[] entries(); bool grpByY = false; Bool forceGroupByY = shouldGroupByY(); if (forceGroupByY) grpByY = forceGroupByY.v; // Collecting all populated entries into a seq. for (block in populated) { for (e in block.entries) { ... } } sorted double->(MhEngineEntry[]) groupedEntries(); // First pass to create all groups. for (MhEngineBoxEntry e in entries) { ... } // Second pass to add other entries that overlap with y to group. if (grpByY) { ... } // Create groups sorted by x. for (y, es in groupedEntries, index=i) { ... } ... } /** * Should group by y-pos? */ extend public Bool shouldGroupByY() { return groupByY; }
All logic in this class has been moved up to more generic class to be used by multi-bay and multi-frame as well.
New: public class MhAlignToChildrenFunction extends MhSystemEngineFunction { New: public class MhUpdateShapeFunction extends MhSystemEngineFunction {
Removed argument int adders
from method buildRows
.
public class MhSystemPopulateFunction extends MhSystemEngineFunction { Old: extend public void buildRows(MhSystemEngineEnvironment env, rect r, int adders) { New: extend public void buildRows(MhSystemEngineEnvironment env, rect r) { }
This argument can be replaced with the following code in this method.
/** * BuildOfRows */ extend public void buildRows(MhSystemEngineEnvironment env, rect r) { ... int adders = info.aisleCount(config); if (adders < 0) return; ... }
The class MhCantileverFrameChildAdjustToBehavior
has been deleted as well as the global singleton mhCantileverFrameChildAdjustToBehavior
. The logic within this class has been incorporated into parent class MhChildAdjustToBehavior
.
Removed: public class MhCantileverFrameChildAdjustToBehavior extends MhChildAdjustToBehavior { /** * Child intersect pos. * Position used to find closest snap alternative. */ public point childIntersectPos(MhSnapper owner, MhSnapper child, Object env=null) { if (isArm(child)) { // Maintain z-pos of arm regardless of its bound. box bound = child.localBound; point center = bound.center.transformed(mhTransform(child.pos, child.rot)); return (center.x, center.y, child.pos.z); } return super(..); } }
See cm.abstract.part
section in 16.5 New Features migration guide for new CustomSpecOption
class documentation .
The following functions are now part of the old pricing system. They are still available for backwards compatibility (except basePrice
which has been overloaded in core Part
).
Migration to the new pricing API should happen as soon as possible. The new pricing API is introduced in v16.5 and documented in the cm.core.part.Part
documentation.
public double customListPrice(bool includeChildren=false, str currency=null, Space space=null) {} extend public double specialListPrice(double listPrice) {} extend public Double baseOptionPrice() {} extend public Double specialOptionPrice() {} extend public double optionSpecialUpcharge() {} extend public Double upcharge() {} Old: extend public double basePrice() {} New: extend public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true) {}
See cm.abstract.part
section in 16.5 New Features migration guide for new CustomOptionSpecial
class documentation .
The upcharge method for SpecOption
has been extended to support:
Old: extend public double upcharge(ProdPart owner=null) {} New: extend public double upcharge(Part owner=null, Space space=null, bool translatePrice=false) {}
Old:
OptionSpecial
adjustments (replace or add).New:
The following fields and methods have been added and changed in the OptionSpecial
class:
// FIELDS Added: public int level; Added: public int sequence; // METHODS Added: public void copy(PartSpecial special) {} Added: extend public str optStr=(str value) {} Added: extend public str optDescStr=(str value) {} Added: extend public int level=(int value) {} Added: extend public int sequence=(int value) {} Added: extend public Part originalPart=(Part value) {} Added: extend public str originalOptStr=(str value) {} // UPDATED Old: public constructor(str partNum, str descr, bool priceReplace, double amount|, str optStr, str optDescStr, Part originalPart, str originalOptStr) {} New: public constructor(str partNum, str descr, bool priceReplace, double amount|, str optStr, str optDescStr, Part originalPart=null, str originalOptStr=null, int level=0, int sequence=-1) {} public str flattenableKey() { StrBuf res(super()); res << optStr << optDescStr New: << level New: << sequence << originalPart << originalPart.specialsKey(); return res.toS(); }
Both specOptions
and appendSpecOptions
now accept a new boolean parameter invalidateOptionPrice (default: true).
This works with the new option price caching mechanism by allowing the system to selectively invalidate the cached option price sum when spec options are modified.
Old: final public SpecOption[] specOptions=(SpecOption[] newOptions) {} New: final public SpecOption[] specOptions=(SpecOption[] newOptions, bool invalidateOptionPrice=true) {} Old: extend public void appendSpecOptions(SpecOption[] newOptions) {} New: extend public void appendSpecOptions(SpecOption[] newOptions, bool invalidateOptionPrice=true) {}
Old:
New:
invalidateOptionPriceSum()
is triggered to ensure the cache stays correctinvalidateOptionPrice=false
to skip cache invalidation if they plan to manage it manually or delay recalculation.bool invalidateWorldPrice
parameter to special functions
PartOptionItem
s
SpecOption
sAdded: extend public void putOptSpecial(PartOptionItem opt, OptionSpecial special, PropObj s=null, bool invalidateWorldPrice=true) {} Old: extend public void generateOptAdjustmentSifRows(SpecOption opt, str[] lines) {} New: extend public void generateOptAdjustmentSifRows(PartOptionItem opt, str[] lines) {} Old: extend public str optSpecialKey(SpecOption opt) {} New: extend public str optSpecialKey(PartOptionItem opt) {} Old: extend public OptionSpecial getOptSpecial(SpecOption opt, PropObj s=null) {} New: extend public OptionSpecial getOptSpecial(PartOptionItem opt, PropObj s=null) {} Old: extend public void removeOptSpecial(SpecOption opt, PropObj s=null) {} New: extend public void removeOptSpecial(PartOptionItem opt, PropObj s=null, bool invalidateWorldPrice=true) {} Old: extend public void removeOptSpecials(PropObj s=null) {} New: extend public void removeOptSpecials(PropObj s=null, bool invalidateWorldPrice=true) {} Old: extend public void removeAllSpecials(PropObj s=null) {} New: extend public void removeAllSpecials(PropObj s=null, bool invalidateWorldPrice=true) {}
PartOptionItem opt
: Option for row to get cell for (can be null)int columnIdx
: Column index to get cell for Part part
: Part owning option row to get cell for (can be null)
opt
is null or column index is out of bounds, returns getDefaultCell
getCellBrush
Old:
GridCell
s New:
getOptionRowCell
for each column and appending it to the returned GridCell
sequenceRemoved: public void onOKButtonClick(Object sender, Object args) {}
OptionSpecial
type on OK button clickgenerateSpecial
to create the new special on OK button clickIn 16.5, the ProdPartQueryDialogDataEnv
has changed it's backing data structures,
replacing the str->Part parts
, int->str rowIDs
, and str->str{} options
maps with a single QueryRowData[] queryRows
data sequence.
Cell highlighting has also been introduced in the QueryDialog
.
As a result, the following functions have been removed and added to QueryProdPartGridBuilderEnv
.
Removed: public str rowIdentifier(Object data) {} Added: public GridCell[] getRowCells(Object data) {} Added: public Brush getCellBrush(Object data, int columnIdx) {}
With the addition of the new "Add Option" feature in the query dialog and the new data structure of QueryDialogDataEnv
,
changes in ProdPartQueryDialogBehavior
have been made.
initTopWindow
to utilize new ProdPartQueryControlWindow
for ProdPart
sinitTopWindowEvents
to handle events from ProdPartQueryControlWindow
onAddOptionBtnClicked
to handle add option button click from ProdPartQueryControlWindow
getCustomSpecialDialog
function:
The following interface additions, removals, and changes have been made in ProdPartQueryDialogBehavior
:
// ADDED/REMOVED INTERFACES Added: public SubWindow initTopWindow(QueryDialog parent) {} Added: public void initTopWindowEvents(SubWindow topWindow) {} Added: public DialogWindow getCustomSpecialDialog(QueryDialog dialog, int row) {} Added: extend public void onAddOptionBtnClicked(Object sender, Object args) {} Removed: extend public str getPartIDFromOptionID(QueryDialog dialog, str id) {} Removed: extend public Part getPartFromOptionID(QueryDialog dialog, str id) {} // MODIFIED INTERFACES Old: extend public str getOptCodeFromGrid(QueryDialog dialog, str id) {} New: extend public str getOptCodeFromGrid(QueryDialog dialog, int row) {} Old: extend public str getOptDescriptionFromGrid(QueryDialog dialog, str id) {} New: extend public str getOptDescriptionFromGrid(QueryDialog dialog, int row) {} Old: public DialogWindow getSpecialDialog(QueryDialog dialog, str id) {} New: public DialogWindow getSpecialDialog(QueryDialog dialog, int row) {} Old: extend public DialogWindow getOptionSpecialDialog(QueryDialog dialog, str id |, Part part) {} New: extend public DialogWindow getOptionSpecialDialog(QueryDialog dialog, int row |, Part part) {}
With the new data structure of QueryDialogDataEnv
, changes in ProdPartQueryDialogDataEnv
have been made.
buildQueryRowData
: Overridden to support ProdPart
option rowsbuildPartOptions
: Created to build part option rows for ProdPart
screatePartRowData
: Overridden to create QueryProdPartRowData
s for ProdPart
rowscreateOptionRowData
: Created to build QueryOptionRowData
s for ProdPart
option rowsrefreshQueryRowData
: Overridden to optimize rebuild processpublic str->str{} options
field:
QueryRowData[] queryRows
as QueryOptionRowData
ssetParts
: No longer needed with new data structurebuildParts
: ''buildPartOptions
: ''getPartIDFromOptionID
: ''getPartFromOptionID
: ''getSpecial
: Logic has been moved to new QueryRowData
typeputSpecial
: ''removeSpecial
: ''The following interface additions and removals have been made in ProdPartQueryDialogDataEnv
:
// ADDED INTERFACES Added: public void buildQueryRowData(Part[] parts=null) {} Added: extend public void buildPartOptions(QueryRowData partRow) {} Added: public QueryRowData createPartRowData(Part part) {} Added: extend public QueryRowData createOptionRowData(SpecOption option, QueryRowData partRow) {} Added: public void refreshQueryRowData() {} // REMOVED INTERFACES Removed: public str->str{} options; Removed: public Part[] setParts(Part[] value) {} Removed: public void buildParts() {} Removed: extend public void buildPartOptions(str partRowID, ProdPart part) {} Removed: extend public void buildPartOptions(ProdPart part) {} Removed: public PartSpecial getSpecial(str id) {} Removed: public void putSpecial(str id, PartSpecial special) {} Removed: public void removeSpecial(str id) {} Removed: extend public str getPartIDFromOptionID(str id) {} Removed: extend public Part getPartFromOptionID(str id) {}
The field elevSpace
has changed its type from Space
to a more specific ElevSpace
. This reduces the need for casting.
Old: public Space elevSpace : stream=null, copy=null; New: public ElevSpaceG2 elevSpace : stream=null, copy=null; # Example Old: if (elevSpace as ElevSpaceG2) { New: if (elevSpace) {
A new field bool locationLocked
has been added. As such, the constructor has been updated to set this field.
public class ElevAutoSnapperEnvG2 extends PropObj { Old: public constructor(str key, point pos, orientation rot) { New: public constructor(str key, point pos, orientation rot, bool locationLocked=false) { }
The class ElevAutoDimEnvG2 has also had its constructor updated to set this field.
public class ElevAutoDimEnvG2 extends ElevAutoSnapperEnvG2 { Old: public constructor(str key, point p0, point p1, double d, UserTextStyle ts, UserDimensionStyle ds, str prefix="", bool allowDimSelect=true) { New: public constructor(str key, point p0, point p1, double d, UserTextStyle ts, UserDimensionStyle ds, str prefix="", bool allowDimSelect=true, bool locationLocked=false) { }
Moved a method Transform loadDirectionXForm()
down from UnitLoadPallet
to UnitLoad
.
public class UnitLoad extends CoreObject { /** * Transform for load direction. */ extend public Transform loadDirectionXForm() { return null; } }
Updated interface of method bool eq
. Added a new optional argument str->Object args=null
.
public class UnitLoad extends CoreObject { Old: extend public bool eq(UnitLoad m) { New: extend public bool eq(UnitLoad m, str->Object args=null) { }
At the moment, only one value in args
is used in this method, "propsToIgnore"->str[]
which can be used to ignore specific props in specific equality checks. It serves as an alternative to overriding str[] propsIgnoreEqCheck()
which will ignore the props for all equality checks of that UnitLoad
.
public class UnitLoad extends CoreObject { /** * Equal? */ extend public bool eq(UnitLoad m, str->Object args=null) { ... ?str[] propsToIgnore = args.?get("propsToIgnore"); if (propsToIgnore) propsToIgnore += propsIgnoreEqCheck(); else propsToIgnore = propsIgnoreEqCheck(); for (k in propDefs.order) { if (k in propsToIgnore) continue; ... } } }
As a result of this change, we have also removed the function bool unitLoadEq(UnitLoad unitLoad, UnitLoad l)
. Previous calls to this function have been replaced by directly calling the eq(UnitLoad m, str->Object args=null)
method.
Removed: public bool unitLoadEq(UnitLoad unitLoad, UnitLoad l) { return unitLoad.eq(l); } Example usage: unitLoad.eq(l);
Added a new method MhPalletLoadSide getLoadDirection()
so that UnitLoad
can return a direction value. This value was previously only used in UnitLoadPallet
but now there is an interface so that other unit load classes can return a direction as well.
public class UnitLoad extends CoreObject { /** * Get load direction. */ extend public MhPalletLoadSide getLoadDirection() { return null; } }
Updated the interface of method Primitive3D loadDir3D
. The argument UnitLoadPallet pallet
has been widened to UnitLoad ul
.
public class UnitLoadPreviewSnapper extends UnitLoadSnapper { Old: extend public Primitive3D loadDir3D(UnitLoadPallet pallet) { New: extend public Primitive3D loadDir3D(UnitLoad ul) { }
Previous implementations of loadDir3D(UnitLoadPallet ul)
would often access a direction value mhPalletLoadSide
that was previously only available to UnitLoadPallet
. You can switch those calls over to UnitLoad.getLoadDirection()
instead without needing to cast to UnitLoadPallet
.
Example: public class UnitLoadPreviewSnapper extends UnitLoadSnapper { /** * Load Direction Arrow 3D. */ extend public Primitive3D loadDir3D(UnitLoad ul) { MhPalletLoadSide dir = ul.getLoadDirection(); if (!dir) return null; ... } }
Updated the interface of method void zoomToPreview
. The argument Snapper s
has been removed. The reason for this is we have switched the previous implementation of zooming in to a specific snapper's bound to a zoomExtents
of the view.
public class UnitLoadDialog extends DialogWindow { Old: extend public void zoomToPreview(Snapper s) { if (!preview3D or !preview3D.space) return; if (!s) { for (ns in preview3D.space.snappers) { s = ns; } } if (!s) return; disableUndo { preview3D.zoomBound(s.bound); } } New: extend public void zoomToPreview() { if (!preview3D or !preview3D.space) return; if (preview3D.space.snappers.empty) return; preview3D.zoomExtents(undoable=false); } }
Updated the interface of method void zoomToPreview
. The argument Snapper s
has been removed. The reason for this is we have switched the previous implementation of zooming in to a specific snapper's bound to a zoomExtents
of the view.
public class UnitLoadTemplateSelectorDialog extends DialogWindow { Old: extend public void zoomToPreview(Snapper s) { if (!preview3D or !preview3D.space) return; if (!s) { for (ns in preview3D.space.snappers) { s = ns; } } if (!s) return; disableUndo { preview3D.zoomBound(s.bound); } } New: extend public void zoomToPreview() { if (!preview3D or !preview3D.space) return; if (preview3D.space.snappers.empty) return; preview3D.zoomExtents(undoable=false); } }
The class MhUserSettings
has been renamed to UnitLoadUserSettings
.
The global function MhUserSettings mhUserSettings()
has been replaced by UnitLoadUserSettings ulUserSettings()
.
Old: public class MhUserSettings extends UserSettings { New: public class UnitLoadUserSettings extends UserSettings { Old: public MhUserSettings mhUserSettings() { New: public UnitLoadUserSettings ulUserSettings() {
The class StdApplicationManager
and ApplicationManager
has been combined into a single class now. This should simplify existing code by eliminating the need to cast (a sample example is listed).
Old: public class StdApplicationManager { New: public class ApplicationManager { # Example Old: app = appManager.StdApplicationManager.?getApplication(id) ?? application; New: app = appManager.?getApplication(id) ?? application;
Added new arguments to addButton
method to control the standard brush and the hover brush of buttons in the notify strip.
Old: extend public NotifyPartButton addButton(str text, str tooltip=null, function(Control, NotifyButtonArgs) callback=null, Object callbackArg=null, bool closeAfterClick=false, Timespan snoozeAfterClick=null, function():Timespan snoozeAfterClickCallback=null, bool highlight=false, bool triggerCallbackOnShow=false, Image image=null) New: extend public NotifyPartButton addButton(str text, str tooltip=null, function(Control, NotifyButtonArgs) callback=null, Object callbackArg=null, bool closeAfterClick=false, Timespan snoozeAfterClick=null, function():Timespan snoozeAfterClickCallback=null, bool highlight=false, bool triggerCallbackOnShow=false, Brush customStdBrush=null, Brush customHoverBrush=null, Color customLabelColor=null, Image image=null)
Added new arguments to the constructor of NotifyPartButton
to store the standard brush and the hover brush when creating buttons for the notify strip.
Old: public constructor(NotifyMessage message, str text, str tooltip=null, function(Control button, NotifyButtonArgs args) callback=null, Object callbackArg=null, bool closeAfterClick=false, // MergeTODO : add a close callback here in 8.0 Timespan snoozeAfterClick=null, function():Timespan snoozeAfterClickCallback=null, bool highlight=false, bool triggerCallbackOnShow=false, Image image=null) New: public constructor(NotifyMessage message, str text, str tooltip=null, function(Control button, NotifyButtonArgs args) callback=null, Object callbackArg=null, bool closeAfterClick=false, // MergeTODO : add a close callback here in 8.0 Timespan snoozeAfterClick=null, function():Timespan snoozeAfterClickCallback=null, bool highlight=false, bool triggerCallbackOnShow=false, Brush customStdBrush=null, Brush customHoverBrush=null, Color customLabelColor=null, Image image=null)
Force initAfterInstantiate()
to call ancestor super class in order to ensure gid protocol is always respected.
Old: extend public void initAfterInstantiate() { New: extend public void initAfterInstantiate() : require super {
The restoreCleanup()
function has been removed. Its primary functionality made unexpected modifications to the snapper being copied. As a replacement to calling restoreCleanup()
, use if (Space space = getSpace()) space.select(SpaceSelection(this));
to restore the original selection.
If modifications to the original snapper is required for some reason (which is highly discouraged), consider making use of the snapper functions beforeUserCopied(..)
or userCopied(..)
instead.
Removed: final public void restoreCleanup() {
In the class CetQLWorldManager
, the method destroySpace
has been renamed to removeSpace
.
Old: extend public void destroySpace(Space s) { New: extend public void removeSpace(Space s) {
In the class CetQLSpaceManager
, the field removeSnapperSet has been removed.
Old: public SnapperRef{} removeSnapperSet : deprecated;
As SnapperRef has been reworked to also keeps track of the space guid to enforce greater consistency, we have a new and recommended way to construct a SnapperRef.
Old: public constructor(guid gid) { Old: public constructor(Snapper z) { New: public constructor(Snapper z, Space space) {
The access modifiers for field image
has been changed, a new setter method is introduced.
Old: public Image image : copy=reference; New: private Image image : copy=reference, public readable; New: final public void setImage(Image i) {
A new function for invalidating ItemTag
s in a space has been added.
ItemTag
s in bsp.singularities
, calling invalidate(..)
on eachBlockSpace
s, calling invalidateItemTags(..)
on each/** * Invalidate all item tags in BSP. */ extend public void invalidateItemTags(dirty2D flag2D=dirty2D.all) { for (ItemTag s in bsp.?singularities) s.invalidate(flag2D); for (BlockSnapper blockSnapper in snappers) { BlockSpace blockSpace = blockSnapper.block.?blockSpace; blockSpace.?invalidateItemTags(..); } }
A new function for invalidating BlockSpace
ItemTag
s has been added.
block.?updateOwners(..)
after the invalidation has been done /** * Invalidate all item tags in BSP. */ public void invalidateItemTags(dirty2D flag2D=dirty2D.all) { super(..); block.?updateOwners(recursive=false, excludedSpace=this, flag2D=flag2D, flag3D=dirty3D.none); }
# CollFilesDialogResizer Removed: resize Removed: needUpdateOnResize Added: resize0 Added: resize1
The constructor for CollProjectTvItem
has been updated to always show customer information by default. Additionally, the constructor now allows optional configurations like bolding the labels for active projects and whether the tree view item itself should be clickable or not.
Old: public constructor(CollProjectInfo project, bool showCustomer=false, bool showLastModified=true) { New: public constructor(CollProjectInfo project, bool showCustomer=true, bool showLastModified=true, bool boldActive=true, bool allowClick=true) {
The following mouse operation handling methods have been removed as the tree view item no longer displays a CollProjectTVITag
beside local CollabPro projects.
Removed: public bool enter(TreeViewMouseInfo mi) {} Removed: public bool exit(TreeViewMouseInfo mi) {} Removed: public bool move(TreeViewMouseInfo mi) {}
The following class field has been removed and dereferenced from the FilePageCollaboration
dialog.
Removed: public Button refreshProjBtn;
As part of our efforts to standardize the layout and interface of CollabPro's file menu page, the following build and relayout methods have been removed. To further extend from the FilePageCollaboration
dialog, additional customized build methods should be supplied by overriding the main build()
method instead. For customized relayouts, they should be included by overriding the main relayout()
method as well.
Removed: extend public void buildInfoSW() {} Removed: extend public void buildContentSW() {} Removed: extend public void buildButtons(Brush brush) {} Removed: extend public void buildSearch(Brush brush) {} Removed: extend public void relayoutInfoSW() {} Removed: extend public void relayoutContentSW() {}
Removed an argument that was not used
Old: final public void endModify(ProgressDialog pd) { New: final public void endModify() {
Old: public Snapper loadDwgFiles(Url[] files, DropFiles drop=null, Point dropSpacePos=null, Point pos=null, bool exception=false) { New: public Snapper{} loadDwgFiles(Url[] files, DropFiles drop=null, Point dropSpacePos=null, Point pos=null, bool exception=false) {
Many interfaces have been changed to accommodate the new multi-select functionality. Most notably, a lot of functions now take a Snapper argument that they operate on instead of always operating on the selected DWG. This makes it possible to operate on individual DWGs in the selection when necessary.
The following interfaces that were used to get the currently selected DWG have been updated to return the set of all selected DWGs.
Old: package Snapper activeDwgSnapper : public readable; Old: final public Snapper snapper() { New: final public Snapper{} selection() {
Old: extend public DwgTvi selectedTvi() { New: final public DwgTvi{} selectedTVItems() {
The following interface that was used to select a DWG has been updated to also handle appending to selection. The reason for it being 'smart' is that it is not a simple select. It can pop up a modal dialog and keep modified DWGs in selection even if removePrevious=true
.
Old: final public void changeActiveDwg(Snapper s, bool rebuild=true) { New: final public bool smartSelect(Snapper dwgSnapper, bool removePrevious=true, bool invokeCallback=true) {
To be able to select many DWGs at once the following interfaces have been added.
Added: final public bool smartSelect(Snapper{} dwgSnappers, bool removePrevious=true, bool invokeCallback=true) { Added: final public bool smartSelect(str{} keys, bool removePrevious=true, bool invokeCallback=true) {
The dwgSnapperIsParent
-field has been removed as it is no longer needed. To figure out if a tree view item is a parent it is possible check item in DwgParentTvi
instead. Selected parent tree view items will not contribute to final public Snapper{} selection()
.
Removed: private bool dwgSnapperIsParent : public readable;
The following methods are deemed no longer needed and have been removed. There is no direct replacement for them.
Removed: final public void setScaleFromInsUnits(bool update=true) { Removed: final public Snapper snapperFromItem(TreeViewItem item) { Removed: final public str getUnitKey() {
The fileTreeViewChanged()
-function has been removed. To update the file tree view, call updateFileTreeView
or updateContent
instead.
Removed: final public void fileTreeViewChanged() {
These methods can be replaced with methods with the same name on DwgCaptureSnapper
.
Removed: final public bool sourceFileMissing() { Removed: final public bool sourceFileOutOfDate() {
The isCaptureSnapper()
-function has been removed. As a replacement, check snapper in DwgCaptureSnapper
instead.
Removed: final public bool isCaptureSnapper() : inline {
The getDwgSource()
-function has been removed. Use the getSource()
-function on DwgSnapper
or DwgCaptureSnapper
instead.
Removed: final public Url getDwgSource() {
The getDwgRoot()
-function has been removed. Use the getDwgRoot()
-function in cm/core/dwg/dwg.interface.cm instead.
Removed: final public DwgRoot getDwgRoot() {
Old: private bool dwgSnapperHasMultipleCopies : public readable; New: final public bool hasMultipleCopies(Snapper snapper) { Old: extend public bool apply(Point pos=null, bool exception=false) { New: extend public bool apply(Snapper snapper, Point pos=null, bool exception=false) { Added: extend public bool apply(Snapper{} snappers, Point pos=null, bool exception=false) {
The functions below have been updated to return the loaded DWG snappers, in order to improve code readability. For the method that returned a bool, the new will return null if and only if it previously returned false.
Old: extend public bool loadDwgFile(Url file, bool xref=false, Window parent=null, New: extend public Snapper loadDwgFile(Url file, bool xref=false, Window parent=null, Old: final public void loadDwgFile(Url file, DwgRoot root, bool xref=false, bool exception=false, bool dragDrop=false) { New: final public Snapper loadDwgFile(Url file, DwgRoot root, bool xref=false, bool exception=false, bool dragDrop=false) { Old: final public void animate(Url file, bool repeat=true, Window parent=null, DropFiles drop=null, Point dropSpacePos=null) { New: final public Snapper animate(Url file, bool repeat=true, Window parent=null, DropFiles drop=null, Point dropSpacePos=null) {
A Snapper
argument has been added to replace uses of the activeDwgSnapper
-field in the following methods. The argument expects either a DwgSnapper
or a DwgCaptureSnapper
.
Old: extend public bool importSettingsChanged() { New: extend public bool importSettingsChanged(Snapper snapper) { Old: final public DwgSnapper{} getXRefsNoInsert() { New: final public DwgSnapper{} getXRefsNoInsert(Snapper snapper) { Old: final public void groupActiveDwgSnapperWith(Snapper{} snappers) { New: final public void groupDwgSnappers(Snapper main, Snapper{} snappers) { Old: extend public int checkForChanges() { New: extend public int checkForChanges(Snapper{} snappers=dwgDialog.?selection()) { Old: final public void dropOnCursor(DropFiles drop, Point spacePos) { New: final public void dropOnCursor(Snapper snapper, DropFiles drop, Point spacePos) { Old: extend public void locateSnapper() { New: extend public void locateSnapper(Snapper snapper) { Old: extend public void reloadSnapper(Url u=null) { New: extend public void reloadSnapper(Snapper snapper, Url u=null) { Old: extend public void reloadDwgSnapper(Url u=null) { New: extend public void reloadDwgSnapper(Snapper snapper, Url u=null) { Old: extend public void reloadCaptureSnapper(Url u=null) { New: extend public void reloadCaptureSnapper(Snapper snapper, Url u=null) { Old: extend public void renameSnapper(str newName=null) { New: extend public void renameSnapper(Snapper snapper, str newName=null) {
Remove an item from the dwg dialog:
Old: extend public void removeSnapper(Snapper candidate, bool update=true, bool anySnapper=true) { New: extend public void removeSnapperFromDialog(Snapper candidate, bool update=true) {
Remove item from space and dwg dialog:
Remove: extend public void removeSnapper() {
To remove from space use removeDwgSnapper(Snapper snapper)
instead.
Renamed variable for clarity
Old: public int64{} l; New: public int64{} layers; Old: public constructor(DwgSnapper dwg, int64 l, bool undo=true) { New: public constructor(DwgSnapper dwg, int64{} layers, bool undo=true) {
Many methods now take an argument to specify the DwgSnapper
being edited.
Old: final public void setSnappableLayer(DwgLayer z, bool v) { New: final public void setSnappableLayer(DwgLayer z, bool v, Snapper snapper) { New: final public void setSnappableLayer(DwgLayer z, bool v, Snapper{} snapper) { Old: final public void setForceLayer(DwgLayer z, bool v) { New: final public void setForceLayer(DwgLayer z, bool v, Snapper snapper) { New: final public void setForceLayer(DwgLayer z, bool v, Snapper{} snapper) { Old: final public void setLayerColor(DwgLayer{} layers, color c, bool ignoreUserMaterial) { New: final public void setLayerColor(DwgLayer{} layers, color c, bool ignoreUserMaterial, Snapper snapper) { New: final public void setLayerColor(DwgLayer{} layers, color c, bool ignoreUserMaterial, Snapper{} snapper) { Old: final public void setLayerColor(DwgLayer layer, color c, bool ignoreUserMaterial) { New: final public void setLayerColor(DwgLayer layer, color c, bool ignoreUserMaterial, Snapper snapper) {
One method was given the responsibility of finding all snappers being updated itself, since it needed this to create the proper undo steps:
Old: final public void setVisibleLayer(DwgLayer z, bool v, bool updateVisibility=true) { New: final public void setVisibleLayer(bool v, DwgLayerTreeViewItem clickedItem, bool updateVisibility=true) {
Removed: extend public bool equal(DwgSettingsEnv target, bool transforms=true, bool units=true, bool scale=true, bool cap=true, bool import3D=true, bool layers=false, bool captureGraphics=true) { Old: extend public bool equal(DwgSettingsEnv target, bool transforms=true, bool units=true, bool scale=true, bool cap=true, bool import3D=true, bool layers=false, bool captureGraphics=true, bool explode=true) { New: extend public bool equal(DwgSettingsEnv target, bool transforms=true, bool units=true, bool scale=true, bool cap=true, bool import3D=true, bool layers=false, bool captureGraphics=true, bool explode=true, bool xrefs=true) {
Old: extend public void update(bool recursive=true) { New: extend package void update(bool recursive=true) {
Removed: final public DwgSnapper{} insertAllXRefs(Window parent=null, Space space=null, bool relocate=true) {
Instead use
final public DwgSnapper{} insertAllXRefs(Window parent=null, Space space=null, bool relocate=true, bool insert=true, Bool xRefImportCancelled=null) {
Some interfaces have been changed from public to private as they are not intended to be used outside of DwgPropertiesCard
.
Old: final public SubWindow buildTopWin(Window parent) { New: final private SubWindow buildTopWin(Window parent) { Old: final public void updateSettingsDrop() { New: final private void updateSettingsDrop(DwgPropertiesCardEnv env=null) { Old: final public void updateContent(bool scrollToLatestPos=false) { New: final public void updateContent(Snapper{} snappers, bool scrollToLatestPos=true) { Old: final public void setPresetScale(double scale) { New: final public void setPresetScale(double scale, bool invokeCallback=true) { Old: final public str getUnitKey() { New: final private str getUnitKey() { Removed: final public void updateDisplays() { Added: final private void updateActualScaleDisplay() { Added: final private void updateSizePreviewDisplay(size dims) { Added: final private void updateActualDimensionDisplay(size dims) { Old: final public double getActualScale() { New: final private double actualScale() { Removed: final public void setMessage(str msg) { Removed: final public void updateMessage(bool update=true) { Removed: final public str updateMessage2() { Added: final private void updateInfoDisplay(DwgPropertiesCardEnv env) {
The following methods are deemed no longer needed and have been removed. There is no direct replacement for them.
Removed: final public bool enablePresetsDD(Snapper selection) { Removed: extend public double getUnitValue () { Removed: final public void setRawScale() {
The reBuild()
-function is no longer needed, since updateContent()
now updates all UI elements.
Removed: final public void reBuild() {
The setScaleFromInsUnits()
-function is no longer needed and has been removed.
Removed: final public void setScaleFromInsUnits(bool update=false) {
Old: extend public void fitToPaper() {
Use these instead (in cm/core/dwg/dwgPropertiesCard.cm)
New: public void fitToPaper(Snapper snapper, Space insertSpace=null) { New: public void fitToPaper(Snapper{} snappers=null, Space insertSpace=null) {
The undo operation can now undo multiple layers at once.
Old: public int64 l; New: public int64{} layers; Old: public constructor(DwgSnapper dwg, int64 l, bool undo=true) { New: public constructor(DwgSnapper dwg, int64{} layers, bool undo=true) {
renamed styles map and made it package
Old: public str->DwgStyle styles(); New: package str->DwgStyle nameStyleMap();
Return DibImage
for the use of SaveFavoriteDialog
and BrowseFavoriteDialog
Old: final public MemoryImage thumbnail(Url location) { New: final public DibImage thumbnail(Url location) {
Change to store DibImage
for the use of FavoriteCache
, reducing GDI Object usage.
Old: public MemoryImage image; New: public DibImage image;
MemoryImage
to be casted to DibImage
and destroyed explicitly to reduce GDI Object usage.
Old: public MemoryImage favoriteThumbnail(Url location, bool progress=false) { New: public DibImage favoriteThumbnail(Url location, bool progress=false) {
The area method in APath2D
has now been implemented.
public double area() {
Therefore, this approximate area method has been removed.
Removed: extend public double area(angle arcResolution=15 deg, double deviationTol=0.1) {
As of 16.5, a new interface for lead time has been added to core Part
. As a result, a new lead time column has been created in cm/core/init/leadTimeColumn.cm
.
Extensions who have their own Lead Time column should migrate to the core version to avoid duplication.
Developers can migrate by:
leadTime()
in Part to get accurate value for core Lead Time columnoverridePartColumns()
on Part to return custom lead time column in place of core column/** * Lead Time Column for Parts */ public class LeadTimeColumn extends BasicPartColumn { /** * Constructor. */ public constructor() { super("coreLeadTime"); } /** * Initial Visibility. */ public symbol[] initialVisibility() { return [#none]; } /** * Return property value for part. */ public Object value(Part part, Space space) { return part.leadTime(); } }
A new hooks.cm file has been added to the cm/core/itemTag
package. The public functions below have been moved to it from the itemTag.cm file.
public bool updateWorldItemTags(World world, bool validate, PriceChangeEnv env) {} public bool updateSpaceItemTags(Space space, bool validate, function():bool interrupt, bool force) {} public void updateSpaceItemTags(Space space) {}
A new field str articleCodeText
has been added in ItemTagInfo
.
Part
associated with the ItemTag
getTagText()
function returns ItemTagInfo
text based on setting
ItemTagInfo
The fields value is set in core Part
during updateItemTags()
or it can be set on construction with this new constructor:
/** * Creates a new ItemTagInfo. */ public constructor(str text, str k, str textType, str articleCode) { articleCodeText = articleCode; this(text, k, textType); }
The new getTagText()
function checks the setting value to return either the articleCodeText
or the tagText
:
/** * Get tag text. */ extend public str getTagText() { if (displayArticleCodeForItemTag) return articleCodeText; return tagText; }
A new functions.cm file has been added to the cm/core/itemTag
package. The public functions below have been moved to it from the itemTag.cm file.
public void enableItemTagsAlwaysUpdate(bool on) {} public bool itemTagsAlwaysUpdateEnabled() {} public void removeItemTags(Snapper this) {}
The following functions were added to PartProxy
in v16.5.
These functions were added in support of the new pricing model which is documented in the compile-time section for cm.core.part.Part
.
New: extend public double basePrice(Part part, bool includeChildren=false, Space space=null, bool translatePrice=true) {} New: extend public double optionPriceSum(Part part, bool includeChildren=false, Space space=null, bool translatePrice=true, bool invalidate=false) {}
In v16.5, a new constructor has been introduced for Part to support the new pricing model.
Previously, Part accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(Snapper snapper, str articleCode, str description, double listPrice, ...)
listPrice
.data._useNewPricing = false
to use old pricing behavior.constructor(Snapper snapper, str articleCode, str description, double basePrice, Double optionPriceSum, ...)
basePrice
and optionPriceSum
separately.data._useNewPricing = true
to activate new pricing behavior.Double optionPriceSum
Parameter
generateOptionPriceSum()
documentationinvalidateOptionPriceSum
basePrice
and optionPriceSum
.Old: new Part(snapper, "PART NUM", "PART DESC", listPrice=199.99); New: new Part(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=49.99); New: new Part(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=null);
The following functions are now part of the old pricing system. The new pricing API is introduced in v16.5 and documented in the next section. The old API will remain for backwards compatibility but is expected to be removed in a future version of CET.
extend public double customListPrice() extend public Double upcharge()
Old:
PartProxy
list price valuePartData
cached list price valueNew:
customListPrice()
listPrice()
and calculatedListPrice(..)
documentation for more migration informationOld:
upcharge()
returns null.New:
optionPriceSum()
.useNewPricing()
== false.upcharge()
optionPriceSum(..)
and calculatedListPrice(..)
documentation for more migration informationThe following functions were introduced as part of the new pricing system. They replace Old pricing methods that relied on a cached list price.
Added: final public bool useNewPricing() {} Added: extend public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true) {} Added: extend public double optionPriceSum(bool includeChildren=false, Space space=null, bool translatePrice=true, bool invalidate=false) {} Added: final public double calculatedListPrice(bool includeChildren=false, Space space=null) {} Added: extend public Double generateOptionPriceSum() {} Added: extend public void invalidateOptionPriceSum() {}
Indicates whether the new part pricing system should be used on the Part instance. An opt-in feature flag to the new pricing system.
PartData
listPrice
, upcharge
, basePrice
, optionPriceSum
, etc.bool includeChildren
(optional)
Space space
(optional)
translatePrice
bool translatePrice
(optional)
space
Old:
basePrice()
is implemented in cm.abstract.part.AbsPart
DsPart
to return catalog base priceNew:
basePrice()
is implemented in cm.core.part.Part
PartSpecial
is foundPartProxy
base price valuePartData
cached base pricebasePrice
for the PartlistPrice
with basePrice
where you need only the product’s inherent costbool includeChildren
(optional)
Space space
(optional)
translatePrice
bool translatePrice
(optional)
space
bool invalidate
(optional)
Old:
upcharge()
is implemented in cm.abstract.part.AbsPart
PartProxy
New:
optionPriceSum()
is implemented in cm.core.part.Part
useNewPricing
is false, returns upcharge()
PartProxy
option price sum valuePartData
cached option price sum
invalidate=true
), value is regenerated automatically with generateOptionPriceSum()
upcharge()
with optionPriceSum()
invalidateOptionPriceSum()
before recalculation.bool includeChildren
(optional)
Space space
(optional)
translatePrice
bool translatePrice
(optional)
space
bool invalidateOptionPriceSum
(optional)
Old:
customListPrice(..)
is primary source of list price value
PartProxy
list price valuePartData
cached list price valuelistPrice()
when useNewPricing == false
New:
calculatedListPrice(..)
is primary source of list price in new pricing model
basePrice(..) + optionPriceSum(..)
)listPrice()
when useNewPricing == true
customListPrice(..)
to customize list price, migrate this logic into:
basePrice(..)
(for foundational Part price)optionPriceSum(..)
/generateOptionPriceSum()
(for option pricing logic).listPrice()
will automatically call calculatedListPrice(..)
if useNewPricing
is enabled.Old:
New:
ProdPart
and DsPart
generateOptionPriceSum()
in your extended Part class.invalidateOptionPriceSum()
) when option state changes to trigger regeneration.Old:
New:
optionPriceSum
value to trigger regenerationinvalidateOptionPriceSum()
whenever Part configuration changes (options, children, etc.)invalidateOptionPriceSum()
after any Part modifications that may affect option pricing.The following functions were added or changed in Part
in v16.5. The new pricing model API is documented above and not included in this section.
translatePrice
functions were modified to remove unused includeChildren
parameter.
Added: extend public double totalBasePrice(bool includeChildren=false, Space space=null) {} Added: extend public double totalOptionPriceSum(bool includeChildren=false, Space space=null) {} Old: final public double translatePrice(double price, bool includeChildren=false, Space space=null) { New: final public double translatePrice(double price, Space space=null) { Old: final public double translatePrice(double price, currencyId currency, bool includeChildren=false, Space space=null) { New: final public double translatePrice(double price, currencyId currency, Space space=null) {
As of 16.5, a new interface for lead time has been added to core Part
. It's value is displayed in the new LeadTimeColumn
implemented in cm/core/init/leadTimeColumn.cm
.
In cm/core/part/part.cm /** * Get lead time string. * Ex. 20 days, 3 weeks, etc. */ extend public str leadTime() { return ""; }
In v16.5, a new constructor has been introduced for WorldPart to support the new pricing model.
Previously, WorldPart accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(World world, str articleCode, str description, double listPrice, ...)
listPrice
value to cache.cm.core.part.Part
for more infoconstructor(World world, str articleCode, str description, double basePrice, Double optionPriceSum, ...)
basePrice
and optionPriceSum
separately for caching.cm.core.part.Part
for more infobasePrice
and optionPriceSum
.Old: new WorldPart(snapper, "PART NUM", "PART DESC", listPrice=199.99); New: new WorldPart(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=49.99); New: new WorldPart(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=null);
put
remove
removeAll
See cm.core.part.attributes
section in 16.5 New Features migration guide for new PartAnnotationHolder
class documentation.
The following functions were added to PartData
in v16.5.
These functions were added in support of the new pricing model which is documented in the compile-time section for cm.core.part.Part
.
// FUNCTIONS New: extend public bool useNewPricing() {} New: extend public double basePrice() : abstract {} New: extend public void setBasePrice(double v) : abstract {} New: extend public Double optionPriceSum() : abstract {} New: extend public void setOptionPriceSum(Double v) : abstract {}
See cm.core.part.attributes
section in 16.5 New Features migration guide for new PartAnnotation
class documentation.
In v16.5, a new constructor has been introduced for BasicPartData to support the new pricing model.
Previously, BasicPartData accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(Snapper snapper, str articleCode, str description, double inPrice=0, double outPrice=0, ...)
outPrice
(list price) value to cache._useNewPricing
as false to use old pricing behavior.constructor(Snapper snapper, str articleCode, str description, double basePrice=0, Double optionPriceSum=null, ...)
basePrice
and optionPriceSum
separately for caching._useNewPricing
as true to activate new pricing behavior._outPrice
field to (basePrice
+ optionPriceSum
)
Double optionPriceSum
Parameter
cm.core.part.Part
for documentationbasePrice
and optionPriceSum
.Old: new BasicPartData(snapper, "PART NUM", "PART DESC", outPrice=199.99); New: new BasicPartData(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=49.99); New: new BasicPartData(snapper, "PART NUM", "PART DESC", basePrice=150, optionPriceSum=null);
The following functions and fields were added to BasicPartData
in v16.5.
These functions were added in support of the new pricing model which is documented in the compile-time section for cm.core.part.Part
.
// FIELDS New: package bool _useNewPricing; New: public double _basePrice; New: public Double _optionPriceSum; // OVERRIDDEN FUNCTIONS (from PartData) New: public bool useNewPricing() {} New: public double basePrice() {} New: public void setBasePrice(double v) {} New: public Double optionPriceSum() {} New: public void setOptionPriceSum(Double v) {}
The PartMakeSpecialDialog
constructor has been changed to accept a new parameter label
. The new parameter
allows for customization of the dialogs label but the label is still defaulted to the title "Make/Change Special".
Old: public constructor(Window parent, PartSpecial original) {} New: public constructor(Window parent, PartSpecial original, str label=$specialsDialog) {}
The helper method generateSpecial()
has been introduced to streamline the process of creating PartSpecial
objects from dialog input.
return PartSpecial(partNumTF.text, descrTF.text, priceReplaceRB.currentState > 0, amountDF.value);
The helper method generateCustomSpecial()
has been introduced to streamline the process of creating custom PartSpecial
objects from dialog input.
In 16.5, the QueryDialogDataEnv
has changed it's backing data structures, replacing the str->Part parts
and int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
Cell highlighting has also been introduced in the QueryDialog
.
As a result, the following functions have been removed and added to QueryPartGridBuilderEnv
.
Removed: public str rowIdentifier(Object data) {} Added: public GridCell[] getRowCells(Object data) {} Added: public Brush getCellBrush(Object data, int columnIdx) {}
In 16.5, The QueryDialogDataEnv
has changed it's backing data structures, replacing the str->Part parts
and
int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
Old:
Part
instances
str->Part parts
int->str rowIDs
New:
QueryRowData
)QueryRowData[] queryRows
)As a result of this change, the following functions and fields were modified in the QueryDialogDataEnv
interface.
// Modified data fields Old: public str->Part parts; Old: public int->str rowIDs; New: public QueryRowData[] queryRows; // Modified data field accessors/manipulation Old: extend public Part[] setParts(Part[] value) {} Old: extend public int->str setRowIDs(int->str value) {} Old: extend public void buildParts() {} New: extend public void buildQueryRowData(Part[] parts=null) {} // Modified to new data structure (str id -> int row) Old: extend public PartSpecial getSpecial(str id) {} New: extend public PartSpecial getSpecial(int row) {} Old: extend public void putSpecial(str id, PartSpecial special) {} New: extend public void putSpecial(int row, PartSpecial special) {} Old: extend public void removeSpecial(str id) {} New: extend public void removeSpecial(int row) {} // Added helper functions New: extend public void refreshQueryRowData() {} New: extend public QueryRowData createPartRowData(Part part) {} New: extend public bool contains(PropObj propObj) {} New: extend public bool any() {} New: extend public bool empty() {} New: extend public QueryRowData getRowData(int row) {} NOTE: Things labelled as Old were removed interface and those labeled as New were added. The Old/New labels are utilized to clearly demonstrate the migration of changes.
In 16.5, the QueryDialogDataEnv
has changed it's backing data structures, replacing the str->Part parts
and int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
As a result, the extended type QueryPartRowData
has been created to represent a core Part
query dialog row.
/** * QueryPartRowData * * This class is responsible for managing * data for a Part row in a QueryDialog. */ public class QueryPartRowData extends QueryRowData { /** * Get the Part instance associated with this row. * @return The Part object associated with this row */ extend public Part part() { ... } /** * Get the special associated with this row. * @return The PartSpecial object associated with this row */ public PartSpecial getSpecial() { ... } /** * Assign a special to this row. * @special The PartSpecial object to associate with this row */ public void putSpecial(PartSpecial special) { ... } /** * Remove the special from this row. */ public void removeSpecial() { ... } }
In 16.5, The QueryDialogDataEnv
has changed it's backing data structures,
replacing the str->Part parts
and int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
View more documentation about this change in the section for cm.core.part.query.QueryDialogDataEnv
.
The following functions in the QueryDialogBehavior
have been updated to reflect the new index-based data retrieval versus the old key/id based retrieval.
They perform the same purposes with the only notable change being in buildGridWindow
which is documented further below.
Old: extend public int->str buildGridWindow(GridWindow grid, Part[] parts) {} New: extend public void buildGridWindow(GridWindow grid, Object rows) {} Old: extend public PartSpecial getSpecial(QueryDialog dialog, str id) {} New: extend public PartSpecial getSpecial(QueryDialog dialog, int row) {} Old: extend public void putSpecial(QueryDialog dialog, str id, PartSpecial special) {} New: extend public void putSpecial(QueryDialog dialog, int row, PartSpecial special) {} Old: extend public void removeSpecial(QueryDialog dialog, str id) {} New: extend public void removeSpecial(QueryDialog dialog, int row) {} Old: extend public GridCell[] getRowCells(QueryDialog dialog, str id) {} New: extend public GridCell[] getRowCells(QueryDialog dialog, int row) {} Old: extend public GridCell getCell(QueryDialog dialog, str columnLabel, str rowID) {} New: extend public GridCell getCell(QueryDialog dialog, str columnLabel, int row) {} Old: extend public DialogWindow getSpecialDialog(QueryDialog dialog, str id) {} New: extend public DialogWindow getSpecialDialog(QueryDialog dialog, int row) {}
The buildGridWindow
function no longer takes in a Part
sequence as a parameter and no longer returns an int->str
row-index to row-id map.
It now accepts a generic Object
type for its row building. It's return type has changed to void
with the reverted need for row IDs.
Old:
Part[] parts
as a parameterint->str
map of row-indexes to row-ids for caching on QueryDialogDataEnv
New:
Object
type for a row data parameterGridBuilder
s generic populateGridWindow
function which takes in an Object
QueryDialogDataEnv
GridBuilder
and it's populateGridWindow
interface
QueryDialogBehavior
on your PropObj
The following functions have been modified, added to, or removed from QueryDialogBehavior
in v16.5.
Added: extend public QueryRowData[] getQueryRows(QueryDialog dialog) {} Added: extend public QueryRowData getRowData(QueryDialog dialog, int row) {} Added: extend public Part getPart(QueryDialog dialog, int row) {} Added: extend public void openCustomSpecialDialog(QueryDialog dialog) {} Added: extend public DialogWindow getCustomSpecialDialog(QueryDialog dialog, int row) {} Removed: extend public bool containsSpecial(QueryDialog dialog) {} Removed: extend public int getRowIndex(QueryDialog dialog, str id) {}
QueryRowData
s in the dialogs QueryDialogDataEnv
QueryRowData
representing the row at the int row
indexPart
representing the row at the int row
indexPartMakeSpecialDialog
) for generating a custom special representing the row at the selected row indexPartMakeSpecialDialog
) for generating a custom special representing the row at the selected row indexQueryDialogDataEnv
cm.core.part.query.QueryDialogDataEnv
for more info.QueryDialogDataEnv
cm.core.part.query.QueryDialogDataEnv
for more info.In 16.5, the QueryDialogDataEnv
has changed it's backing data structures, replacing the str->Part parts
and int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
As a result, the abstract class QueryRowData
has been created to represent a generic query dialog row.
/** * QueryRowData * * This abstract class is responsible for managing * data for a row in a QueryDialog. */ public class QueryRowData : abstract { /** * ID for this row data instance. */ public str id; /** * The data object associated with this row. */ public Object data : copy=reference; /** * Constructor. * @id ID for this row * @data The data object to associate with this row */ public constructor(str id, Object data) { ... } /** * Get the special associated with this row. * Override to get specific special handling logic. * @return The PartSpecial object associated with this row */ extend public PartSpecial getSpecial() : abstract { } /** * Assign a special to this row. * Override to get specific special handling logic. * @special The PartSpecial object to associate with this row */ extend public void putSpecial(PartSpecial special) : abstract { } /** * Remove the special from this row. * Override to get specific special handling logic. */ extend public void removeSpecial() : abstract { } }
In 16.5, The QueryDialogDataEnv
has changed it's backing data structures,
replacing the str->Part parts
and int->str rowIDs
maps with a single QueryRowData[] queryRows
data sequence.
View more documentation about this change in the section for cm.core.part.query.QueryDialogDataEnv
.
The following functions in the QueryDialog
have been updated, added, or removed to reflect the new index-based data retrieval versus the old key/id based retrieval.
Old: extend public str selectedRowID() {} New: extend public int selectedRow() {} Old: extend public PartSpecial getSpecial(str id) {} New: extend public PartSpecial getSpecial(int row) {} Old: extend public void putSpecial(str id, PartSpecial special) {} New: extend public void putSpecial(int row, PartSpecial special) {} Old: extend public void removeSpecial(str id) {} New: extend public void removeSpecial(int row) {} Removed: extend public str->Part parts() {} Removed: extend public int->str rowIDs() {} Added: extend public QueryRowData selectedRowData() {}
The following functions have been added and removed from QueryDialog
in v16.5.
Added: extend public bool any() {} Added: extend public bool empty() {} Added: extend public bool contains(PropObj propObj) {} Added: public bool keyCode(Window originator, KeyCode keyCode) {} Removed: extend public bool containsSpecial() {}
QueryDialog
contains any backing dataQueryDialog
has any dataany()
on the dialogs QueryDialogDataEnv env
data
contains any QueryDataRow
s; false if notQueryDialog
contains any backing dataQueryDialog
has no dataempty()
on the dialogs QueryDialogDataEnv env
data
contains any QueryDataRow
s; false if notQueryDialog
contains the passed in propObj
in it's backing datacontains(..)
on the dialogs QueryDialogDataEnv env
cm.core.part.query.QueryDialogDataEnv
for more infoQueryDialog
to intercept Ctrl+A events originating from a QueryDialog
. CoreAppWindow
and trigger a selectAll action on snapper elements, which was not desirable.GridWindow
, it returns true immediately to prevent parent handlingGridWindow
via gridWindow().?key(CTRL_A)
super(..)
The following interfaces have been consolidated, there should be no necessary changes.
Old: public void initFromPropsScheme(PropObj obj) : deprecated { New: public void initFromPropsScheme(PropObj obj, str systemKey=null, World world=null) {
We have made str systemKey
an optional argument and removed the World w=null
argument.
Old: public PropsSchemeSpecificQPInfo propsSchemeQPInfo(CoreObject obj, World w=null) { Old: public PropsSchemeSpecificQPInfo propsSchemeQPInfo(CoreObject obj, str systemKey, World w=null) { New: public PropsSchemeSpecificQPInfo propsSchemeQPInfo(CoreObject obj, str systemKey=null) {
Following the interface change introduced for BrushHoverButton
, the constructor for PropsSchemeFilterButton
has been updated.
Old: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, function(Control button) callback=null, SrcRef src=#:src) { New: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, bool showUnderline=false, // Added function(Control button) callback=null, SrcRef src=#:src) {
We have optimized props scheme dialog by eliminating unnecessary nested SubWindow
in cards
, schemeBarSub
, barsAndOptions
, and applyWins
.
The following methods have been removed as they are now unnecessary:
Removed: extend public void layoutApply(Window reference=null) {} Removed: extend public void layoutSelection() {}
Previously, these methods were used to adjust margins caused by the presence of the now-removed applyWindow
sub-window.
The following methods have been removed as redundant window resizing operations are no longer required in these methods:
Removed: public void ancestorResizeEnd() {} Removed: public void parentClientBoundChanged() {}
They will now inherit the behaviours from Card
instead.
A small addition of a default argument str loc=callerLoc()
to the constructor.
Old: public constructor(Window parent, Font font=systemFont(), Brush brush=null, str label="Dialog", bool initVisible=true, bool noBorder=false) : deprecated { New: public constructor(Window parent, Font font=systemFont(), Brush brush=null, str label="Dialog", bool initVisible=true, bool noBorder=false, str loc=callerLoc()) { // Added
The class field lastSelectedTab
has been removed and is replaced with lastSelectedTabKey
. The decision to store the last selected tab's key instead of the index position is to allow exact string matching when remembering and restoring the last selected toolbox tab, further improving consistency when loading the last selected toolbox tab.
Removed: public int lastSelectedTab; Added: public str lastSelectedTabKey;
The MessageWindow
class has been moved from cm.core.toolbox
to cm.win
.
The cm.win function endProgress
was accidentally overriden by Toolbox in 16.0, this has been removed.
Removed: final public void endProgress() {
New argument UIHint hint
has been added.
Old: public constructor(ComboTextPainter victim, str->Object styles) : deprecated { New: public constructor(ComboTextPainter victim, str->Object styles, UIHint hint) {
The method convertToBitmap
has been removed as it is no longer necessary to convert a DibImage into a MemoryImage.
Removed: extend public void convertToBitmap(DibImage dib, sizeI dim) {
In v16.5, a new constructor has been introduced for UserPart to support the new pricing model.
Previously, UserPart accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(World world, ..., double listPrice, ...)
listPrice
value to cache.cm.core.part.Part
for more infoconstructor(World world, ..., double basePrice, Double optionPriceSum, ...)
basePrice
and optionPriceSum
separately for caching.cm.core.part.Part
for more infobasePrice
and optionPriceSum
.Remove: public class PrevCatChecked {
Old: public class CategoryUndoOp { New: package class CategoryUndoOp { Old: public class AddCategoryUndoOp { New: package class AddCategoryUndoOp { Old: public class RemoveCategoryUndoOp { New: package class RemoveCategoryUndoOp {
Removed: public PrevCatChecked{} theDescendants : stream=null; Old: public symbol cat; New: private symbol cat; Old: public Snapper{} taggedSnappers : stream=null; New: private Snapper{} taggedSnappers() : stream=null; Old: public constructor(symbol cat, Snapper{} snappers, PrevCatChecked{} theDescendants = null) { New: public constructor(symbol cat, Snapper{} snappers) {
MemoryImage
to be casted to DibImage
and destroyed explicitly to reduce GDI Object usage.
Old: public MemoryImage loadOldGMaterial3DThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) { New: public DibImage loadOldGMaterial3DThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) {
Since getThumbnail(memoryStream)
return a DibImage
now, return it as a DibImage
in loadDexGMThumbnail()
.
Old: public Image loadDexGMThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) { New: public DibImage loadDexGMThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) {
Match loadOldGMaterial3DThumbnail()
and loadDexGMThumbnail()
change to return DibImage.
Old: public Image loadGMaterial3DThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) { New: public DibImage loadGMaterial3DThumbnail(Url url, gmThumbnailType thumbnailType=gmThumbnailType.flat) {
The following new fields fontWeight wght
, bool italic
, and bool underline
have been added. As such, a constructor has been updated to set these fields.
public class Text3D extends Primitive3D { Old: public constructor(str text, float height, float thickness, str fontFace, LayerExpr layer=null) { New: public constructor(str text, float height, float thickness, str fontFace, fontWeight wght=fontWeight.normal, bool italic=false, bool underline=false, LayerExpr layer=null) { }
Cleanup of constructors of Dwg entites. Remove redundant construcors and replace differences with default arguments.
Old: public constructor(point2D center, double startAngle, double endAngle, double radius, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(point2D center, double startAngle, double endAngle, double radius, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight) New: public constructor(point2D center, double startAngle, double endAngle, double radius, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight=defaultLineWeight)
Old: public constructor(point p0, point p1, point p2, bool i0, bool i1, bool i2, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype) Old: public constructor(point p0, point p1, point p2, bool i0, bool i1, bool i2, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype, double lineWeight) New: public constructor(point p0, point p1, point p2, bool i0, bool i1, bool i2, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype, double lineWeight=defaultLineWeight, COLORTYPE colorType=cLayer)
Old: public constructor(point start, point end, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(point start, point end, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight) New: public constructor(point start, point end, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight=defaultLineWeight)
Old: public constructor(point position, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(point position, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeigh) Old: public constructor(point position, DwgLayer layer, DwgLineType linetype, DwgBlock block, COLORTYPE colorType, color c, int16 colorIndex, double lineWeight) New: public constructor(point position, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, COLORTYPE colorType=cLayer, int16 colorIndex=-1, double lineWeight=defaultLineWeight)
Old: public constructor(AMultiMesh mesh, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype, bool[] visibleEdges=null) Old: public constructor(AMultiMesh mesh, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype, double lineWeight, bool[] visibleEdges=null) New: public constructor(AMultiMesh mesh, color c, DwgLayer layer, DwgBlock block, DwgLineType linetype, double lineWeight=defaultLineWeight, COLORTYPE colorType = cLayer, bool[] visibleEdges=null)
Old: public constructor(point2D[] points, bool closed, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(point2D[] points, bool closed, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight) Old: public constructor(point2D[] points, bool closed, DwgLayer layer, DwgLineType linetype, DwgBlock block, COLORTYPE colorType, color c, int16 colorIndex, double lineWeight) New: public constructor(point2D[] points, bool closed, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, COLORTYPE colorType=cLayer, int16 colorIndex=-1, double lineWeight=defaultLineWeight)
Old: public constructor(str name, str fileName, point origin, vector width, vector height, sizeI pixelSize, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(str name, str fileName, point origin, vector width, vector height, sizeI pixelSize, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight) New: public constructor(str name, str fileName, point origin, vector width, vector height, sizeI pixelSize, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight=defaultLineWeight)
Old: public constructor(point2D[] points, double thickness, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c) Old: public constructor(point2D[] points, double thickness, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, double lineWeight) New: public constructor(point2D[] points, double thickness, DwgLayer layer, DwgLineType linetype, DwgBlock block, color c, COLORTYPE colorType=cLayer, double lineWeight=defaultLineWeight)
Removed redundant loadDwg function
Removed: public DwgRoot loadDwg(Url path, DwgImportEnv importEnv=null, bool verbose=false)
# CBBClient Changed: - final public void showLoginFailNotification() + final public void showLoginFailNotification(rtoutcome reason, str errorType)
The public field color currentFontColor
has been removed and a new private field UserTextStyle _tStyle
has been added. The old currentFontColor
data is now stored inside the new field _tStyle
. New methods color currentFontColor()
and color currentFontColor=(color c)
have been added so the interface of setting currentFontColor
remains the same. By default, _tStyle
will follow the style of Dimension text
under the tools tab. However for existing 3D dimension from old drawing, user will still be seeing the previous style which always Arial
with 50mm
font height.
public class Draw3DMeasureBase extends DrawSnapper : abstract { Removed: public color currentFontColor; New: private UserTextStyle _tStyle; New: /** * Current font color (get). */ extend public color currentFontColor() { if (tStyle) return tStyle.fontColor(); return black; } New: /** * Current font color (set). */ extend public color currentFontColor=(color c) { if (tStyle) { if (!tStyle.followedStyle) { tStyle = tStyle.editedCopy().UserTextStyle; } tStyle.setFontColor(c); } return currentFontColor(); } }
This class has been removed and can be replaced with the new GetTreeViewItemsInstruction
.
Removed: class GetTreeViewItemAtIndexInstruction
This class has been removed and can be replaced with the new GetTreeViewItemsInstruction
.
Removed: class GetTreeViewItemInstruction
Changed the type of the skipSnap
constructor argument from bool
to Bool
. When assigned to null, userSnapDisable
will not be overridden and instead use its global value during insert.
Old: public constructor(Snapper snapper, line[] mouseLines, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(Snapper snapper, line[] mouseLines, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(SnapperSpawner spawner, line[] mouseLines, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(SnapperSpawner spawner, line[] mouseLines, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(Snapper snapper, point2D[] pos, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(Snapper snapper, point2D[] pos, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(SnapperSpawner spawner, point2D[] pos, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(SnapperSpawner spawner, point2D[] pos, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(Snapper snapper, line mouseLine, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(Snapper snapper, line mouseLine, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(SnapperSpawner spawner, line mouseLine, str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(SnapperSpawner spawner, line mouseLine, str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(Snapper snapper, point2D pos=point2D(), str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(Snapper snapper, point2D pos=point2D(), str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(SnapperSpawner spawner, point2D pos=point2D(), str outputKey=null, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(SnapperSpawner spawner, point2D pos=point2D(), str outputKey=null, Bool skipSnap=null, SrcRef src=#:src) { Old: public constructor(SnapperSpawner spawner, str outputKey, bool skipSnap=false, SrcRef src=#:src) { New: public constructor(SnapperSpawner spawner, str outputKey, Bool skipSnap=null, SrcRef src=#:src) {
This instruction has been renamed CreateBlockInstruction
.
Old: public class PutSnappersInBlockInstruction extends TestInstruction { New: public class CreateBlockInstruction extends TestInstruction {
This instruction now handles TriStateCheckBox
as well and has therefore been given a more general name.
Old: public class ValidateTreeViewItemIsCheckedInstruction extends ValidateInstruction { New: public class ValidateCheckboxStateInstruction extends ValidateInstruction {
Old: public constructor(str itemKey, bool expectedChecked, SrcRef src=#:src) { New: public constructor(str objectKey, bool expectedChecked, SrcRef src=#:src) {
Old: public constructor(str itemKey, extent expectedState, SrcRef src=#:src) { New: public constructor(str objectKey, extent expectedState, SrcRef src=#:src) {
This class has been removed. As a replacement, use GetFieldValueInstruction
to read the "key"-field of the tree view item, followed by ValidateValueInstruction
.
Removed: class ValidateTreeViewItemKeyInstruction
The field c
in SolidColorBrush has now been changed to public readable
to prevent alteration of existing brushes.
Old: public color c; New: package color c : public readable;
The return type of brush cache function to get a cached solid color brush is now more specific.
Old: public Brush solidColorBrush(color c, bool use=false) { New: public SolidColorBrush solidColorBrush(color c, bool use=false) { Old: public Brush solidColorBrush(int r, int g, int b) { New: public SolidColorBrush solidColorBrush(int r, int g, int b) {
Predefined solid brushes in cm/win/brush.cm
now have their types changed to SolidColorBrush.
Old: public const Brush whiteBrush = SolidColorBrush(color(255, 255, 255)); public const SolidColorBrush whiteBrush = solidColorBrush(color(255, 255, 255));
For both GradientHBrush
and GradientVBrush
, the field c2
has been changed to public readable
.
Old: public color c2; New: package color c2 : public readable;
Added a new argument faceliftScrollBars=false
in ScrollableGridWindow constructor.
The MessageWindow
class has been moved from cm.core.toolbox
to cm.win
.
Instead of passing a sizeI size
in the constructor argument, only int width
is passed instead.
Old: public constructor(Window parent, str message, Image image, str key=null, sizeI size=(0, 0), int internalMargin=7, Brush brush=ultraLightGrayBrush, FrameStyle frameStyle=lightGrayPenFrame, color textColor=black, color linkColor=primary600, color linkHoverColor=primary600, int textSize=12, str fontFace=null, function(Control button, str key):bool linkCallback=null, SrcRef src=#:src) { New: public constructor(Window parent, str message, Image image, str key=null, int width=0, int internalMargin=7, Brush brush=ultraLightGrayBrush, FrameStyle frameStyle=lightGrayPenFrame, color textColor=black, color linkColor=primary600, color linkHoverColor=primary600, int textSize=12, str fontFace=null, function(Control button, str key):bool linkCallback=null, SrcRef src=#:src) {
The constructor for BrushHoverButton
has been updated to allow an optional configuration of underlining the button's label text when a button is hovered. This should facilitate a smoother integration for button styles, or more specifically, button states that adhere to CET's design system.
Old: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, function(Control button) callback=null, SrcRef src=#:src) { New: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, bool showUnderline=false, // Added function(Control button) callback=null, SrcRef src=#:src) {
As part of the interface change introduced for BrushHoverButton
, some classes that extend from it will also be affected.
See other affected changes in:
The constructor for FaceliftSearchField
has been updated to accept an optional search icon that can be used to override the search field's icon where necessary.
Old: public constructor(Window parent, // inherited key arguments Font font=inputFieldFont, Brush brush=whiteBrush, FrameStyle frameStyle=faceliftStdFrame, frame3DState frameState=frameStateDown, pointI pos=(0, 0), sizeI size=(0, 0), pointI margins=(8, 8), function(Control button) posChangedCallback=null, function(Control button) callback=null, function(Control button) escapeKeyCallback=null, function(Control button) lostFocusCallback=null, // extended function(Control button) enterKeyCallback=null, str key=null, bool absFontH=false, str promptText=null, SrcRef src=#:src) { New: public constructor(Window parent, // inherited key arguments Font font=inputFieldFont, Brush brush=whiteBrush, FrameStyle frameStyle=faceliftStdFrame, frame3DState frameState=frameStateDown, pointI pos=(0, 0), sizeI size=(0, 0), pointI margins=(8, 8), Image searchIcon=icon("facelift2023/search"), // Added function(Control button) posChangedCallback=null, function(Control button) callback=null, function(Control button) escapeKeyCallback=null, function(Control button) lostFocusCallback=null, // extended function(Control button) enterKeyCallback=null, str key=null, bool absFontH=false, str promptText=null, SrcRef src=#:src) {
Following the interface change introduced for BrushHoverButton
, the constructor for FrameStyleHoverButton
has been updated.
Old: public constructor(Window parent, FrameStyle mouseOverFrameStyle|, // inherited key arguments Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, function(Control button) callback=null, SrcRef src=#:src) { New: public constructor(Window parent, FrameStyle mouseOverFrameStyle|, // inherited key arguments Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, bool showUnderline=false, // Added function(Control button) callback=null, SrcRef src=#:src) {
Following the interface change introduced for BrushHoverButton
, the constructor for ProgressButton
has been updated.
Old: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, function(Control button) callback=null, SrcRef src=#:src) { New: public constructor(Window parent, Brush stdBrush, Brush hoverBrush, Brush mouseDownBrush, // inherited key arguments Font font=controlFont, FrameStyle frameStyle=noFrame, frame3DState frameState=frameStateUp, pointI pos=(0, 0), sizeI size=sizeI(-1, -1), pointI margins=(6, 4), alignment align=middle, str key=null, str label="", color labelColor=color(0, 0, 0), color pressedLabelColor=color(colorType.none), alignment textSide=undefinedAlignment, Image image=null, Image disabledImage=null, color color=nocolor, bool roundedCorners=false, bool showUnderline=false, // Added function(Control button) callback=null, SrcRef src=#:src) {
A new bool facelift=false
argument is added to TreeView's constructor.
Old: public constructor(Window parent, // inherited key arguments Font font=systemFont(), Brush brush=null, FrameStyle frameStyle=stdLightFrame, frame3DState frameState=frameStateDown, pointI pos=(0, 0), sizeI size=(100, 100), pointI margins=(-1, -1), alignment align=middle, bool popup=false, bool shadow=false, function (Control control) callback=null, // extended key arguments bool alwaysMultiSelect=false, bool allowMultiSelect=false, bool directSelect=false, bool listBoxStyle=false, treeViewSelectionStyle selectionStyle=treeViewSelectionStyle.undefined, function (Control control) click2Callback=null, bool transparentScrollBars=false, bool noScrollBars=false, str key=null, SrcRef src=#:src) { New: public constructor(Window parent, // inherited key arguments Font font=systemFont(), Brush brush=null, FrameStyle frameStyle=stdLightFrame, frame3DState frameState=frameStateDown, pointI pos=(0, 0), sizeI size=(-1, -1), pointI margins=(-1, -1), alignment align=middle, bool popup=false, bool shadow=false, function (Control control) callback=null, // extended key arguments bool alwaysMultiSelect=false, bool allowMultiSelect=false, bool directSelect=false, bool listBoxStyle=false, treeViewSelectionStyle selectionStyle=treeViewSelectionStyle.undefined, function (Control control) click2Callback=null, bool transparentScrollBars=false, bool noScrollBars=false, str key=null, bool facelift=false, SrcRef src=#:src) {
The following methods have a new str languageTag
argument, you're required to specify the language to obtain suggestions or replacements from.
Old: extend public str getSuggestions() { New: extend public str getSuggestions(str languageTag) { Old: extend public str getReplacement() { New: extend public str getReplacement(str languageTag) {
We have consolidated methods drawText
and drawTextWithLineHeight
by adding int limitLineHeight=-1
to drawText.
Old: final public void drawTextWithLineHeight(str text, rectI bound, rectI clipRect, int limitLineHeight, alignment align=middle, Font font=null, color textColor=color(0, 0, 0), color bkColor=color(192, 192, 192), bool transparency=true, bool clipping=false) { Old: final public void drawText(str text, rectI bound, rectI clipRect, alignment align=middle, Font font=null, color textColor=color(0, 0, 0), color bkColor=color(192, 192, 192), bool transparency=true, bool clipping=false) { New: final public void drawText(str text, rectI bound, rectI clipRect, alignment align=middle, Font font=null, color textColor=color(0, 0, 0), color bkColor=color(192, 192, 192), bool transparency=true, bool clipping=false, int limitLineHeight=-1) { // Added
The function dibResize()
(introduced in 16.0 Minor) used to alter the passed in image and return a newly created copy of DibImage. This has now been improved to resize the DibImage in place, and no longer return a new copy of DibImage:
Old: public DibImage dibResize(DibImage im, sizeI newSize, str filter=null) { New: public void dibResize(DibImage im, sizeI newSize, str filter=null) {
To retrieve RGB pixel values from a MemoryImage, the following method has been introduced:
Old: final public RawImageData rawImageDataFixed(int targetBPP=-1) { New: final public byte[] getPixelDataRGB() {
There have been some cleanups, argument ourOnlyHope
has been replaced with debug
.
Old: final public Image get(str name, bool debug=false, bool ourOnlyHope=true) { New: final public Image get(str name, bool debug=false) { Old: final public Image getDisabled(str name, bool ourOnlyHope=true) { New: final public Image getDisabled(str name, bool debug=false) {
We have removed the MemoryPixelDevice bitmap
field in SvgImage to reduce GDI bitmap object counts. It uses a Dib instead, similar to DibImage.
Old: public MemoryPixelDevice bitmap : copy=null, stream=null; New: public Dib dib : copy=null, stream=null;
The constructors have been consolidated for this class.
Old: public constructor(str key, Image[] images, rectI bound, int durationMs=10000) { New: public constructor(str key, Image[] images, rectI bound, int durationMs=10000, bool cycle=false, bool endWithUber=false) {
The access modifiers for field centerImage
has been changed, a new setter method is introduced.
Old: public Image centerImage; New: private Image centerImage : copy=reference, public readable; New: final public bool setCenterImage(Image i) {
The following interfaces have been changed or added in GridWindow
for v16.5.
Old: extend public void insertRow(int y, str label=null, bool update=true) {} New: extend public void insertRow(int y, str label=null, bool update=true, bool updateRowIndexLabels=false) {} Old: extend public void insertRows(int y, int n) {} New: extend public void insertRows(int y, int n, bool updateRowIndexLabels=false) {} Old: extend public void removeRow(int y, bool update=true) {} New: extend public void removeRow(int y, bool update=true, bool updateRowIndexLabels=false) {} New: extend public void updateRowIndexLabels(int startRow=0) {} New: extend public int appendRow(GridCell[] rowCells, str label=null, bool update=true) {} New: extend public void insertRow(int y, GridCell[] rowCells, str label=null, bool update=true, bool updateRowIndexLabels=false) {}
The bool updateRowIndexLabels
parameter (default false) on the interfaces above was added in v16.5. It's purpose is to update row labels
when row indexes change.
Important to note that if the rows are labeled as anything other than the row index, this parameters value should be set to false. It will update the row labels from the inserted/removed index to the end of the row sequence, setting the labels to the appropriate row index.
See documentation for the updateRowIndexLabels(int startRow=0)
function for more info.
extend public void insertRow(int y, str label=null, bool update=true, bool updateRowIndexLabels=false) { extend public void insertRows(int y, int n, bool updateRowIndexLabels=false) { extend public void removeRow(int y, bool update=true, bool updateRowIndexLabels=false) { ... New: if (updateRowIndexLabels) updateRowIndexLabels(startRow=y); ... }
Updates the labels of grid rows so they display their current row index.
startRow
(default = 0, the first row).startRow
values are corrected to 0./** * Update labels of rows. * This will replace row labels with their index value. * @startRow optional row to begin label updates at; default 0 (top/first row) */ extend public void updateRowIndexLabels(int startRow=0) { if (startRow < 0) startRow = 0; while (int row = startRow; row < rowCount; row++) { setRowLabel(row, NameGridLabel((row+1).toS())); } }
Appends a new row of GridCell
s to the grid and returns its index.
rowCells
→ sequence of GridCell
s to populate the new row.label
→ optional label for the row.update
→ whether to auto-update sizing and UI after insertion.The row index of the newly added row.
Appends a new row of GridCell
s to the grid at a given index.
y
→ index of row in grid to be insertedrowCells
→ sequence of GridCell
s to populate the new row.label
→ optional label for the row.update
→ whether to auto-update sizing and UI after insertion.updateRowIndexLabels
→ optional flag to update row index labels after insertionChanged getThumbnail()
to return a DibImage
instead of a MemoryImage
to reduce GDI Object usage.
Old: extend public MemoryImage getThumbnail(Url file) { New: extend public DibImage getThumbnail(Url file) {
In v16.5, a new constructor has been introduced for SymbolPicklistPart to support the new pricing model.
Previously, SymbolPicklistPart accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(Snapper snapper, ..., double listPrice, ...)
listPrice
value to cache.cm.core.part.Part
for more infoconstructor(Snapper snapper, ..., double basePrice, Double optionPriceSum, ...)
basePrice
and optionPriceSum
separately for caching.cm.core.part.Part
for more infobasePrice
and optionPriceSum
.In v16.5, a new constructor has been introduced for GrdLengthPart to support the new pricing model.
Previously, GrdLengthPart accepted a cached list price (listPrice
) directly as a parameter. This behavior is now being phased out.
constructor(Snapper snapper, ..., double listPrice=0, ...)
listPrice
value to cache.cm.core.part.Part
for more infoconstructor(Snapper snapper, ..., double basePrice=0, Double optionPriceSum=0, ...)
basePrice
and optionPriceSum
separately for caching.cm.core.part.Part
for more infobasePrice
and optionPriceSum
.