UNPKG

6.96 kBPlain TextView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4
5/*
6* This is an extension and not part of the main GoJS library.
7* Note that the API for this class may change with any version, even point releases.
8* If you intend to use an extension in production, you should copy the code to your own source directory.
9* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
10* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
11*/
12
13import * as go from '../release/go-module.js';
14
15// A "ScrollingTable" Panel
16
17// This also defines an "AutoRepeatButton" Panel,
18// which is used by the scrollbar in the "ScrollingTable" Panel.
19
20// This defines a custom "Button" that automatically repeats its click
21// action when the user holds down the mouse.
22// The first optional argument may be a number indicating the number of milliseconds
23// to wait between calls to the click function. Default is 50.
24// The second optional argument may be a number indicating the number of milliseconds
25// to delay before starting calls to the click function. Default is 500.
26
27// Example:
28// $("AutoRepeatButton", 150, // slower than the default 50 milliseconds between calls
29// {
30// click: function(e, button) { doSomething(button.part); }
31// },
32// $(go.Shape, "Circle", { width: 8, height: 8 })
33// )
34go.GraphObject.defineBuilder('AutoRepeatButton', function(args) {
35 const repeat = go.GraphObject.takeBuilderArgument(args, 50, function(x) { return typeof x === "number"; });
36 const delay = go.GraphObject.takeBuilderArgument(args, 500, function(x) { return typeof x === "number"; });
37 const $ = go.GraphObject.make;
38 // some internal helper functions for auto-repeating
39 function delayClicking(e: go.InputEvent, obj: any) {
40 endClicking(e, obj);
41 if (obj.click) {
42 obj._timer =
43 setTimeout(function() { repeatClicking(e, obj); },
44 delay); // wait milliseconds before starting clicks
45 }
46 }
47 function repeatClicking(e: go.InputEvent, obj: any) {
48 if (obj._timer) clearTimeout(obj._timer);
49 if (obj.click) {
50 obj._timer =
51 setTimeout(function() {
52 if (obj.click) {
53 (obj.click)(e, obj);
54 repeatClicking(e, obj);
55 }
56 },
57 repeat); // milliseconds between clicks
58 }
59 }
60 function endClicking(e: go.InputEvent, obj: any) {
61 if (obj._timer) {
62 clearTimeout(obj._timer);
63 obj._timer = undefined;
64 }
65 }
66
67 return $('Button',
68 { actionDown: delayClicking, actionUp: endClicking });
69});
70
71// Create a scrolling Table Panel, whose name is given as the optional first argument.
72// If not given the name defaults to "TABLE".
73// Example use:
74// $("ScrollingTable", "TABLE",
75// new go.Binding("TABLE.itemArray", "someArrayProperty"),
76// ...)
77// Note that if you have more than one of these in a Part,
78// you'll want to make sure each one has a unique name.
79go.GraphObject.defineBuilder('ScrollingTable', function(args) {
80 const $ = go.GraphObject.make;
81 const tablename = go.GraphObject.takeBuilderArgument(args, 'TABLE');
82
83 // an internal helper function for actually performing a scrolling operation
84 function incrTableIndex(obj: go.GraphObject, i: number) {
85 const diagram = obj.diagram;
86 if (!obj.panel || !obj.panel.panel || !obj.panel.panel.panel) return;
87 const table = obj.panel.panel.panel.findObject(tablename) as go.Panel;
88 if (i === +Infinity || i === -Infinity) { // page up or down
89 const tabh = table.actualBounds.height;
90 const rowh = table.elt(table.topIndex).actualBounds.height; // assume each row has same height?
91 if (i === +Infinity) {
92 i = Math.max(1, Math.ceil(tabh / rowh) - 1);
93 } else {
94 i = -Math.max(1, Math.ceil(tabh / rowh) - 1);
95 }
96 }
97 let idx = table.topIndex + i;
98 if (idx < 0) idx = 0;
99 else if (idx >= table.rowCount - 1) idx = table.rowCount - 1;
100 if (table.topIndex !== idx) {
101 if (diagram !== null) diagram.startTransaction('scroll');
102 table.topIndex = idx;
103 const node = table.part; // may need to reroute links if the table contains any ports
104 if (node instanceof go.Node) node.invalidateConnectedLinks();
105 updateScrollBar(table);
106 if (diagram !== null) diagram.commitTransaction('scroll');
107 }
108 }
109
110 function updateScrollBar(table: go.Panel) {
111 if (table.panel === null) return;
112 const bar = table.panel.elt(1) as go.Node; // the scrollbar is a sibling of the table
113 if (!bar) return;
114 const idx = table.topIndex;
115
116 const up = bar.findObject('UP');
117 if (up) up.opacity = (idx > 0) ? 1.0 : 0.3;
118
119 const down = bar.findObject('DOWN');
120 if (down) down.opacity = (idx < table.rowCount - 1) ? 1.0 : 0.3;
121
122 const tabh = bar.actualBounds.height;
123 let rowh = table.elt(idx).actualBounds.height; // ?? assume each row has same height?
124 if (rowh === 0 && idx < table.rowCount - 2) rowh = table.elt(idx + 1).actualBounds.height;
125 const numVisibleRows = Math.max(1, Math.ceil(tabh / rowh) - 1);
126 const needed = idx > 0 || idx + numVisibleRows <= table.rowCount;
127 bar.opacity = needed ? 1.0 : 0.5;
128 }
129
130 return $(go.Panel, 'Table',
131 {
132 _updateScrollBar: updateScrollBar
133 },
134 // this actually holds the item elements
135 $(go.Panel, 'Table',
136 {
137 name: tablename,
138 column: 0,
139 stretch: go.GraphObject.Fill,
140 background: 'whitesmoke',
141 rowSizing: go.RowColumnDefinition.None,
142 defaultAlignment: go.Spot.Top
143 }),
144
145 // this is the scrollbar
146 $(go.RowColumnDefinition,
147 { column: 1, sizing: go.RowColumnDefinition.None }),
148 $(go.Panel, 'Table',
149 { column: 1, stretch: go.GraphObject.Vertical, background: '#DDDDDD' },
150 // the scroll up button
151 $('AutoRepeatButton',
152 {
153 name: 'UP',
154 row: 0,
155 alignment: go.Spot.Top,
156 'ButtonBorder.figure': 'Rectangle',
157 'ButtonBorder.fill': 'lightgray',
158 click: function(e: go.InputEvent, obj: go.GraphObject) { incrTableIndex(obj, -1); }
159 },
160 $(go.Shape, 'TriangleUp',
161 { stroke: null, desiredSize: new go.Size(6, 6) })),
162 // (someday implement a thumb here and support dragging to scroll)
163 // the scroll down button
164 $('AutoRepeatButton',
165 {
166 name: 'DOWN',
167 row: 2,
168 alignment: go.Spot.Bottom,
169 'ButtonBorder.figure': 'Rectangle',
170 'ButtonBorder.fill': 'lightgray',
171 click: function(e: go.InputEvent, obj: go.GraphObject) { incrTableIndex(obj, +1); }
172 },
173 $(go.Shape, 'TriangleDown',
174 { stroke: null, desiredSize: new go.Size(6, 6) }))
175 )
176 );
177});