tree-adapter.dhover×351all
#!/usr/bin/env dub
/+ dub.sdl:
    name "property_tree_tree_adapter"
    targetPath "build"
    dependency "sparkles:ui" path="../../../.."
    dflags "-preview=in" "-preview=dip1000"
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/
/**
 * The whole thing as an ADAPTER over the existing components:
 * `TreeData!PropNode` + `TreeViewState!string` + `activate`/`collapseOrUp` +
 * `treeText`. No new interaction machinery.
 *
 * Under test:
 *   C20. A property tree needs NOTHING new from the tree component except a
 *        rebuild: `TreeStep.rebuild` already means "the opened set changed",
 *        which for us means "re-walk the subject".
 *   C21. `state.open` keyed by the path string is the whole persistence story.
 *   C22. The one real toolkit gap: `TreeData.hasChildren` is STRUCTURAL, so a
 *        closed composite whose children were never materialised renders as a
 *        leaf and `collapseOrUp` will not close it. `activate` already reads an
 *        `expandable` capability off the node value; `treeView`/`writeTreeText`
 *        and `collapseOrUp` do not.
 *   C23. An edit ([`edit-commands.d`](./edit-commands.d)) followed by a rebuild refreshes the badges and
 *        preserves cursor and expansion — the frame model's whole promise.
 *
 * Run: `dub run --single tree-adapter.d`
 */
module 
(module) property_tree_tree_adapter

The whole thing as an ADAPTER over the existing components: TreeData!PropNode + TreeViewState!string + activate/collapseOrUp + treeText. No new interaction machinery.

Under test: C20. A property tree needs NOTHING new from the tree component except a rebuild: TreeStep.rebuild already means "the opened set changed", which for us means "re-walk the subject". C21. state.open keyed by the path string is the whole persistence story. C22. The one real toolkit gap: TreeData.hasChildren is STRUCTURAL, so a closed composite whose children were never materialised renders as a leaf and collapseOrUp will not close it. activate already reads an expandable capability off the node value; treeView/writeTreeText and collapseOrUp do not. C23. An edit (edit-commands.d) followed by a rebuild refreshes the badges and preserves cursor and expansion — the frame model's whole promise.

Run

dub run --single tree-adapter.d

property_tree_tree_adapter
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) property_tree_tree_adapter.text = std.conv.text(T...)(T args) if (T.length > 0)

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
,
(alias template) property_tree_tree_adapter.to = std.conv.to(T)

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

to
;
import
(package) std
std
.
(module) std.traits

Templates which extract information about types and symbols at compile time.

Category Templates
Symbol Name traits fullyQualifiedName mangledName moduleName packageName
Function traits isFunction arity functionAttributes hasFunctionAttributes functionLinkage FunctionTypeOf isSafe isUnsafe isFinal ParameterDefaults ParameterIdentifierTuple ParameterStorageClassTuple Parameters ReturnType SetFunctionAttributes variadicFunctionStyle
Aggregate Type traits BaseClassesTuple BaseTypeTuple classInstanceAlignment EnumMembers FieldNameTuple Fields hasAliasing hasElaborateAssign hasElaborateCopyConstructor hasElaborateDestructor hasElaborateMove hasIndirections hasMember hasStaticMember hasNested hasUnsharedAliasing InterfacesTuple isInnerClass isNested MemberFunctionsTuple RepresentationTypeTuple TemplateArgsOf TemplateOf TransitiveBaseTypeTuple
Type Conversion CommonType AllImplicitConversionTargets ImplicitConversionTargets CopyTypeQualifiers CopyConstness isAssignable isCovariantWith isImplicitlyConvertible isQualifierConvertible
Type Constructors InoutOf ConstOf SharedOf SharedInoutOf SharedConstOf SharedConstInoutOf ImmutableOf QualifierOf
Categories of types allSameType ifTestable isType isAggregateType isArray isAssociativeArray isAutodecodableString isBasicType isBoolean isBuiltinType isCopyable isDynamicArray isEqualityComparable isFloatingPoint isIntegral isNarrowString isConvertibleToString isNumeric isOrderingComparable isPointer isScalarType isSigned isSIMDVector isSomeChar isSomeString isStaticArray isUnsigned
Type behaviours isAbstractClass isAbstractFunction isCallable isDelegate isExpressions isFinalClass isFinalFunction isFunctionPointer isInstanceOf isIterable isMutable isSomeFunction isTypeTuple
General Types ForeachType KeyType Largest mostNegative OriginalType PointerTarget Signed Unconst Unshared Unqual Unsigned ValueType Promoted
Misc lvalueOf rvalueOf Select select
User-Defined Attributes hasUDA getUDAs getSymbolsByUDA

Source

std/traits.d

@copyrightCopyright The D Language Foundation 2005 - 2009.@licenseBoost License 1.0.@authorsWalter Bright, Tomasz Stachowiak (isExpressions), Andrei Alexandrescu, Shin Fujishiro, Robert Clipsham, David Nadlinger, Kenji Hara, Shoichi Kato
traits
:
(alias template) property_tree_tree_adapter.hasUDA = std.traits.hasUDA(alias symbol, alias attribute)

Determine if a symbol has a given user-defined attribute.

@seegetUDAs
hasUDA
,
(alias template) property_tree_tree_adapter.isAggregateType = std.traits.isAggregateType(T)

Detect whether type T is an aggregate type.

isAggregateType
,
(alias template) property_tree_tree_adapter.isArray = std.traits.isArray(T)

Detect whether type T is an array (static or dynamic; for associative arrays see isAssociativeArray).

isArray
,
(alias template) property_tree_tree_adapter.isSomeString = std.traits.isSomeString(T)

Detect whether T is one of the built-in string types.

The built-in string types are Char[], where Char is any of char, wchar or dchar, with or without qualifiers.

Static arrays of characters (like char[80]) are not considered built-in string types.

isSomeString
;
import
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.inspector

The inspector component (INS, docs/specs/ui/inspector.md) — an interactive tree of nodes over a subject, with a details pane for the selected node and a selection contract that lets the host highlight the selected node's extent in the subject.

The shape is the one every structure inspector shares — Chromium's Elements panel, Visual Studio's Live Visual Tree, neovim's :InspectTree — and the component is deliberately generic over it:

an adapter supplies the node model (a TreeData whose T carries the view's DbI capabilities — label, slot, badge, …) and, by presence, a details(node) capability for the details pane; the tree is the shared interactive component (sparkles.ui.components.tree_view) — cursor, disclosure, viewport, the works; the selection contract is one value: the host reads state.tree.selectedNode and asks its adapter what extent that node covers (a layout rect for a widget tree, a byte range for a syntax tree) — the component never learns what an extent is; the header carries the title and a row of host-supplied toggle actions (hover-sync on/off, anonymous nodes, …) as data, hit-testable by the ids the host minted.

inspectWidgets is the first adapter: the toolkit looking at itself. Any sparkles:ui application can mount an inspector over its own widget tree and layout — the Live-Visual-Tree capability, natively.

writeTreeText is the plain-text target: the same flattened rows as indented text with guide rails, for logging, golden tests, and terminals with no interactivity at all.

inspector
:
(alias template) property_tree_tree_adapter.treeText = sparkles.ui.components.inspector.treeText(T)(in TreeData!T data, in FlatTreeRow[] rows, in TreeGlyphs glyphs = TreeGlyphs.init, scope bool delegate(uint) @safe isOpen = null)

ditto — as one string.

treeText
;
import
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.tree_view

The interactive tree view (TRV1TRV7) — the interaction half of the tree component, completing the three-layer split whose data and view halves live in sparkles.ui.components.tree_widget:

dataTreeData, the flat arena. Owned by the adapter, rebuilt at will. interaction (TreeViewState) — the opened set, the cursor, the viewport and both scrollbars, and the live filter's editor: every piece of state a tree pane keeps between frames, as one value. viewtreeView over the viewSlice window this state selects.

Before this module the interaction layer existed three times — hue's explorer pane, hue's GUI re-implementation of the same pane, and the gallery's tree page each carried their own copy of "move through the visible rows", "left closes, then climbs", and the scrollbar-grab-owns-the-pointer pointer arms. The behaviors here are those, stated once:

The cursor moves by visible row, never by arena index — pressing down inside a closed folder cannot land on a node nobody can see. TreeViewState.clamp couples the cursor and the viewport: the cursor stays in view, and the view never shows dead space below the last row. collapseOrUp is the universal two-step Left: close an open node, else climb to its parent's row. A press on a scrollbar is a grab, never a row click, and the grab owns the pointer until release wherever the drag strays (STM9's inverse mapping, same as the viewer's). The live filter is the one line-edit machine (STM13); every edit asks the adapter to rebuild, because in broot's tree-as-search-result mode the tree is a function of the query.

What is deliberately not here: the node model and its rebuild policy (lazy children, filtering predicates, git decoration — the adapter's), and painting (a host slices with viewSlice and paints through its own canvas). Mutations that invalidate the visible rows return TreeStep`.rebuild` rather than calling anything: the adapter owns rebuilding, the state only reports that it is needed.

tree_view
:
(alias template) property_tree_tree_adapter.activate = sparkles.ui.components.tree_view.activate(Key, T, KeyOf)(ref TreeViewState!Key s, in TreeData!T data, scope KeyOf keyOf)

Enter / a second click (TRV7): a node with children toggles its disclosure (rebuild); a leaf reports activated — its meaning (open the file, pick the CST node) is the adapter's. An adapter whose expandability is not "has children" (an empty directory still toggles) supplies expandable.

activate
,
(alias template) property_tree_tree_adapter.collapseOrUp = sparkles.ui.components.tree_view.collapseOrUp(Key, T, KeyOf)(ref TreeViewState!Key s, in TreeData!T data, scope KeyOf keyOf)

The universal two-step Left (TRV3): close the selected node when it is open, else move the cursor to its parent's row. keyOf maps a node index to the adapter's disclosure key.

Returns rebuild when the opened set changed (the adapter re-flattens), handled otherwise.

collapseOrUp
,
(alias template) property_tree_tree_adapter.measureContent = sparkles.ui.components.tree_view.measureContent(Key, T)(ref TreeViewState!Key s, in TreeData!T data)

Recomputes the widest visible row in cells (contentCols) from the same node capabilities the renderer reads: per-depth guide cells (3), the marker column (3), the label, and a badge's two cells when one is present.

measureContent
,
(enum) sparkles.ui.components.tree_view.TreeStep

What an interaction did, and what the caller owes it.

TreeStep
,
(alias struct) property_tree_tree_adapter.TreeViewState = sparkles.ui.components.tree_view.TreeViewState(Key)

The tree pane's interaction state (VMD2 + the viewport): one value a host embeds, keyed by the adapter's node identity Key (a path for a filesystem tree, a node index for an in-memory one) so the opened set survives rebuilds.

sel/top index the visible rows, not the arena. rows is the cached result of the adapter's last flatten — derived data stored here so every motion and clamp can see how many rows exist without a callback.

TreeViewState
;
import
(package) sparkles
sparkles
.
(package) sparkles.ui
ui
.
(package) sparkles.ui.components
components
.
(module) sparkles.ui.components.tree_widget

The tree component (WGT12, VMD1VMD6) — the exemplar of the view-model/view split, built to the tree-view case study's three-layer design:

data (TreeData) — a flat node arena with parent/child/sibling index links. No interaction state, no decoration: an independent structural snapshot needs one explicit arena duplication. The current D slice aliases under default copy (UI-O1), and T supplies its own copy contract. interaction — an opened set (DisclosureState), a selection, a scroll offset — lives beside the data, keyed by identity, so one tree can back several independent views. view (treeView) — a pure function from both to a widget subtree; owns glyphs and slots only.

flatten — hierarchy to the visible rows — is a pure free function with no lazy loading and no filtering mixed in (the case study names mixing them as the failure mode), and it precomputes the four-state guide model (space / continue / fork / end) per depth level, so no renderer re-derives rails per frame.

tree_widget
:
(alias template) property_tree_tree_adapter.flatten = sparkles.ui.components.tree_widget.flatten(T)(in TreeData!T data, scope bool delegate(uint) @safe isOpen)

The flatten step (VMD3): hierarchy → the visible rows, honoring isOpen (closed nodes keep their subtree out). Pure and free — no lazy loading, no filtering — and the guides are computed here, once, from a per-depth "has later siblings" accumulator (broot's precomputed rails).

flatten
,
(alias struct) property_tree_tree_adapter.TreeData = sparkles.ui.components.tree_widget.TreeData(T)

The data layer (VMD1): a flat arena of T values with index links. add appends under a parent (or as a root), maintaining sibling chains; there is no remove — rebuild instead (flat storage is what makes per-keystroke rebuilding viable, per the case study's tree-as-search-result mode).

TreeData
,
(struct) sparkles.ui.components.tree_widget.TreeGlyphs

The tree's charset — theme-glyph data with unicode defaults. All guide cells are three columns wide, with one space between the connector and the row's content. An adapter whose icons already express disclosure (the explorer's open/closed folder) passes empty marker strings.

TreeGlyphs
;
@safe: enum
(enum) property_tree_tree_adapter.readOnly
readOnly
;
/// The node value, carrying exactly the capabilities the existing views read: /// `label`, `badge` — plus `expandable`, which `activate` already honours. struct
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
{
(alias) object.string = string
string
(field) string property_tree_tree_adapter.PropNode.path
path
;
(alias) object.string = string
string
(field) string property_tree_tree_adapter.PropNode.label
label
;
(alias) object.string = string
string
(field) string property_tree_tree_adapter.PropNode.badge

the presented value; empty for composites

badge
; /// the presented value; empty for composites
bool
(field) bool property_tree_tree_adapter.PropNode.expandable
expandable
;
bool
(field) bool property_tree_tree_adapter.PropNode.editable
editable
= true;
} // ── the adapter ────────────────────────────────────────────────────────────── /// NOTE (C24): the adapter does NOT store a pointer to the subject. Under /// dip1000 a struct holding `T*` into a caller's stack becomes `scope`, and /// every non-scope member call on it is then refused in `@safe` code. Taking /// `ref T` per rebuild is both safer and simpler — and it matches the frame /// model, where the subject is whatever the host has THIS frame. struct
(struct) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer)

NOTE (C24): the adapter does NOT store a pointer to the subject. Under dip1000 a struct holding T* into a caller's stack becomes scope, and every non-scope member call on it is then refused in @safe code. Taking ref T per rebuild is both safer and simpler — and it matches the frame model, where the subject is whatever the host has THIS frame.

PropTree
(T)
{
(struct) sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode)

The data layer (VMD1): a flat arena of T values with index links. add appends under a parent (or as a root), maintaining sibling chains; there is no remove — rebuild instead (flat storage is what makes per-keystroke rebuilding viable, per the case study's tree-as-search-result mode).

TreeData
!
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
;
(struct) sparkles.ui.components.tree_view.TreeViewState!string

The tree pane's interaction state (VMD2 + the viewport): one value a host embeds, keyed by the adapter's node identity Key (a path for a filesystem tree, a node index for an in-memory one) so the opened set survives rebuilds.

sel/top index the visible rows, not the arena. rows is the cached result of the adapter's last flatten — derived data stored here so every motion and clamp can see how many rows exist without a callback.

TreeViewState
!
(alias) object.string = string
string
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
;
int
(field) int property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).maxDepth
maxDepth
= 16;
void
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(ref
(alias) T = property_tree_tree_adapter.Layer
T
(parameter) property_tree_tree_adapter.Layer subject
subject
)
{
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
=
(template instance) sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode)
TreeData
!
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
.
(constant) sparkles.ui.components.tree_widget.TreeData!(PropNode) sparkles.ui.components.tree_widget.TreeData!(PropNode).init = TreeData(null, 4294967295u)
init
;
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Layer)(ref property_tree_tree_adapter.Layer v, uint parent, string prefix, int depth) pure @safe
walk
(
(parameter) property_tree_tree_adapter.Layer subject
subject
, uint.
(constant) uint uint.max = 4294967295u
max
, "", 0);
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_view.TreeViewState!string.rows

The visible rows, as the adapter last rebuilt them.

rows
=
sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_widget.flatten!(property_tree_tree_adapter.PropNode)(in sparkles.ui.components.tree_widget.TreeData!(PropNode) data, scope bool delegate(uint) @safe isOpen) @safe

The flatten step (VMD3): hierarchy → the visible rows, honoring isOpen (closed nodes keep their subtree out). Pure and free — no lazy loading, no filtering — and the guides are computed here, once, from a per-depth "has later siblings" accumulator (broot's precomputed rails).

flatten
!
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
, (uint
(parameter) uint n
n
) =>
bool property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).isOpen(uint node) const pure nothrow @nogc @safe
isOpen
(
(parameter) uint n
n
));
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
void sparkles.ui.components.tree_view.measureContent!(string, property_tree_tree_adapter.PropNode)(ref sparkles.ui.components.tree_view.TreeViewState!string s, in sparkles.ui.components.tree_widget.TreeData!(PropNode) data) pure nothrow @nogc @safe

Recomputes the widest visible row in cells (contentCols) from the same node capabilities the renderer reads: per-depth guide cells (3), the marker column (3), the label, and a badge's two cells when one is present.

measureContent
(
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
);
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
void sparkles.ui.components.tree_view.TreeViewState!string.clamp() pure nothrow @nogc @safe

Couples cursor and viewport: the cursor stays valid and in view, and the view never leaves dead space below the last row (a reveal before the pane had its real height can overshoot; the next sized clamp pulls back).

clamp
();
} bool
bool property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).isOpen(uint node) const pure nothrow @nogc @safe
isOpen
(uint
(parameter) uint node
node
) const =>
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).nodes
nodes
[
(parameter) uint node
node
].
(field) property_tree_tree_adapter.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).Node.value
value
.
(field) string property_tree_tree_adapter.PropNode.path
path
);
(alias) object.string = string
string
string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).keyOf(uint node) const pure nothrow @nogc @safe
keyOf
(uint
(parameter) uint node
node
) const =>
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).nodes
nodes
[
(parameter) uint node
node
].
(field) property_tree_tree_adapter.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).Node.value
value
.
(field) string property_tree_tree_adapter.PropNode.path
path
;
private void
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke)(ref property_tree_tree_adapter.Stroke v, uint parent, string prefix, int depth) pure @safe
walk
(U)(ref
(alias) U = property_tree_tree_adapter.Stroke
U
(parameter) property_tree_tree_adapter.Stroke v
v
, uint
(parameter) uint parent
parent
,
(alias) object.string = string
string
(parameter) string prefix
prefix
, int
(parameter) int depth
depth
)
{ static foreach (name; __traits(allMembers, U)) {{ alias
(alias field) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).M = double property_tree_tree_adapter.Stroke.width
M
= __traits(getMember, U, name);
static if (__traits(compiles, typeof(
(field) double property_tree_tree_adapter.Stroke.width
M
)) && !is(typeof(
(field) double property_tree_tree_adapter.Stroke.width
M
) == function))
{{ alias
(alias) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).F = double
F
= typeof(
(field) double property_tree_tree_adapter.Stroke.width
M
);
const
(local variable) const(string) path
path
=
(parameter) string prefix
prefix
.
(field) ulong string.length
length
?
(parameter) string prefix
prefix
~ "." ~ name :
(constant) string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).name = "width"
name
;
static if (
(template instance) std.traits.isAggregateType!double
isAggregateType
!
(alias) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).F = double
F
&& !
(template instance) isSomeString!F
isSomeString
!
(alias) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Layer).F = property_tree_tree_adapter.Stroke
F
)
{ const
(local variable) const(uint) node
node
=
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
uint sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).add(property_tree_tree_adapter.PropNode value, uint parent = 4294967295u) pure nothrow @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(
(local variable) const(string) path
path
,
(constant) string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Layer).name = "stroke"
name
, "", true,
!
(template instance) property_tree_tree_adapter.Layer.hasUDA!(stroke, property_tree_tree_adapter.readOnly)
hasUDA
!(
(field) property_tree_tree_adapter.Stroke property_tree_tree_adapter.Layer.stroke
M
,
(enum) property_tree_tree_adapter.readOnly
readOnly
)),
(parameter) uint parent
parent
);
if (
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(local variable) const(string) path
path
) &&
(parameter) int depth
depth
+ 1 <
(field) int property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).maxDepth
maxDepth
)
walk(__traits(getMember, v, name),
(local variable) const(uint) node
node
,
(local variable) const(string) path
path
,
(parameter) int depth
depth
+ 1);
} else static if (
(template instance) std.traits.isArray!double
isArray
!
(alias) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).F = double
F
&& !
(template instance) isSomeString!F
isSomeString
!
(alias) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Layer).F = string
F
)
{ auto ref
(local variable) int[] arr
arr
= __traits(getMember, v, name);
const
(local variable) const(uint) node
node
=
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
uint sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).add(property_tree_tree_adapter.PropNode value, uint parent = 4294967295u) pure nothrow @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(
(local variable) const(string) path
path
,
(constant) string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Layer).name = "dashes"
name
,
string std.conv.text!(string, ulong, string)(string __param_0, ulong __param_1, string __param_2) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
("[",
(local variable) int[] arr
arr
.
(field) ulong int[].length
length
, "]"),
(local variable) int[] arr
arr
.
(field) ulong int[].length
length
> 0,
!
(template instance) property_tree_tree_adapter.Layer.hasUDA!(dashes, property_tree_tree_adapter.readOnly)
hasUDA
!(
(field) int[] property_tree_tree_adapter.Layer.dashes
M
,
(enum) property_tree_tree_adapter.readOnly
readOnly
)),
(parameter) uint parent
parent
);
if (
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
(
(local variable) const(string) path
path
) &&
(parameter) int depth
depth
+ 1 <
(field) int property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).maxDepth
maxDepth
)
foreach (
(parameter) ulong i
i
, ref
(parameter) int e
e
;
(local variable) int[] arr
arr
)
{ const
(local variable) const(string) ep
ep
=
(local variable) const(string) path
path
~ "[" ~
(local variable) ulong i
i
.
string std.conv.to!string.to!ulong(ulong __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "]";
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
uint sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).add(property_tree_tree_adapter.PropNode value, uint parent = 4294967295u) pure nothrow @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(
(local variable) const(string) ep
ep
, "[" ~
(local variable) ulong i
i
.
string std.conv.to!string.to!ulong(ulong __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "]",
string std.conv.text!int(int __param_0) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
(
(local variable) int e
e
), false, !
(template instance) property_tree_tree_adapter.Layer.hasUDA!(dashes, property_tree_tree_adapter.readOnly)
hasUDA
!(
(field) int[] property_tree_tree_adapter.Layer.dashes
M
,
(enum) property_tree_tree_adapter.readOnly
readOnly
)),
(local variable) const(uint) node
node
);
} } else
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
uint sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).add(property_tree_tree_adapter.PropNode value, uint parent = 4294967295u) pure nothrow @safe

Appends value under parent (uint.max = a new root); returns its index.

add
(
(struct) property_tree_tree_adapter.PropNode

The node value, carrying exactly the capabilities the existing views read: label, badge — plus expandable, which activate already honours.

PropNode
(
(local variable) const(string) path
path
,
(constant) string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).walk!(property_tree_tree_adapter.Stroke).name = "width"
name
,
string std.conv.text!double(double __param_0) pure @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
(__traits(getMember, v, name)), false,
!
(template instance) property_tree_tree_adapter.Stroke.hasUDA!(width, property_tree_tree_adapter.readOnly)
hasUDA
!(
(field) double property_tree_tree_adapter.Stroke.width
M
,
(enum) property_tree_tree_adapter.readOnly
readOnly
)),
(parameter) uint parent
parent
);
}} }} } } // ── the subject ────────────────────────────────────────────────────────────── enum
(enum) property_tree_tree_adapter.Cap
Cap
{
(enum value) property_tree_tree_adapter.Cap.butt = 0
butt
,
(enum value) property_tree_tree_adapter.Cap.round = 1
round
}
struct
(struct) property_tree_tree_adapter.Stroke
Stroke
{ double
(field) double property_tree_tree_adapter.Stroke.width
width
= 1;
(enum) property_tree_tree_adapter.Cap
Cap
(field) property_tree_tree_adapter.Cap property_tree_tree_adapter.Stroke.cap
cap
; }
struct
(struct) property_tree_tree_adapter.Layer
Layer
{
(alias) object.string = string
string
(field) string property_tree_tree_adapter.Layer.name
name
= "layer";
bool
(field) bool property_tree_tree_adapter.Layer.visible
visible
= true;
(struct) property_tree_tree_adapter.Stroke
Stroke
(field) property_tree_tree_adapter.Stroke property_tree_tree_adapter.Layer.stroke
stroke
;
int[]
(field) int[] property_tree_tree_adapter.Layer.dashes
dashes
;
@
(enum) property_tree_tree_adapter.readOnly
readOnly
ulong
(field) ulong property_tree_tree_adapter.Layer.id
id
= 42;
} // ── driving a session ──────────────────────────────────────────────────────── void
void D main() @safe
main
()
{ import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) write = std.stdio.write(T...)(T args) if (!is(T[0] : File))

Writes its arguments in text format to standard output (without a trailing newline).

Params: args = the items to write to stdout

Throws: In case of an I/O error, throws an StdioException.

Example: Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main() { string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         write("Input ", count, ": ", line, "\n");
    }

} ---

write
,
(alias template) writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to $(D writef(fmt, args, '\n')).

writefln
,
(alias template) writeln = std.stdio.writeln(T...)(T args)

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Params: args = the items to write to stdout

Throws: In case of an I/O error, throws an $(LREF StdioException). Example: Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main() { string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }

} ---

writeln
;
(struct) property_tree_tree_adapter.Layer
Layer
(local variable) property_tree_tree_adapter.Layer l
l
;
(local variable) property_tree_tree_adapter.Layer l
l
.
(field) int[] property_tree_tree_adapter.Layer.dashes
dashes
= [4, 2];
(struct) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer)

NOTE (C24): the adapter does NOT store a pointer to the subject. Under dip1000 a struct holding T* into a caller's stack becomes scope, and every non-scope member call on it is then refused in @safe code. Taking ref T per rebuild is both safer and simpler — and it matches the frame model, where the subject is whatever the host has THIS frame.

PropTree
!
(struct) property_tree_tree_adapter.Layer
Layer
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
;
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) int sparkles.ui.components.tree_view.TreeViewState!string.width

Pane geometry: outer size, and rows of pane chrome outside the tree (header + status/details; a chromeless pane sets 0). Prefer resize over assigning height: a pane that GREW must not scroll its content up to stay flush with the bottom.

width
= 40;
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) int sparkles.ui.components.tree_view.TreeViewState!string.height

Pane geometry: outer size, and rows of pane chrome outside the tree (header + status/details; a chromeless pane sets 0). Prefer resize over assigning height: a pane that GREW must not scroll its content up to stay flush with the bottom.

height
= 14;
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(
(local variable) property_tree_tree_adapter.Layer l
l
);
void
void property_tree_tree_adapter.main.show(string what) @safe
show
(
(alias) object.string = string
string
(parameter) string what
what
)
{
void std.stdio.writefln!(char, string, long, ulong)(in char[] fmt, string __param_1, long __param_2, ulong __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("\n── %s (cursor=%s, rows=%s) ─────────",
(parameter) string what
what
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) long sparkles.ui.components.tree_view.TreeViewState!string.sel

Cursor row and first visible row (indices into rows).

sel
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_view.TreeViewState!string.rows

The visible rows, as the adapter last rebuilt them.

rows
.
(field) ulong sparkles.ui.components.tree_widget.FlatTreeRow[].length
length
);
void std.stdio.write!string(string __param_0) @safe

Writes its arguments in text format to standard output (without a trailing newline).

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         write("Input ", count, ": ", line, "\n");
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
write
(
string sparkles.ui.components.inspector.treeText!(property_tree_tree_adapter.PropNode)(in sparkles.ui.components.tree_widget.TreeData!(PropNode) data, in sparkles.ui.components.tree_widget.FlatTreeRow[] rows, in sparkles.ui.components.tree_widget.TreeGlyphs glyphs = TreeGlyphs("\xe2\x94\x9c\xe2\x94\x80 ", "\xe2\x94\x94\xe2\x94\x80 ", "\xe2\x94\x82 ", " ", "\xe2\x96\xb8 ", "\xe2\x96\xbe ", ""), scope bool delegate(uint) @safe isOpen = cast(bool delegate(uint) @safe)null) @safe

ditto — as one string.

treeText
(
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_view.TreeViewState!string.rows

The visible rows, as the adapter last rebuilt them.

rows
));
}
void property_tree_tree_adapter.main.show(string what) @safe
show
("closed");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC20/C22 — Enter on `stroke`: `activate` reads `expandable` from");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" the node value, so a not-yet-materialised composite");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" still toggles. It returns rebuild; the adapter obeys.");
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
void sparkles.ui.components.tree_view.TreeViewState!string.moveSel(long dy) pure nothrow @nogc @safe

Moves the cursor by dy visible rows (±1 step, ±bodyRows page), keeping it in view.

moveSel
(2); // → stroke
auto
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
=
sparkles.ui.components.tree_view.TreeStep sparkles.ui.components.tree_view.activate!(string, property_tree_tree_adapter.PropNode, string delegate(uint) pure nothrow @nogc @safe)(ref sparkles.ui.components.tree_view.TreeViewState!string s, in sparkles.ui.components.tree_widget.TreeData!(PropNode) data, scope string delegate(uint) pure nothrow @nogc @safe keyOf) pure nothrow @safe

Enter / a second click (TRV7): a node with children toggles its disclosure (rebuild); a leaf reports activated — its meaning (open the file, pick the CST node) is the adapter's. An adapter whose expandability is not "has children" (an empty directory still toggles) supplies expandable.

activate
(
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
, (uint
(parameter) uint n
n
) =>
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).keyOf(uint node) const pure nothrow @nogc @safe
keyOf
(
(parameter) uint n
n
));
void std.stdio.writefln!(char, sparkles.ui.components.tree_view.TreeStep, string)(in char[] fmt, sparkles.ui.components.tree_view.TreeStep __param_1, string __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" activate → %s key = %s",
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).keyOf(uint node) const pure nothrow @nogc @safe
keyOf
(
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
uint sparkles.ui.components.tree_view.TreeViewState!string.selectedNode() const pure nothrow @nogc @safe

The selected row's node, or uint.max when there is none.

selectedNode
));
if (
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
==
(enum) sparkles.ui.components.tree_view.TreeStep

What an interaction did, and what the caller owes it.

TreeStep
.
(enum value) sparkles.ui.components.tree_view.TreeStep.rebuild = 2

consumed; the opened set or filter changed — rebuild rows

rebuild
)
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(
(local variable) property_tree_tree_adapter.Layer l
l
);
void property_tree_tree_adapter.main.show(string what) @safe
show
("stroke open");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC22 — the gap: Left on the SAME node. `collapseOrUp` asks");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" `data.hasChildren`, which is structural, so it closes only");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" because the children happen to be materialised now:");
const
(local variable) const(bool) before
before
=
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
("stroke");
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
=
sparkles.ui.components.tree_view.TreeStep sparkles.ui.components.tree_view.collapseOrUp!(string, property_tree_tree_adapter.PropNode, string delegate(uint) pure nothrow @nogc @safe)(ref sparkles.ui.components.tree_view.TreeViewState!string s, in sparkles.ui.components.tree_widget.TreeData!(PropNode) data, scope string delegate(uint) pure nothrow @nogc @safe keyOf) pure nothrow @safe

The universal two-step Left (TRV3): close the selected node when it is open, else move the cursor to its parent's row. keyOf maps a node index to the adapter's disclosure key.

Returns rebuild when the opened set changed (the adapter re-flattens), handled otherwise.

collapseOrUp
(
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
, (uint
(parameter) uint n
n
) =>
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).keyOf(uint node) const pure nothrow @nogc @safe
keyOf
(
(parameter) uint n
n
));
void std.stdio.writefln!(char, sparkles.ui.components.tree_view.TreeStep, const(bool), bool)(in char[] fmt, sparkles.ui.components.tree_view.TreeStep __param_1, const(bool) __param_2, bool __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" collapseOrUp → %s stroke open: %s → %s",
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
,
(local variable) const(bool) before
before
,
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
bool sparkles.ui.state.DisclosureState!string.isOpen(in string k) const pure nothrow @nogc @safe

true iff k is open under the current polarity + exceptions.

isOpen
("stroke"));
if (
(local variable) sparkles.ui.components.tree_view.TreeStep step
step
==
(enum) sparkles.ui.components.tree_view.TreeStep

What an interaction did, and what the caller owes it.

TreeStep
.
(enum value) sparkles.ui.components.tree_view.TreeStep.rebuild = 2

consumed; the opened set or filter changed — rebuild rows

rebuild
)
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(
(local variable) property_tree_tree_adapter.Layer l
l
);
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" With the node CLOSED, its children are gone, so a second");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" Left cannot distinguish `stroke` from a leaf — it climbs to");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" the parent instead. `collapseOrUp` needs the same");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" `expandable` capability `activate` already has.");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("\nC21/C23 — open two nodes, move the cursor, then EDIT:");
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
=
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.opened(string k) const pure nothrow @safe

This state with k forced open / closed.

opened
("stroke").
sparkles.ui.state.DisclosureState!string sparkles.ui.state.DisclosureState!string.opened(string k) const pure nothrow @safe

This state with k forced open / closed.

opened
("dashes");
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(
(local variable) property_tree_tree_adapter.Layer l
l
);
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) long sparkles.ui.components.tree_view.TreeViewState!string.sel

Cursor row and first visible row (indices into rows).

sel
= 4;
void property_tree_tree_adapter.main.show(string what) @safe
show
("two open, cursor on stroke.cap");
(local variable) property_tree_tree_adapter.Layer l
l
.
(field) property_tree_tree_adapter.Stroke property_tree_tree_adapter.Layer.stroke
stroke
.
(field) double property_tree_tree_adapter.Stroke.width
width
= 3.5; // an edit lands ([`edit-commands.d`](./edit-commands.d))
(local variable) property_tree_tree_adapter.Layer l
l
.
(field) int[] property_tree_tree_adapter.Layer.dashes
dashes
= [8, 4, 1]; // and a structural one
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
void property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).rebuild(ref property_tree_tree_adapter.Layer subject) @safe
rebuild
(
(local variable) property_tree_tree_adapter.Layer l
l
);
void property_tree_tree_adapter.main.show(string what) @safe
show
("after the edit — badges refreshed, expansion and cursor kept");
void std.stdio.writefln!(char, string[])(in char[] fmt, string[] __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("\n opened set survived as data: %s",
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.state.DisclosureState!string sparkles.ui.components.tree_view.TreeViewState!string.open

User intent (VMD5): which nodes should be open, keyed by identity.

open
.
(field) string[] sparkles.ui.state.DisclosureState!string.exceptions

Sorted, unique keys that differ from the default.

exceptions
);
void std.stdio.writefln!(char, bool)(in char[] fmt, bool __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" read-only field is marked: id.editable = %s",
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode) property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).data
data
.
(field) sparkles.ui.components.tree_widget.TreeData!(PropNode).Node[] sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).nodes
nodes
[
(local variable) property_tree_tree_adapter.PropTree!(Layer) t
t
.
(field) sparkles.ui.components.tree_view.TreeViewState!string property_tree_tree_adapter.PropTree!(property_tree_tree_adapter.Layer).state
state
.
(field) sparkles.ui.components.tree_widget.FlatTreeRow[] sparkles.ui.components.tree_view.TreeViewState!string.rows

The visible rows, as the adapter last rebuilt them.

rows
[$ - 1].
(field) uint sparkles.ui.components.tree_widget.FlatTreeRow.node
node
].
(field) property_tree_tree_adapter.PropNode sparkles.ui.components.tree_widget.TreeData!(property_tree_tree_adapter.PropNode).Node.value
value
.
(field) bool property_tree_tree_adapter.PropNode.editable
editable
);
}