UNPKG

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