Analytics

Overview

In 15.0, we introduced new event capture systems that will drive Analytics features available for manufacturers in the near future.

For more information on this topic, please refer to implementation article on Analytics available here: https://support.configura.com/hc/en-us/articles/22335281700503-Analytics

cm.win

Added interfaces for windows to provide auxiliary information during event logging.
Added interfaces for logging window events. (e.g. window show, window hide)

//window.cm
Added: extend public str statsEntityKey()
Added: extend public void auxiliaryStatsEntities(G3StatsEntity[] entities, str action)

//windowEventLog.cm
Added: public void logFrameWindowShowEvent(Window w)
Added: public void logFrameWindowHideEvent(Window w)
Added: public void logWindowEvent(str action, Window w)

cm.core

Added interfaces for snappers to provide auxiliary information during event logging.
Added interfaces for logging snapper events. (e.g. snapper select)

//snapper.cm
Added: extend public str statsEntityKey()
Added: extend public void auxiliaryStatsEntities(G3StatsEntity[] entities, str action)

//eventLogFunctions.cm
Added: public void logSnapperSelectEvent(Snapper snapper)
Added: public void logSnapperEvent(str action, Snapper snapper)
Added: public void logUserSelectTbCardEvent(ToolboxCard toolboxCard)
Added: public str tbCardStatsEntityKey(symbol pkg, str fnName)

Edited 26 April 2024
Interfaces regarding snapper insert events have been removed. Refer to full implementation article for more information: https://support.configura.com/hc/en-us/articles/22335281700503-Analytics

cm.abstract.dataSymbol.toolbox

Addition of DsCatalogToolboxData class to hold catalog information of the toolbox.

//dsCatalogToolboxData.cm
Added: public class DsCatalogToolboxData
Added: package DsCatalogToolboxData createDsCatalogToolboxData(DataCatalog catalog, ProductCatalog productCatalog, int index)

//toolboxes.cm
Old: public constructor(Url url, Url previewUrl, str groupId) 
New: public constructor(Url url, Url previewUrl, str groupId, DsCatalogToolboxData cData)

Old: private void activateCatalogToolboxCard(Url url, Url previewUrl, str groupId)
New: private void activateCatalogToolboxCard(Url url, Url previewUrl, str groupId, DsCatalogToolboxData cData)

Facelift

Custom Title Bars

FrameWindow now supports the use of custom title bars, which allows the use of custom buttons.

cm.core.library

The component tab libraries have been extended with more organisational features! For more information look at https://dev-docs.configura.com/design-system/component-tab-libraries

cm.win

Double buffering is now supported for Window on a opt-in basis. If you notice your Window flickering, experiment with calling setDoubleBuffered(hwnd, true) on your window.

In order for double buffer to work properly, you'll need to invalidate your window and repaint it during WM_PAINT.

Old: repaint();
New: invalidate(hwnd);

Old: refresh();
New: refreshG2();
New: refreshChildrenRecursiveG2(); // Old refresh used to repaint children.

Old: eraseBackground(); repaint();
New: invalidate(hwnd, eraseBackground=true);
New: refreshG2();

If your windows need immediate repainting after invalidating a window, you can do the following:

invalidate(hwnd);
updateWindow(hwnd);

cm.abstract.dataSymbol

Added:

Helper functions were added for gathering different fields on DsPart. A helper function was added to get a SpecOption from a DsPDataOption on a DsPart. A function for exporting PartOptionAdjustments was also added to DsPart.

// class DsPart

extend public Url previewImageUrl()
extend public double area()
extend public double length()
extend public double depth()
extend public double height()
extend public double width()

extend public SpecOption getSpecOption(DsPDataOption dataOpt)
extend public void xmlOptionAdjustments(DsiPDataOption opt, str prefix, XmlStreamBuf buf)

Added:

A function to gather CustomerOwnMaterials for a DsPData and a function to return the CustomerOwnMaterial for a DsiPDataOption were added.

// dsPData.cm 
extend public void getCOMs(CustomerOwnMaterial{} coms)
extend public CustomerOwnMaterial getCOM(DsiPDataOption dsOption)

Added:

A function to gather CustomerOwnMaterials for a DsMultiPData was added.

// dsMultiPData.cm 
extend public CustomerOwnMaterial{} getCOMs()

cm.abstract.dataSymbol.optionColumn

Added:

A new column for a Part's manufacturer (enterprise) code has been added. It is adjustable by default.

// dsManufacturerCodeColumn.cm 

// Class Signature
public class DsManufacturerCodeColumn extends BasicPartColumn : inherit constructors

Added:

A new adjustable column for textile length on a Part's option has been added. It is adjustable by default. It is designed to be apart of PartInfoTrees, next to a SpecOption. An option adjustment system has been added in Part to support option adjustments from Calculation columns.

// dsTextileLengthColumn.cm 

// Class Signature
public class DsTextileLengthPartColumn extends BasicPartInfoTreeColumn

Added:

A field for a SpecOption on DsOptionInfoTree has been added. A constructor that accepts a SpecOption as a parameter was also added to DsOptionInfoTree.

// optionColumn.cm 
// class DsOptionInfoTree
public SpecOption specOpt;

public constructor(PartInfoTree parent, str key, str description, str groupDescription,
		       str price, Part owner, DsPDataOption option, SpecOption specOpt, str header="",
		       bool choosableInCalculation=true)

cm.abstract.material

A new FlattenedCOMPartData class has been added. It's purpose is to flatten data specific to COMParts like textile length and list price.

Class Signature:
public class FlattenedCOMPartData extends FlattenedPartData

Extendable Interfaces:

// flattenedCOMPartData.cm

extend public void appendSimilar(COMPart part)
extend public double flattenedLength()
extend public str flattenedParentPartNumbers()
extend public double flattenedListPrice()

Added:

  • private alias comPartsHook = function (Part part);

    • new hooks for processing generated child COMParts
    • these hooks are called during postFinalizeHooks to process and change/edit values on a COMPart child
  • public void registerCOMPartsHook(comPartsHook hook)

  • public void unregisterCOMPartsHook(comPartsHook hook)

    • functions for registering and unregistering a comPartsHook

Added fields:

public Display requiredLbl; public Display codeLbl; public Display descLbl; public Display partNumLbl; public FormattedTextField partNumTF; public Display supplierLbl; public FormattedTextField suppTF; public Display mfrLbl; public FormattedTextField mfrTF; public Display ppUnitLbl; public DoubleField ppUnitDF; public Display unitLbl; public DistUnitEnumDDTV unitDDM; public Display apprvLbl; public FormattedTextField apprvTF; public Display shipLbl; public FormattedTextArea shipTA; public Display linkLbl; public FormattedTextField linkTF; public Display transD; public Display scaleD; public DoubleField scaleField; public Button browseBtn; public Button colorBtn; public Button gMatBtn; public Button okBtn; public Button cancelBtn;

Added functions:

  • Getters/Setters for new UI controls to link data entry to MaterialPartProxy
  • public void update()
    • updates dialog UI controls
  • public void alignChildren()
    • aligns child controls
  • public void applyAndClose()
    • applies changes from child controls and closes dialog
  • public bool validateEntries(StrBuf errors)
    • validates that the user has entered code and description information for the COM material
  • public MaterialPartProxy getProxy()
    • returns MaterialPartProxy for the COM under the #parts context

A new type of Part has been added for CustomerOwnMaterials. It utilizes a COMPartProxy provided by the CustomerOwnMaterial for it's part information.

Class Signature:
public class COMPart extends ProdPart

Extendable Interfaces:

// comPart.cm

extend public str uniqueCOMPartKey()
extend public CustomerOwnMaterial material()
extend public str materialCode()
extend public double pricePerUnit()
extend public str shippingInfo()
extend public str approvalNumber()
extend public str lengthUnit()
extend public double flattenedLength()
extend public double adjustedLength(Space space=null)
extend public void setAdjustedLength(double v, Space space=null)
extend public str parentPartNumbers()
extend public Object getValue(str key)
extend private void generateSpecOptions()
extend public distanceUnit keyToDistanceUnit(str key)
extend public str lengthStr()

A new column for textile length input has been added for COMParts. It registers user adjustments to length as SinglePartAdjustments on a COMPart.

Class Signature:
public class COMPartTextileLengthColumn extends BasicPartColumn

Added Function:

  • public MaterialProxy matProxy(symbol context)
    • returns a COMPartProxy for the CustomerOwnMaterial
    • COMPartProxy is an object that holds the part information for a CustomerOwnMaterial
    • the parameter symbol context can be used to receive a different proxy under different contexts

cm.abstract.materialHandling

New topApproach property

Added new topApproach primitives that are generated at the top of the bay. Also added a new prop to allow propagating width changes to frames as well.

Engine Runtime Visualiser

A new tool to identify and look up the state and values of entries at each function run is created to provide a better understanding of the role of each function.

The tool can be found under the Debug Engine section:

Engine visualiser toolbox

To use the tool, open the engine visualiser. Then, perform any function like stretching a bay while the visualiser dialog is opened. The dialog will then show most of the functions ran and the entries in that function. Details of each entries such as its state and bound are shown. The visualiser will also show the details of each entry before and after the engine run. By looking at which entry the function modified or did not modify, we can identify the purpose of each function.

The visualiser also draws the bounds of the entries and highlights entries that are new or modified by the function:

Engine visualiser graphics

In the screenshot above, it tell us that the function bayUpdateFrames modified those frame entries.

An important point to consider:
The visualiser does not show all engine function runs. Sometimes an engine function run does not have a snapper and so the visualiser is unable to identify any entries, so that function run will be omitted. To see all engine runs it is better to use the engine tracker instead.

Shapes and behaviors can now append invalidations

Added new methods to appendInvalidations() to MhSnapper. Appends invalidations from MhSnapperShape and MhBehavior.

MhSnapperShape

Added : extend public void appendInvalidations(MhSnapper owner, InvalidList list) { }
MhBehavior

Added : extend public void appendInvalidations(MhSnapper owner, InvalidList list) { }

Data classes

New classes and functions have been added to cm.abstract.materialHandling.data to support data snappers in a similar manner to how the Material Handling essential extensions have been set up.

public class MhDataCatalogAccess extends MhCatalogAccess : abstract {

public class MhDataSnapper extends MhSnapper {

public class MhDataSnapperShape extends MhSnapperShape {

public class MhPData extends DsPData : replacing load {

public class MhPDataFeaturePropDef extends PropDef {

public class MhPDataFkPropDef extends PropDef {

New shelving template

The Templates functionality in the Selective Rack Demo extension has been updated. You can now generate a Shelving extension with this feature.

Generate shelving template

Select shelving

Just like the Selective Racking template, this simply generates an extension with minimal code to get started customizing a Shelving extension.

New behavior to allow for easier control of bay editor MaterialOverride2D and MaterialOverride3D of frames

Added a new MhBayEditorFrameGfxBehavior that allows for easy overriding of the material override of the frames in the bay editor. There is also a new method to initialize the LineType and fillType of the ElevContentSnapperG2 of frames in the bay editor.

cm.abstract.materialHandling.storage.shelving

New level spawner

A new spawner MhShelvingLevelSpawner has been added to Abstract Shelving. It is used to spawn snappers with the MhShelfShape shape class and contains logic to add collision primitives only during construction, used to simulate clearance without requiring actual geometry objects to contain them.

New bay editor items

Added new classes for shelving bay editors that contain logic which should be commonly used for shelving products.

public class MhShelvingBaySizeEditorItem extends MhBaySizeEditorItem {

public class MhShelvingBayLevelEditorItem extends MhBayLevelEditorItem {

New shelving configuration class

Added new class MhShelvingConfiguration which contains some default logic for shelving configurations. holeZDomain() has been overridden here to work without expecting floor levels.

public class MhShelvingConfiguration extends MhStorageRowConfiguration {

cm.abstract.part

A new generic column for a SpecOption description in a PartInfoTree has been added. It can be utilized to display a SpecOption's description in a SpecOptionInfoTree.

Class Signature:
public class SpecOptionDescInfoTreeColumn extends BasicPartInfoTreeColumn

A new generic PartInfoTree for SpecOptions has been added. It can be utilized to display a SpecOption's code and description in a PartInfoTree. It's constructor also allows for passing in the columns to be utilized for the tree, rather than needing to override the class.

Class Signature:
public class SpecOptionInfoTree extends PartInfoTree

Constructors

// generic constructor for Part and SpecOption
public constructor(Part owner, SpecOption specOpt) {

// constructors to specify columns to include in PartInfoTree
public constructor(Part owner, SpecOption specOpt, rest: PartColumn[] columns) {
public constructor(Part owner, SpecOption specOpt, PartColumn[] columns) {

A new generic column for a SpecOption code in a PartInfoTree has been added. It can be utilized to display a SpecOption's code in a SpecOptionInfoTree.

Class Signature:
public class SpecOptionInfoTreeColumn extends BasicPartInfoTreeColumn

A new class for PartOptionAdjustments. It can be utilized to store adjustments to SpecOptions on a Part.

Class Signature:
public class PartOptionAdjustment extends SinglePartAdjustment

Product SIF will now export "yardage" as an additional field in the Option. Product SIF will now export "currency symbol" as an additional field in the Product.

cm.basic

Added yards to distanceUnit

Add a new variant yards to the distanceUnit enum, and added various constants and a function for working with it.

New constants:

  • meterPerYard
  • yardsPerMeter
  • squareMeterPerYard
  • cubicMeterPerYard

New function: public double yards(double v, unitMagnitude magnitude=unitMagnitude.dist)

cm.core

cm.core

Added:

A Url field for the target file has been added.

// orderExporter.cm
public Url target;

cm.core.block

A new popup warning dialog has been added when a user tries to explode a block that has quantity adjustments. The user gets the option to continue or abort the explosion. Helpers were added to check for these quantity adjustments and show the popup dialog if any are found.

// blockFuns.cm
public bool containsQuantityAdjustment(Block block)
public bool askUserRemoveQuantityAdjustment()

A new popup warning dialog has been added when a user tries to change a property via the calculation dialog, that affects block snappers in multiple alternatives. The user gets the option to continue or abort the change. There is also a "Don't ask again"-checkbox, to stop the dialog from popping up in the future.

A new hook has been added to Post-Finalize hooks to propagate any BlockSpace quantity adjustments to the Spaces above it.

// blockHooks.cm
public Part[] propagateBlockSpaceQuantities(Part[] parts, Space space)

cm.core.calc

Added:

A PartInfoTree field was added to CalcDoubleInputCell and CalcGridCellPopup to allow for PartInfoTree related adjustments. Helper functions were also added to CalcDoubleInputCell to get the actual value and search value for the column field.

// calcDoubleInputCell.cm
public PartInfoTree infoTree;

extend public double columnActualValue(PartCache cache, Space space)
extend public str columnSearchValue(PartCache cache, Space space)

Added:

An interface to get the background brush for a PartInfoTree grid cell has been added.

// brushes.cm
public Brush calcAutoBgBrush(GridCell cell, GridWindow gw, PartInfoTree infoTree, BasicPartInfoTreeColumn column, Space space);

// class CalculationColorScheme
extend public Brush autoBrush(GridCell cell, GridWindow gw, Space space, PartInfoTree infoTree, BasicPartInfoTreeColumn column=null)

cm.core.init

Added:

A new column for a Part's generic code (TAG2) has been added. It is adjustable by default.

// corePartColumns.cm 

// Class Signature
public class GenericCodeColumn extends BasicPartColumn

cm.core.itemTag

Added:

A default category for ItemTags has been added. The categories() function now includes this default category.

// itemTag.cm
public const symbol defaultItemTagCategory = #generalText;

// class ItemTag
extend public symbol{} categories() {
	symbol{} categories = {defaultItemTagCategory};
	...
}

Added:

A default category for ItemTags has been added. The layer() function in ItemTagInfo now includes this default category.

// itemTagInfo.cm
Old: 
extend public LayerExpr layer() {
	return null;
}

New: 
extend public LayerExpr layer() {
	return {defaultItemTagCategory};
}

cm.core.material

A str->Object map has been added to Material to store miscellaneous data. Interfaces to add to, remove from, and access the misc map were also added. It's current use is for storing part information about a Material.

An interface for getting a Material's MaterialPartProxy was also added to Material. The proxy returned is based off of the symbol context passed into the matProxy function.

// material.cm

public str->Object misc;

final public void addMiscData(str key, Object value)
final public bool removeMiscData(str key)
final public Object getMiscData(str key)

extend public MaterialProxy matProxy(symbol context)

A MaterialPartProxy class has been added. This proxy serves as a connection between a Material and any miscellaneous data that the Material might have.

Class Signature:
public class MaterialPartProxy extends MaterialProxy : abstract

Extendable Interfaces:

// materialPartProxy.cm

extend public void addMiscData(str key, Object value) : abstract
extend public bool removeMiscData(str key) : abstract
extend public Object getMiscData(str key) : abstract

// Part Information
extend public str partNumber()
extend public str partNumber=(str v)
extend public str description()
extend public str description=(str v)

// Material Information
extend public str supplier()
extend public str supplier=(str v)
extend public str materialMfg()
extend public str materialMfg=(str v)
extend public str lengthUnit()
extend public str lengthUnit=(str v)
extend public str approvalNumber()
extend public str approvalNumber=(str v)
extend public double pricePerUnit()
extend public double pricePerUnit=(double v)

// Catalog Options
extend public str catalogCode()
extend public str catalogCode=(str v)

// Selection
extend public str materialCode()
extend public str materialCode=(str v)
extend public str colorCode()
extend public str colorCode=(str v)
extend public str colorDescription()
extend public str colorDescription=(str v)
extend public str shippingInfo()
extend public str shippingInfo=(str v)
extend public bool tryAppendPart(Part parent)

A MaterialProxy class has been added. This proxy serves as a way of storing any miscellaneous data that a Material might have.

Class Signature:
public class MaterialProxy : abstract

Extendable Interfaces:

// materialProxy.cm

extend public Object ref() : abstract
extend public void apply(MaterialProxy from) : abstract

A MaterialPartProxy for CachedMaterials has been added. This proxy serves as a connection between a CachedMaterial and any part information or miscellaneous data that the CachedMaterial might have.

More info about MaterialPartProxy can be found in MaterialPartProxy migration docs.

Class Signature:

public class CachedMaterialPartProxy extends MaterialPartProxy

Extendable Interfaces:

// cachedMaterialPartProxy.cm

extend public GMaterial3D gMaterial3D()

cm.core.part

Added:

Interfaces were added to partAdjustment.cm replicating adjustedValueIfAny and adjustProperty to get an adjusted value or to adjust a property on a Part using an adjustment key.

// partAdjustment.cm
public Object adjustedValueIfAny(str adjustmentKey, str propKey, Space space, bool ignoreBlockSpace=true)
public void adjustProperty(str adjustmentKey, str key, Object value, Space space, bool createIfNull=true, bool ignoreBlockSpace=true)

class Part.cm

Added:

// checks if Part should allow adjustments to description in Calculations dialog
extend public bool allowDescriptionAdjustment()

// checks if Part should allow adjustments to item tag in Calculations dialog
extend public bool acceptItemTagAdjustments()

// gets comment for Part for Calculations dialog
final public str comment(Space space)

// gets tag value for Part for Calculations dialog given a category
final public str tagCalcValue(str category)

// used to propagate Part's quantity adjustments from BlockSpaces to main Space
extend public void propagateQuantity(double partQty, double newQty, Space partSpace, Space currentSpace)

// checks if Part has original quantity adjustment
extend public bool hasOriginalQtyAdjustment()

// gets total quantity adjustment from BlockSpaces that Part is in
extend public GlobalPartAdjustment getBlockSpaceQtyAdj(Space space=null)

A BasicPartColumn type was added to exclusively handle PartInfoTrees. This is meant to be used for PartInfoTrees that need to utilize an adjustable column.

// basicPartInfoTree.cm

extend public Object value(PartInfoTree tree, Space space)
extend public Object validateValue(PartInfoTree tree, Space space, Object v)
extend public Object defaultAdjustmentValue(PartInfoTree tree, Space space)
extend public bool adjustable(PartInfoTree infoTree, Space space)
extend public bool isAdjusted(PartInfoTree tree, Space space)
extend public void adjust(PartInfoTree tree, Space space, Object v)
extend public void resetAdjustment(PartInfoTree tree, Space space)
extend public str output(PartInfoTree tree, Space space)
extend public str searchKey(PartInfoTree tree, Space space)

cm.format.pmx

A new OrderExporter for PMX database files has been added to Calculations. It is registered with CET Commercial Interiors.

Class Signature:
public class PmxOrderExporter extends OrderExporter

Extendable Interfaces:

// pmxOrderExporter.cm

extend public void initialize(World world, Url drawing=null)
extend private bool askUserAboutOverwrite()
extend package UrlField appendUrlField(Window parent, str label)

cm.import.interop

Added Unsigned Integer Support to NetObj

Added methods for improved handling of unsigned integers, enhancing .NET interoperability:

Added: extend public nat getUInt(str name, Object[] args)
Added: extend public word getUShort(str name, Object[] args)
Added: extend public nat64 getULong(str name, Object[] args)
Added: extend public nat callUInt(str name, Object[] args)
Added: extend public word callUShort(str name, Object[] args)
Added: extend public nat64 callULong(str name, Object[] args)

Additionally, we've updated the addCallParameters(str name, Object[] args) method on NetObj to support these new unsigned integer types.

cm.util

The LinkedListQueue is a newly introduced data structure in the CM language, designed for efficient queue operations.

Due to this being a type-generating syntax, you must declare the type before using it.

Example:

public LinkedListQueue<str> StrQueue;

Where str is the element type and StrQueue is a friendly alias to use.

Public Interface:

Where T is the declared element type.

Constructors

public constructor();
public constructor(T first);
public constructor(T[] seq);
public constructor(rest: T[] args);

Inquery

public int count();
public bool any();
public bool empty();
public void clear();

Enqueue

public void enqueue(T v);
public void enqueue(T[] args);
public void enqueue(rest: T[] args);
public LinkedListQueue<T> operator<<(T v);

Dequeue / Peek

public T dequeue();
public T peek();

Misc

public bool contains(T v);
public void sort(f(T a, T b, Object env)->int comparer, Object env=null);

Conversions

public T[] seq();
public T{} set();

Example

// declare the type.
public LinkedListQueue<int> IntQueue;

private void test() {
    IntQueue queue();

    // Insert 10 as the first item, then 5 as the following item.
    queue << 10 << 5;

    // Alternate means of enqueueing an element.
    queue.enqueue(12);

    while (queue.any()) {
        // dequeue removes the front item and returns it, assigning it to v in this case.
        int v = queue.dequeue();
        pln(v); // 10 then 5 then 12
    }
}