@gorilla-engine-sdk/ge-preset-browser 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,64 @@
1
+ **IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE DOWNLOADING, INSTALLING OR USING THE GORILLA ENGINE SDK:**
2
+
3
+ - BY SIGNING THIS AGREEMENT, OR CLICKING ON THE “ACCEPT” BUTTON BELOW (IF AVAILABLE), OR BY DOWNLOADING, INSTALLING, OR USING THE GORILLA ENGINE SDK, YOU AGREE TO THE TERMS OF THIS AGREEMENT, AND ALL INCORPORATED TERMS INCLUDING GORILLA ENGINE’S PRIVACY POLICY, AS APPLICABLE, WHICH WILL BIND YOU.
4
+
5
+ - IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, WE WILL NOT LICENSE THE GORILLA ENGINE SDK TO YOU AND YOU MUST DISCONTINUE THE INSTALLATION OR DOWNLOAD PROCESS OR CEASE USE OF THE UJAM GORILLA ENGINE SDK.
6
+
7
+ **GORILLA ENGINE FREE TIER LICENSE**
8
+
9
+ This Gorilla Engine Free Tier License ("Agreement") is entered between UJAM, Inc., a Delaware corporation (hereinafter "UJAM" or "we") and you (“Licensee” or “you”) and becomes effective once you download, install, or use the GORILLA ENGINE SDK.
10
+
11
+ 1. OBJECT OF AGREEMENT. This Agreement governs UJAM’s GORILLA ENGINE SDK (“SDK”) and all related software and documentation and any update, upgrades or bug fixes (collectively referred to as the "UJAM GORILLA ENGINE SDK SERVICE").
12
+
13
+ 2. GRANT OF LICENSE: Subject to your full compliance with all of the terms and conditions of this Agreement, we grant you a non-exclusive, revocable, nonsublicensable (except as specifically provided herein), non-transferable license to use the UJAM GORILLA ENGINE SDK SERVICE solely to: (i) download, install, and use the UJAM GORILLA ENGINE SDK SERVICE for the sole purpose of building audio plugins such as virtual instruments and effects ("Application") and using such Application for music productions and live performances. **HOWEVER, YOU MUST NOT SHARE OR OTHERWISE EXPLOIT YOUR GORILLA ENGINE BASED APPLICATION WITH ANY THIRD PARTY UNTIL YOU HAVE ACQUIRED ONE OF THE ADD-ON LICENSES AS FURTHER DESCRIBED IN SECTION 8 OF THIS AGREEMENT.** If you have any questions regarding this license and allowed uses of the SDK, please reach out to us via email at support@gorilla-engine.com.
14
+
15
+ 3. LICENSE RESTRICTIONS AND OBLIGATIONS: Except as expressly and unambiguously authorized under this Agreement, you must not
16
+ 1. copy, rent, lease, sell, transfer, assign, sublicense, disassemble, reverse engineer or decompile (except to the limited extent expressly authorized by applicable statutory law), modify, create derivative works from, or alter any part of the UJAM GORILLA ENGINE SDK SERVICE;
17
+ 2. sublicense your Application to end-users until you have acquired a license as further described in Section 8 of this Agreement.
18
+ 3. use any automated means, including, without limitation, agents, robots, scripts or spiders, to access the UJAM GORILLA ENGINE SDK SERVICE or bypass the UJAM GORILLA ENGINE SDK SERVICE or to interfere or attempt to interfere with the proper working of the UJAM GORILLA ENGINE SDK SERVICE;
19
+ 4. use the UJAM GORILLA ENGINE SDK SERVICE as a dynamic-link library (for clarity: the SDK shall solely be used as a statically linked library); (g) use the SDK or any part of the SDK in connection with building or distributing your own or a third-party SDK or framework; or (h) use the Licensed Software to train artificial intelligence, your own or a third-party algorithm, and/or any other kind of machine learning processes.
20
+ 5. use the UJAM GORILLA ENGINE SDK SERVICE for the benefit of a third party, other than end users of your Applications as expressly authorized by this Agreement;
21
+ 6. use the UJAM GORILLA ENGINE SDK SERVICE to implement or enhance a product or service that is competitive with the UJAM GORILLA ENGINE SDK SERVICE;
22
+ 7. modify and/or rename the UJAM binary libraries; or
23
+ 8. otherwise engage in activity that interrupts the proper working of the UJAM GORILLA ENGINE SDK SERVICE or is otherwise fraudulent or illegal.
24
+
25
+ Furthermore, you agree
26
+
27
+ 9. display attribution on all embodiments and uses of the Gorilla Engine SDK by displaying the language “powered by Gorilla Engine” ; and
28
+ 10. to contact UJAM once you intend to Distribute (as defined in Section 8\) your Application to obtain the appropriate license to do so – which you agree is required for such a scenario (as further described in Section 8 below).
29
+
30
+ We reserve the right to discontinue, modify, cease support of, and alter the pricing structure of this Agreement (the Gorilla Engine Free Tier License) of the UJAM GORILLA ENGINE SDK SERVICE.
31
+
32
+ 10. LICENSE TO UJAM: You hereby grant to us the non-exclusive, perpetual, worldwide, royalty-free right and license to any and all content ("Content") provided by you or your end users in connection with your use or your end users' use of the SDK, including but not limited to feedback or other contributions made towards the UJAM GORILLA ENGINE SDK SERVICE (including so-called re-usable components, made available by UJAM via its repositories), in order for us to provide and improve the UJAM GORILLA ENGINE SDK SERVICE. You represent and warrant that all Content provided by you shall not violate any third party rights and shall be free of any and all claims.
33
+
34
+ 11. REPRESENTATIONS AND WARRANTIES: You represent and warrant that you: (i) are fully authorized to enter into this agreement; (ii) shall use the UJAM GORILLA ENGINE SDK SERVICE in compliance with all applicable local, state, national and foreign laws, treaties and regulations, including those related to data privacy, international communications, export laws and the transmission of technical or personal data laws; (iii) shall not (and shall not permit any third party, including a permitted sublicensee to), directly or indirectly, take any action or upload, download, post, submit or otherwise distribute or facilitate distribution of Content or any material on or through the UJAM GORILLA ENGINE SDK SERVICE, that: (a) infringes any patent, trademark, trade secret, copyright, right of publicity/privacy or other right of any third party or induces infringement thereof; (b) breaches any third party contract or obligation; (c) is unlawful, threatening, abusive, harassing, defamatory, deceptive, fraudulent, invasive of another's privacy, tortious, obscene, offensive, or profane.
35
+
36
+ 12. OWNERSHIP AND PROPRIETARY RIGHTS: As between UJAM and Licensee (and any permitted sublicensees), the SDK and all intellectual property rights in and to the UJAM GORILLA ENGINE SDK SERVICE, are and shall at all times remain the sole and exclusive property of UJAM and are protected by applicable intellectual property laws and treaties. You shall not obscure, remove or otherwise alter our copyright or trademark notices or other proprietary rights' notices affixed to or within the SDK or elsewhere.
37
+
38
+ 13. SUPPORT AND UPGRADES: This Agreement does not entitle you to any support for the SDK, unless you enter into a separate agreement with us in writing, either signed by both parties or agreed upon via click-through agreement. Any such support provided by us shall be subject to the terms and disclaimers of this Agreement.
39
+
40
+ 14. ADD-ON LICENSES FOR A PERMITTED DISTRIBUTION OF GORILLA ENGINE BASED APPLICATION:
41
+ 1. **Add-On Licenses (Upgrade to Pro Tier):** You agree to contact UJAM to obtain one of our commercial license (including the so-called “Pro Tier” License, including available optional Add-On upgrades which can be ) (collectively referred to as “Add-On Licenses”), whichever deemed to be appropriate for your intended use of the SDK, to Distribute (as defined below in subsection ii.) your Gorilla Engine based Application to end-users. Such Add-On License shall supersede this Agreement, as agreed to by the parties.
42
+ 2. **Failure to comply with Section 8:** If you fail to comply with Section 8(i) by Distributing the SDK as part of an Application beyond the allowed use under this Agreement, you shall immediately contact UJAM and pay to UJAM a royalty per each Distribution (as defined below) in an amount as solely determined by UJAM. A Distribution refers to either an embedded, pre-bundled, pre-installed platform application or software application that is downloaded, delivered, or served to a user or device by any means of distribution including directly from you or through any platform, including cloud based platforms. In avoidance of doubt, any subscription or rental shall be considered a Distribution.
43
+ 3. **Audit Rights**: Should (i) you fail to obtain an Add-On License and distribute the SDK as part of an Application, or should (ii) UJAM believe that you distribute the Application without having obtained an Add-On License, then UJAM shall have the right, upon reasonable notice, to audit/inspect any premises, computer(s), and networks on or in which the SDK is installed or used to monitor compliance with the terms of this Agreement, including but not limited to confirming the number of Distributions of the Application. If an audit reveals any unauthorized use, in addition to all other remedies available to UJAM, you shall be responsible to UJAM for all reasonable expenses related to the audit.
44
+ 4. **Third Party Libraries:** You acknowledge that certain third-party libraries may be used in connection with the SDK, subject to their respective license agreements as further disclosed by UJAM. It is your sole responsibility to abide to such third-party terms, which may include your obligations, amongst others, to provide certain disclosures accompanying your Gorilla Engine based Software..
45
+
46
+ 15. DATA PROTECTION AND PRIVACY: We may collect and process information about you and your use of the Gorilla Engine SDK, some of which may amount to personal data, subject to Gorilla Engine’s Privacy Policy.
47
+
48
+ 16. TRADE SECRETS AND CONFIDENTIAL INFORMATION: You acknowledges that the SDK contains valuable trade secrets of UJAM and, should you access any such trade secrets in violation of this Agreement, you agree to maintain the confidentiality of the trade secrets of the SDK using at least the same degree of care that you use with your own confidential information.
49
+
50
+ 17. WARRANTY DISCLAIMER: THE UJAM GORILLA ENGINE SDK SERVICE, INCLUDING THE SDK, IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, WE DISCLAIM ALL WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, REGARDING THE UJAM GORILLA ENGINE SDK SERVICE, INCLUDING WITHOUT LIMITATION ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY, ACCURACY, RESULTS OF USE, RELIABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AVAILABILITY, PERFORMANCE, BANDWIDTH, AND NON-INFRINGEMENT OF THIRD-PARTY RIGHTS. FURTHER, WE DISCLAIM ANY WARRANTY THAT LICENSEE'S USE OF THE UJAM GORILLA ENGINE SDK SERVICE WILL BE AVAILABLE, UNINTERRUPTED OR ERROR FREE.
51
+
52
+ 18. LIABILITY LIMITATION: REGARDLESS OF WHETHER ANY REMEDY SET FORTH HEREIN FAILS OF ITS ESSENTIAL PURPOSE OR OTHERWISE, AND EXCEPT FOR BODILY INJURY, IN NO EVENT WILL WE OR OUR CONTRACTORS, EMPLOYEES OR AFFILIATES BE LIABLE TO YOU OR TO ANY THIRD PARTY UNDER ANY TORT, CONTRACT, NEGLIGENCE, STRICT LIABILITY OR OTHER LEGAL OR EQUITABLE THEORY FOR ANY LOST PROFITS, LOST OR CORRUPTED DATA, COMPUTER FAILURE OR MALFUNCTION, INFRINGEMENT, INTERRUPTION OF BUSINESS, OR OTHER SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND ARISING OUT OF THE USE OR INABILITY TO USE THE UJAM GORILLA ENGINE SDK SERVICE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES AND WHETHER OR NOT SUCH LOSS OR DAMAGES ARE FORESEEABLE. IN NO EVENT SHALL OUR TOTAL LIABILITY TO YOU OR ANY THIRD PARTY EXCEED TEN USD DOLLARS. ANY CLAIM ARISING OUT OF OR RELATING TO THIS AGREEMENT MUST BE BROUGHT WITHIN ONE (1) YEAR AFTER THE OCCURRENCE OF THE EVENT GIVING RISE TO SUCH CLAIM.
53
+
54
+ 19. INDEMNITY: You agree that we shall have no liability whatsoever for your or your end users of the UJAM GORILLA ENGINE SDK SERVICE. You shall indemnify, defend and hold us harmless from any and all claims, damages, liabilities, costs, and fees (including reasonable attorneys' fees) arising from your or your end users' use of the UJAM GORILLA ENGINE SDK SERVICE or for any breach of this Agreement, including any breach of the representations and warranties you made herein.
55
+
56
+ 20. TERM AND TERMINATION: This Agreement shall continue until terminated as set forth in this Section. Either party may terminate this Agreement at any time, for any reason, or for no reason including, but not limited to, if you violate any provision of this Agreement. We reserve the right to cancel, amend, or modify the SDK at any time. Any termination of this Agreement shall also terminate the license granted hereunder. Upon termination of this Agreement for any reason, you shall immediately destroy and remove from all computers, hard drives, networks, and other storage media all copies of the SDK, and shall so certify to us that such actions have occurred (including all cached ephemeral copies). Sections 5 (“REPRESENTATIONS AND WARRANTIES”), 6 (“OWNERSHIP AND PROPRIETARY RIGHTS”), 10 (“TRADE SECRETS AND CONFIDENTIAL INFORMATION”), 11 (“WARRANTY DISCLAIMER”), 12 (“LIABILITY LIMITATION”), 13 (“INDEMNITY”), 16 (“GOVERNING LAW”), 18 (“GENERAL PROVISIONS”) shall survive termination of this Agreement.
57
+
58
+ 21. EXPORT CONTROLS: You shall comply with all applicable export laws and restrictions and regulations and you shall not export, or allow the export or re-export of the SDK in violation of any such restrictions, laws, or regulations.
59
+
60
+ 22. GOVERNING LAW: This Agreement shall be governed by New York law, excluding conflict of law provisions. The parties agree to and submit to the exclusive jurisdiction of courts located in New York City, New York. The application of the United Nations Convention of Contracts for the International Sale of Goods is expressly excluded.
61
+
62
+ 23. PREVAILING PARTY. Notwithstanding Section 12 (“LIABILITY LIMITATION”), in the event of any court action relating to enforcement of this Agreement, including injunctive relief, the non-prevailing party shall reimburse the prevailing party for all reasonable attorneys’ fees and costs, including expert witness fees, resulting therefrom.
63
+
64
+ 24. GENERAL PROVISIONS. If any part of this Agreement is found void or unenforceable, it will not affect the validity of the balance of the Agreement, which shall remain valid and enforceable according to its terms. This Agreement may only be modified by written agreement between the Parties. Updates to the UJAM GORILLA ENGINE SDK SERVICE may be licensed to you by UJAM with additional or different terms. UJAM further reserves rights, in its discretion, not to license updates. This is the entire Agreement between UJAM and you relating to the UJAM GORILLA ENGINE SDK SERVICE and it supersedes any prior representations, discussions, undertakings, communications, or advertising relating to the UJAM GORILLA ENGINE SDK SERVICE. This Agreement is not assignable by you.
package/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # @gorilla-engine-sdk/ge-preset-browser
2
+
3
+ Drop-in preset browser UI for Gorilla Engine React audio plugins.
4
+
5
+ Provides a ready-to-use `PresetBrowser` component with:
6
+
7
+ - A combo-box listing all loaded presets
8
+ - Previous / next navigation buttons
9
+ - Save, Save As, and Delete buttons for user presets
10
+ - A built-in save-as modal with optional category enforcement
11
+ - Tooltip hints on disabled buttons (e.g. factory presets cannot be saved/deleted)
12
+
13
+ This package is a pure UI layer on top of
14
+ `@gorilla-engine-sdk/ge-session-presets-lib`, which handles all preset state
15
+ and file-system operations.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @gorilla-engine-sdk/ge-preset-browser
21
+ ```
22
+
23
+ **Peer Dependencies:**
24
+
25
+ - `@gorilla-engine-sdk/gorilla-engine-react` ^1.x
26
+ - `@gorilla-engine-sdk/ge-dialogs-lib` ^0.x
27
+ - `@gorilla-engine-sdk/ge-session-presets-lib` ^0.x
28
+
29
+ ## Quick Start
30
+
31
+ The full stack combines [`@gorilla-engine-sdk/ge-blob-manager`](../ge-blob-manager) for blob
32
+ loading, `@gorilla-engine-sdk/ge-session-presets-lib` for state management, this package for
33
+ the preset browser UI, and [`@gorilla-engine-sdk/ge-labeled-components`](../ge-labeled-components)
34
+ for the main plugin controls.
35
+
36
+ ```tsx
37
+ import path from 'path';
38
+ import { useState } from 'react';
39
+ import { BlobManager } from '@gorilla-engine-sdk/ge-blob-manager';
40
+ import { LabeledKnob, LabeledSlider } from '@gorilla-engine-sdk/ge-labeled-components';
41
+ import {
42
+ SessionAndPresetsConfig,
43
+ SessionAndPresetsStateProvider,
44
+ SessionAndPresetsWrapper,
45
+ defaultSessionAndPresetsConfig,
46
+ } from '@gorilla-engine-sdk/ge-session-presets-lib';
47
+ import { PresetBrowser } from '@gorilla-engine-sdk/ge-preset-browser';
48
+
49
+ const config: SessionAndPresetsConfig = {
50
+ ...defaultSessionAndPresetsConfig,
51
+ factoryPresetPath: path.join(GorillaEngine.getResourcePath(), 'Presets'),
52
+ userPresetPath: path.join(GorillaEngine.getUserDataPath(), 'Presets'),
53
+ flagPresetChanged: true,
54
+ roundtripPresets: true,
55
+ };
56
+
57
+ // --- Root: rendered by Gorilla Engine ---
58
+ export function Root() {
59
+ const [instrument, setInstrument] = useState<GorillaEngine.Instrument | null>(null);
60
+
61
+ if (!instrument) {
62
+ return (
63
+ <geLabel width={800} height={600}>
64
+ <BlobManager
65
+ pluginName="MyPlugin"
66
+ manufacturerName="MyCompany"
67
+ blobName="MyPlugin"
68
+ onInstrumentLoaded={(inst) => setInstrument(inst)}
69
+ onErrorLoadingInstrument={(err) => console.error('Blob load error:', err)}
70
+ />
71
+ </geLabel>
72
+ );
73
+ }
74
+
75
+ return (
76
+ <SessionAndPresetsStateProvider config={config} instrument={instrument}>
77
+ <SessionAndPresetsWrapper>
78
+ <geLabel width={800} height={600}>
79
+ {/* Preset browser sits at the top of the UI */}
80
+ <PresetBrowser
81
+ browserStyle={{
82
+ container: { x: 10, y: 10, width: 400, height: 65 },
83
+ comboBox: { x: 0, y: 0, width: 290, height: 30 },
84
+ prevButton: { x: 295, y: 0, width: 30, height: 30, text: '◀' },
85
+ nextButton: { x: 330, y: 0, width: 30, height: 30, text: '▶' },
86
+ deleteButton: { x: 0, y: 35, width: 95, height: 25, text: 'Delete' },
87
+ saveButton: { x: 100, y: 35, width: 95, height: 25, text: 'Save' },
88
+ saveAsButton: { x: 200, y: 35, width: 95, height: 25, text: 'Save As' },
89
+ }}
90
+ config={{ askBeforeDelete: true, enforceCategories: true }}
91
+ />
92
+
93
+ {/* Main synthesis controls using ge-labeled-components */}
94
+ <LabeledKnob
95
+ x={60}
96
+ y={120}
97
+ width={80}
98
+ height={100}
99
+ parameterPath="/macro/cutoff"
100
+ label="Cutoff"
101
+ />
102
+ <LabeledKnob
103
+ x={180}
104
+ y={120}
105
+ width={80}
106
+ height={100}
107
+ parameterPath="/macro/resonance"
108
+ label="Reso"
109
+ />
110
+ <LabeledKnob
111
+ x={300}
112
+ y={120}
113
+ width={80}
114
+ height={100}
115
+ parameterPath="/macro/attack"
116
+ label="Attack"
117
+ />
118
+ <LabeledKnob
119
+ x={420}
120
+ y={120}
121
+ width={80}
122
+ height={100}
123
+ parameterPath="/macro/release"
124
+ label="Release"
125
+ />
126
+ <LabeledSlider
127
+ x={600}
128
+ y={100}
129
+ width={40}
130
+ height={120}
131
+ parameterPath="/macro/volume"
132
+ label="Volume"
133
+ />
134
+ </geLabel>
135
+ </SessionAndPresetsWrapper>
136
+ </SessionAndPresetsStateProvider>
137
+ );
138
+ }
139
+ ```
140
+
141
+ ## Components
142
+
143
+ ### `PresetBrowser`
144
+
145
+ The main component. Renders all preset controls in a single `geLabel` container.
146
+
147
+ **Props:**
148
+
149
+ | Prop | Type | Description |
150
+ | ---------------- | ------------------------------ | ------------------------------------------------------------------------------ |
151
+ | `browserStyle` | `PresetBrowserStyle?` | Visual style for all sub-elements — defaults to `defaultPresetBrowserStyle` |
152
+ | `saveModalStyle` | `PresetBrowserSaveModalStyle?` | Style for the save-as modal — defaults to `defaultPresetBrowserSaveModalStyle` |
153
+ | `config` | `PresetBrowserConfig?` | Behaviour options — defaults to `defaultPresetBrowserConfig` |
154
+
155
+ ### `SavePresetWithCategoriesModal`
156
+
157
+ The built-in save-as modal. Used internally by `PresetBrowser` but can also be
158
+ used standalone if you need to embed it in a custom layout.
159
+
160
+ ## Configuration
161
+
162
+ ### `PresetBrowserConfig`
163
+
164
+ | Field | Type | Default | Description |
165
+ | --------------------- | ---------------------- | ------- | ----------------------------------------------------------- |
166
+ | `askBeforeDelete` | `boolean` | `true` | Show a confirmation dialog before deleting a preset |
167
+ | `enforceCategories` | `boolean` | `true` | Show a category picker in the save modal |
168
+ | `presetSaveModalHook` | `PresetSaveModalHook?` | — | Supply a custom save modal hook to replace the built-in one |
169
+
170
+ ```ts
171
+ const defaultPresetBrowserConfig: PresetBrowserConfig = {
172
+ askBeforeDelete: true,
173
+ enforceCategories: true,
174
+ };
175
+ ```
176
+
177
+ ## Styling
178
+
179
+ Both `PresetBrowserStyle` and `PresetBrowserSaveModalStyle` accept `Partial<…Props>` for each element, spread directly onto the native Gorilla Engine component.
180
+
181
+ ```ts
182
+ const myBrowserStyle: PresetBrowserStyle = {
183
+ container: { x: 10, y: 5, width: 320, height: 65 },
184
+ comboBox: { x: 0, y: 0, width: 215, height: 30, backgroundColor: '1a1a1a' },
185
+ prevButton: { x: 220, y: 0, width: 30, height: 30, text: '◀' },
186
+ nextButton: { x: 255, y: 0, width: 30, height: 30, text: '▶' },
187
+ deleteButton: { x: 0, y: 35, width: 85, height: 25, text: 'Delete' },
188
+ saveButton: { x: 90, y: 35, width: 85, height: 25, text: 'Save' },
189
+ saveAsButton: { x: 180, y: 35, width: 85, height: 25, text: 'Save As' },
190
+ };
191
+
192
+ const mySaveModalStyle: PresetBrowserSaveModalStyle = {
193
+ fileNameLabel: { text: 'Preset name:', textAlign: 'left' },
194
+ fileNameInput: {},
195
+ categoryLabel: { text: 'Category:', textAlign: 'left' },
196
+ categoryComboBox: {},
197
+ };
198
+ ```
199
+
200
+ Pass them to the component:
201
+
202
+ ```tsx
203
+ <PresetBrowser
204
+ browserStyle={myBrowserStyle}
205
+ saveModalStyle={mySaveModalStyle}
206
+ config={{ askBeforeDelete: false, enforceCategories: false }}
207
+ />
208
+ ```
209
+
210
+ ## Custom Save Modal
211
+
212
+ Replace the built-in save modal by implementing `PresetSaveModalHook` and
213
+ passing it via `config.presetSaveModalHook`:
214
+
215
+ ```ts
216
+ import { usePresetSaveModal, PresetSaveModalHook } from '@gorilla-engine-sdk/ge-preset-browser';
217
+
218
+ // Use the built-in hook with custom style:
219
+ const saveModalHook = usePresetSaveModal({
220
+ enforceCategories: false,
221
+ modalStyle: mySaveModalStyle,
222
+ });
223
+
224
+ <PresetBrowser
225
+ config={{
226
+ askBeforeDelete: true,
227
+ enforceCategories: false,
228
+ presetSaveModalHook: saveModalHook,
229
+ }}
230
+ />
231
+ ```
232
+
233
+ ## License
234
+
235
+ [GORILLA ENGINE FREE TIER LICENSE](./LICENSE.md)
@@ -0,0 +1,29 @@
1
+ import { PresetSaveModalHook } from './hooks/PresetSaveModalHook';
2
+ /**
3
+ * Configuration for the {@link PresetBrowser} component.
4
+ *
5
+ * Pass this as the `config` prop to override default behaviour.
6
+ * Defaults are available via {@link defaultPresetBrowserConfig}.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * <PresetBrowser
11
+ * config={{
12
+ * askBeforeDelete: true,
13
+ * enforceCategories: false,
14
+ * }}
15
+ * />
16
+ * ```
17
+ */
18
+ export type PresetBrowserConfig = {
19
+ /**
20
+ * Provide a custom save-modal hook to replace the built-in
21
+ * {@link SavePresetWithCategoriesModal}. Useful when you need a
22
+ * fully custom save UI.
23
+ */
24
+ presetSaveModalHook?: PresetSaveModalHook;
25
+ /** When `true`, shows a confirmation dialog before deleting a preset */
26
+ askBeforeDelete: boolean;
27
+ /** When `true`, displays a category picker in the save modal and requires the user to choose a category */
28
+ enforceCategories: boolean;
29
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJlc2V0QnJvd3NlckNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9QcmVzZXRCcm93c2VyQ29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,56 @@
1
+ import { GEButtonProps, GELabelProps } from '@gorilla-engine-sdk/gorilla-engine-react';
2
+ import { GEComboBoxProps } from '@gorilla-engine-sdk/gorilla-engine-react/dist/nativeWrappers/GEComboBox';
3
+ import { GETextBoxProps } from '@gorilla-engine-sdk/gorilla-engine-react/dist/nativeWrappers/GETextBox';
4
+ /**
5
+ * Style configuration for the {@link PresetBrowser} component.
6
+ *
7
+ * Each field is a `Partial<…Props>` spread directly onto the corresponding
8
+ * native Gorilla Engine element, so any supported prop (position, size,
9
+ * colour, font, etc.) can be overridden. Defaults are available via
10
+ * {@link defaultPresetBrowserStyle}.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const myStyle: PresetBrowserStyle = {
15
+ * container: { x: 10, y: 5, width: 320, height: 110 },
16
+ * comboBox: { width: 210, height: 30, backgroundColor: '222222' },
17
+ * prevButton: { width: 30, height: 30, text: '◀' },
18
+ * nextButton: { width: 30, height: 30, text: '▶' },
19
+ * deleteButton: { width: 80, height: 25, text: 'Delete' },
20
+ * saveButton: { width: 80, height: 25, text: 'Save' },
21
+ * saveAsButton: { width: 80, height: 25, text: 'Save As' },
22
+ * };
23
+ * ```
24
+ */
25
+ export type PresetBrowserStyle = {
26
+ /** Container label that wraps the entire preset browser */
27
+ container: Partial<GELabelProps>;
28
+ /** Combo-box that lists and selects the current preset */
29
+ comboBox: Partial<GEComboBoxProps>;
30
+ /** Button that navigates to the previous preset */
31
+ nextButton: Partial<GEButtonProps>;
32
+ /** Button that navigates to the next preset */
33
+ prevButton: Partial<GEButtonProps>;
34
+ /** Button that deletes the currently loaded user preset */
35
+ deleteButton: Partial<GEButtonProps>;
36
+ /** Button that overwrites the currently loaded user preset */
37
+ saveButton: Partial<GEButtonProps>;
38
+ /** Button that opens the save-as modal to create a new user preset */
39
+ saveAsButton: Partial<GEButtonProps>;
40
+ };
41
+ /**
42
+ * Style configuration for the save-preset modal shown by
43
+ * {@link SavePresetWithCategoriesModal}.
44
+ *
45
+ * Defaults are available via {@link defaultPresetBrowserSaveModalStyle}.
46
+ */
47
+ export type PresetBrowserSaveModalStyle = {
48
+ /** Label displayed above the preset name input */
49
+ fileNameLabel?: Partial<GELabelProps>;
50
+ /** Text box where the user types the new preset name */
51
+ fileNameInput?: Partial<GETextBoxProps>;
52
+ /** Label displayed above the category selector (only when `enforceCategories` is `true`) */
53
+ categoryLabel?: Partial<GELabelProps>;
54
+ /** Combo-box for selecting a category (only when `enforceCategories` is `true`) */
55
+ categoryComboBox?: Partial<GEComboBoxProps>;
56
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJlc2V0QnJvd3NlclN0eWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1ByZXNldEJyb3dzZXJTdHlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,2 @@
1
+ import { PresetBrowserConfig } from './PresetBrowserConfig';
2
+ export declare const defaultPresetBrowserConfig: PresetBrowserConfig;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultPresetBrowserConfig = void 0;
4
+ exports.defaultPresetBrowserConfig = {
5
+ askBeforeDelete: true,
6
+ enforceCategories: true,
7
+ };
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdFByZXNldEJyb3dzZXJDb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZGVmYXVsdFByZXNldEJyb3dzZXJDb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRWEsUUFBQSwwQkFBMEIsR0FBd0I7SUFDN0QsZUFBZSxFQUFFLElBQUk7SUFDckIsaUJBQWlCLEVBQUUsSUFBSTtDQUN4QixDQUFBIn0=
@@ -0,0 +1,3 @@
1
+ import { PresetBrowserSaveModalStyle, PresetBrowserStyle } from './PresetBrowserStyle';
2
+ export declare const defaultPresetBrowserStyle: PresetBrowserStyle;
3
+ export declare const defaultPresetBrowserSaveModalStyle: PresetBrowserSaveModalStyle;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultPresetBrowserSaveModalStyle = exports.defaultPresetBrowserStyle = void 0;
4
+ exports.defaultPresetBrowserStyle = {
5
+ container: {
6
+ x: 10,
7
+ y: 5,
8
+ width: 300,
9
+ height: 100,
10
+ interceptsMouseClicks: false,
11
+ },
12
+ comboBox: {
13
+ x: 0,
14
+ y: 0,
15
+ width: 200,
16
+ height: 30,
17
+ backgroundColor: '333333',
18
+ font: 'stylesState.defaultFontMedium',
19
+ textColor: 'ffffff',
20
+ padding: 7,
21
+ levelSeperator: '|',
22
+ },
23
+ prevButton: {
24
+ x: 205,
25
+ y: 0,
26
+ width: 30,
27
+ height: 30,
28
+ backgroundColor: '333333',
29
+ text: '<',
30
+ },
31
+ nextButton: {
32
+ x: 235,
33
+ y: 0,
34
+ width: 30,
35
+ height: 30,
36
+ backgroundColor: '333333',
37
+ text: '>',
38
+ },
39
+ deleteButton: {
40
+ x: 0,
41
+ y: 35,
42
+ width: 85,
43
+ height: 25,
44
+ backgroundColor: '333333',
45
+ text: 'Delete',
46
+ },
47
+ saveButton: {
48
+ x: 90,
49
+ y: 35,
50
+ width: 85,
51
+ height: 25,
52
+ backgroundColor: '333333',
53
+ text: 'Save',
54
+ },
55
+ saveAsButton: {
56
+ x: 180,
57
+ y: 35,
58
+ width: 85,
59
+ height: 25,
60
+ backgroundColor: '333333',
61
+ text: 'Save As',
62
+ },
63
+ };
64
+ exports.defaultPresetBrowserSaveModalStyle = {
65
+ fileNameLabel: {
66
+ textAlign: "left",
67
+ text: 'Enter a name for your preset:'
68
+ },
69
+ fileNameInput: {},
70
+ categoryLabel: {
71
+ textAlign: "left",
72
+ text: 'Select a category for your preset:'
73
+ },
74
+ categoryComboBox: {},
75
+ };
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdFByZXNldEJyb3dzZXJTdHlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0UHJlc2V0QnJvd3NlclN0eWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUthLFFBQUEseUJBQXlCLEdBQXVCO0lBQzNELFNBQVMsRUFBRTtRQUNULENBQUMsRUFBRSxFQUFFO1FBQ0wsQ0FBQyxFQUFFLENBQUM7UUFDSixLQUFLLEVBQUUsR0FBRztRQUNWLE1BQU0sRUFBRSxHQUFHO1FBQ1gscUJBQXFCLEVBQUUsS0FBSztLQUM3QjtJQUNELFFBQVEsRUFBRTtRQUNSLENBQUMsRUFBRSxDQUFDO1FBQ0osQ0FBQyxFQUFFLENBQUM7UUFDSixLQUFLLEVBQUUsR0FBRztRQUNWLE1BQU0sRUFBRSxFQUFFO1FBQ1YsZUFBZSxFQUFFLFFBQVE7UUFDekIsSUFBSSxFQUFFLCtCQUErQjtRQUNyQyxTQUFTLEVBQUUsUUFBUTtRQUNuQixPQUFPLEVBQUUsQ0FBQztRQUNWLGNBQWMsRUFBRSxHQUFHO0tBQ3BCO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsQ0FBQyxFQUFFLEdBQUc7UUFDTixDQUFDLEVBQUUsQ0FBQztRQUNKLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUU7UUFDVixlQUFlLEVBQUUsUUFBUTtRQUN6QixJQUFJLEVBQUUsR0FBRztLQUNWO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsQ0FBQyxFQUFFLEdBQUc7UUFDTixDQUFDLEVBQUUsQ0FBQztRQUNKLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUU7UUFDVixlQUFlLEVBQUUsUUFBUTtRQUN6QixJQUFJLEVBQUUsR0FBRztLQUNWO0lBQ0QsWUFBWSxFQUFFO1FBQ1osQ0FBQyxFQUFFLENBQUM7UUFDSixDQUFDLEVBQUUsRUFBRTtRQUNMLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUU7UUFDVixlQUFlLEVBQUUsUUFBUTtRQUN6QixJQUFJLEVBQUUsUUFBUTtLQUNmO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsQ0FBQyxFQUFFLEVBQUU7UUFDTCxDQUFDLEVBQUUsRUFBRTtRQUNMLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUU7UUFDVixlQUFlLEVBQUUsUUFBUTtRQUN6QixJQUFJLEVBQUUsTUFBTTtLQUNiO0lBQ0QsWUFBWSxFQUFFO1FBQ1osQ0FBQyxFQUFFLEdBQUc7UUFDTixDQUFDLEVBQUUsRUFBRTtRQUNMLEtBQUssRUFBRSxFQUFFO1FBQ1QsTUFBTSxFQUFFLEVBQUU7UUFDVixlQUFlLEVBQUUsUUFBUTtRQUN6QixJQUFJLEVBQUUsU0FBUztLQUNoQjtDQUNGLENBQUE7QUFFWSxRQUFBLGtDQUFrQyxHQUFnQztJQUM3RSxhQUFhLEVBQUU7UUFDYixTQUFTLEVBQUMsTUFBTTtRQUNoQixJQUFJLEVBQUMsK0JBQStCO0tBQ3JDO0lBQ0QsYUFBYSxFQUFFLEVBQUU7SUFDakIsYUFBYSxFQUFFO1FBQ2IsU0FBUyxFQUFDLE1BQU07UUFDaEIsSUFBSSxFQUFDLG9DQUFvQztLQUMxQztJQUNELGdCQUFnQixFQUFFLEVBQUU7Q0FDckIsQ0FBQSJ9
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Hook interface returned by {@link usePresetSaveModal}.
3
+ *
4
+ * Use this type when providing a custom save-modal implementation via
5
+ * {@link PresetBrowserConfig.presetSaveModalHook}.
6
+ */
7
+ export type PresetSaveModalHook = {
8
+ /** Update the modal's internal props before showing it (e.g. set callbacks) */
9
+ setSaveModalProps: ({}: {}) => void;
10
+ /** Show the save-preset modal */
11
+ showSaveModal: () => void;
12
+ /** Hide the save-preset modal */
13
+ hideSaveModal: () => void;
14
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJlc2V0U2F2ZU1vZGFsSG9vay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ob29rcy9QcmVzZXRTYXZlTW9kYWxIb29rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,36 @@
1
+ import { PresetSaveModalHook } from './PresetSaveModalHook';
2
+ import { PresetBrowserSaveModalStyle } from '../PresetBrowserStyle';
3
+ /**
4
+ * Props for {@link usePresetSaveModal}.
5
+ */
6
+ type UsePresetSaveModalProps = {
7
+ /** When `true`, the modal shows a category picker and requires a category selection */
8
+ enforceCategories: boolean;
9
+ /** Style overrides applied to the {@link SavePresetWithCategoriesModal} */
10
+ modalStyle: PresetBrowserSaveModalStyle;
11
+ };
12
+ /**
13
+ * Hook that creates and manages the built-in save-preset modal.
14
+ *
15
+ * Returns a {@link PresetSaveModalHook} that can be passed directly to
16
+ * {@link PresetBrowserConfig.presetSaveModalHook}, or used independently
17
+ * when building a custom preset browser.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const saveModalHook = usePresetSaveModal({
22
+ * enforceCategories: true,
23
+ * modalStyle: defaultPresetBrowserSaveModalStyle,
24
+ * });
25
+ *
26
+ * // Show programmatically:
27
+ * saveModalHook.setSaveModalProps({
28
+ * onCancelTrigger: () => {},
29
+ * onApproveTrigger: () => {},
30
+ * hideModal: saveModalHook.hideSaveModal,
31
+ * });
32
+ * saveModalHook.showSaveModal();
33
+ * ```
34
+ */
35
+ export declare function usePresetSaveModal(props: UsePresetSaveModalProps): PresetSaveModalHook;
36
+ export {};
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.usePresetSaveModal = usePresetSaveModal;
40
+ const React = __importStar(require("react"));
41
+ const react_1 = require("react");
42
+ const ge_dialogs_lib_1 = require("@gorilla-engine-sdk/ge-dialogs-lib");
43
+ const SavePresetWithCategoriesModal_1 = __importDefault(require("../views/SavePresetWithCategoriesModal"));
44
+ /**
45
+ * Hook that creates and manages the built-in save-preset modal.
46
+ *
47
+ * Returns a {@link PresetSaveModalHook} that can be passed directly to
48
+ * {@link PresetBrowserConfig.presetSaveModalHook}, or used independently
49
+ * when building a custom preset browser.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * const saveModalHook = usePresetSaveModal({
54
+ * enforceCategories: true,
55
+ * modalStyle: defaultPresetBrowserSaveModalStyle,
56
+ * });
57
+ *
58
+ * // Show programmatically:
59
+ * saveModalHook.setSaveModalProps({
60
+ * onCancelTrigger: () => {},
61
+ * onApproveTrigger: () => {},
62
+ * hideModal: saveModalHook.hideSaveModal,
63
+ * });
64
+ * saveModalHook.showSaveModal();
65
+ * ```
66
+ */
67
+ function usePresetSaveModal(props) {
68
+ const [saveModalProps, setSaveModalProps] = (0, react_1.useState)({
69
+ onCancelTrigger: undefined,
70
+ onApproveTrigger: undefined,
71
+ hideModal: undefined,
72
+ });
73
+ const saveModalPropsRef = (0, react_1.useRef)(saveModalProps);
74
+ saveModalPropsRef.current = saveModalProps;
75
+ const [showSaveModal, hideSaveModal] = (0, ge_dialogs_lib_1.useModal)(() => (React.createElement(SavePresetWithCategoriesModal_1.default, { ...saveModalPropsRef.current, enforceCategories: props.enforceCategories, modalStyle: props.modalStyle })), [true, false]);
76
+ return { setSaveModalProps, showSaveModal, hideSaveModal };
77
+ }
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlUHJlc2V0U2F2ZU1vZGFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hvb2tzL3VzZVByZXNldFNhdmVNb2RhbC50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEwQ0EsZ0RBcUJDO0FBL0RELDZDQUErQjtBQUUvQixpQ0FBeUM7QUFFekMsdUVBQThEO0FBRzlELDJHQUFtRjtBQVluRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUNILFNBQWdCLGtCQUFrQixDQUFDLEtBQThCO0lBQy9ELE1BQU0sQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsR0FBRyxJQUFBLGdCQUFRLEVBQUM7UUFDbkQsZUFBZSxFQUFFLFNBQVM7UUFDMUIsZ0JBQWdCLEVBQUUsU0FBUztRQUMzQixTQUFTLEVBQUUsU0FBUztLQUNyQixDQUFDLENBQUM7SUFFSCxNQUFNLGlCQUFpQixHQUFHLElBQUEsY0FBTSxFQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pELGlCQUFpQixDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUM7SUFDM0MsTUFBTSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsR0FBRyxJQUFBLHlCQUFRLEVBQzdDLEdBQUcsRUFBRSxDQUFDLENBQ0osb0JBQUMsdUNBQTZCLE9BQ3hCLGlCQUFpQixDQUFDLE9BQU8sRUFDN0IsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQixFQUMxQyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsR0FDNUIsQ0FDSCxFQUNELENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUNkLENBQUM7SUFFRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBQzdELENBQUMifQ==
@@ -0,0 +1,9 @@
1
+ import { PresetBrowserConfig } from './PresetBrowserConfig';
2
+ import { PresetBrowserSaveModalStyle, PresetBrowserStyle } from './PresetBrowserStyle';
3
+ import { defaultPresetBrowserSaveModalStyle, defaultPresetBrowserStyle } from './defaultPresetBrowserStyle';
4
+ import { defaultPresetBrowserConfig } from './defaultPresetBrowserConfig';
5
+ import { PresetSaveModalHook } from './hooks/PresetSaveModalHook';
6
+ import { usePresetSaveModal } from './hooks/usePresetSaveModal';
7
+ import PresetBrowser from './views/PresetBrowser';
8
+ import SavePresetWithCategoriesModal from './views/SavePresetWithCategoriesModal';
9
+ export { PresetBrowserConfig, PresetSaveModalHook, usePresetSaveModal, PresetBrowserStyle, PresetBrowserSaveModalStyle, defaultPresetBrowserSaveModalStyle, defaultPresetBrowserStyle, defaultPresetBrowserConfig, PresetBrowser, SavePresetWithCategoriesModal, };
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SavePresetWithCategoriesModal = exports.PresetBrowser = exports.defaultPresetBrowserConfig = exports.defaultPresetBrowserStyle = exports.defaultPresetBrowserSaveModalStyle = exports.usePresetSaveModal = void 0;
7
+ const defaultPresetBrowserStyle_1 = require("./defaultPresetBrowserStyle");
8
+ Object.defineProperty(exports, "defaultPresetBrowserSaveModalStyle", { enumerable: true, get: function () { return defaultPresetBrowserStyle_1.defaultPresetBrowserSaveModalStyle; } });
9
+ Object.defineProperty(exports, "defaultPresetBrowserStyle", { enumerable: true, get: function () { return defaultPresetBrowserStyle_1.defaultPresetBrowserStyle; } });
10
+ const defaultPresetBrowserConfig_1 = require("./defaultPresetBrowserConfig");
11
+ Object.defineProperty(exports, "defaultPresetBrowserConfig", { enumerable: true, get: function () { return defaultPresetBrowserConfig_1.defaultPresetBrowserConfig; } });
12
+ const usePresetSaveModal_1 = require("./hooks/usePresetSaveModal");
13
+ Object.defineProperty(exports, "usePresetSaveModal", { enumerable: true, get: function () { return usePresetSaveModal_1.usePresetSaveModal; } });
14
+ const PresetBrowser_1 = __importDefault(require("./views/PresetBrowser"));
15
+ exports.PresetBrowser = PresetBrowser_1.default;
16
+ const SavePresetWithCategoriesModal_1 = __importDefault(require("./views/SavePresetWithCategoriesModal"));
17
+ exports.SavePresetWithCategoriesModal = SavePresetWithCategoriesModal_1.default;
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBNEJBLDJFQUdxQztBQWFuQyxtSEFmQSw4REFBa0MsT0FlQTtBQUNsQywwR0FmQSxxREFBeUIsT0FlQTtBQWIzQiw2RUFBMEU7QUFjeEUsMkdBZE8sdURBQTBCLE9BY1A7QUFaNUIsbUVBQWdFO0FBTzlELG1HQVBPLHVDQUFrQixPQU9QO0FBTnBCLDBFQUFrRDtBQVloRCx3QkFaSyx1QkFBYSxDQVlMO0FBWGYsMEdBQWtGO0FBWWhGLHdDQVpLLHVDQUE2QixDQVlMIn0=
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { PresetBrowserSaveModalStyle, PresetBrowserStyle } from '../PresetBrowserStyle';
3
+ import { PresetBrowserConfig } from '../PresetBrowserConfig';
4
+ /**
5
+ * Props for {@link PresetBrowser}.
6
+ */
7
+ type PresetBrowserProps = {
8
+ /** Visual style overrides — defaults to {@link defaultPresetBrowserStyle} */
9
+ browserStyle?: PresetBrowserStyle;
10
+ /** Style overrides for the save-as modal — defaults to {@link defaultPresetBrowserSaveModalStyle} */
11
+ saveModalStyle?: PresetBrowserSaveModalStyle;
12
+ /** Behaviour configuration — defaults to {@link defaultPresetBrowserConfig} */
13
+ config?: PresetBrowserConfig;
14
+ };
15
+ /**
16
+ * Drop-in preset browser UI component for Gorilla Engine React plugins.
17
+ *
18
+ * Renders a combo-box listing all loaded presets, prev/next navigation
19
+ * buttons, and save / save-as / delete buttons for user presets. Must be
20
+ * rendered inside a component tree wrapped by
21
+ * `SessionAndPresetsStateProvider` from `@gorilla-engine-sdk/ge-session-presets-lib`.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * import { PresetBrowser } from '@gorilla-engine-sdk/ge-preset-browser';
26
+ *
27
+ * function PluginUI() {
28
+ * return (
29
+ * <geLabel width={800} height={600}>
30
+ * <PresetBrowser
31
+ * browserStyle={{ container: { x: 10, y: 5, width: 300, height: 65 } }}
32
+ * config={{ askBeforeDelete: true, enforceCategories: false }}
33
+ * />
34
+ * </geLabel>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ declare function PresetBrowser(props: PresetBrowserProps): React.JSX.Element;
40
+ export default PresetBrowser;
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const React = __importStar(require("react"));
37
+ const react_1 = require("react");
38
+ const ge_session_presets_lib_1 = require("@gorilla-engine-sdk/ge-session-presets-lib");
39
+ const ge_dialogs_lib_1 = require("@gorilla-engine-sdk/ge-dialogs-lib");
40
+ const usePresetSaveModal_1 = require("../hooks/usePresetSaveModal");
41
+ const defaultPresetBrowserStyle_1 = require("../defaultPresetBrowserStyle");
42
+ const defaultPresetBrowserConfig_1 = require("../defaultPresetBrowserConfig");
43
+ /**
44
+ * Drop-in preset browser UI component for Gorilla Engine React plugins.
45
+ *
46
+ * Renders a combo-box listing all loaded presets, prev/next navigation
47
+ * buttons, and save / save-as / delete buttons for user presets. Must be
48
+ * rendered inside a component tree wrapped by
49
+ * `SessionAndPresetsStateProvider` from `@gorilla-engine-sdk/ge-session-presets-lib`.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * import { PresetBrowser } from '@gorilla-engine-sdk/ge-preset-browser';
54
+ *
55
+ * function PluginUI() {
56
+ * return (
57
+ * <geLabel width={800} height={600}>
58
+ * <PresetBrowser
59
+ * browserStyle={{ container: { x: 10, y: 5, width: 300, height: 65 } }}
60
+ * config={{ askBeforeDelete: true, enforceCategories: false }}
61
+ * />
62
+ * </geLabel>
63
+ * );
64
+ * }
65
+ * ```
66
+ */
67
+ function PresetBrowser(props) {
68
+ const [browserStyle] = (0, react_1.useState)(props?.browserStyle ? props?.browserStyle : defaultPresetBrowserStyle_1.defaultPresetBrowserStyle);
69
+ const [saveModalStyle] = (0, react_1.useState)(props.saveModalStyle ? props.saveModalStyle : defaultPresetBrowserStyle_1.defaultPresetBrowserSaveModalStyle);
70
+ const [config] = (0, react_1.useState)(props.config ? props.config : defaultPresetBrowserConfig_1.defaultPresetBrowserConfig);
71
+ const configState = (0, ge_session_presets_lib_1.useSessionAndPresetsConfig)();
72
+ const state = (0, ge_session_presets_lib_1.useSessionAndPresetsState)();
73
+ const stateRef = (0, react_1.useRef)(state);
74
+ stateRef.current = state;
75
+ const refDeleteButton = (0, react_1.createRef)();
76
+ const refSaveButton = (0, react_1.createRef)();
77
+ const [showToolTip, hideToolTip] = (0, ge_dialogs_lib_1.useToolTip)();
78
+ const { savePreset, loadPresetFromSource, deletePreset, prevPreset, nextPreset, getLoadedPreset, } = (0, ge_session_presets_lib_1.useSessionAndPresets)();
79
+ const [modalProps, setModalProps] = (0, react_1.useState)({
80
+ title: 'Error',
81
+ message: 'Error message',
82
+ cancelTrigger: false,
83
+ cancelTriggerLabel: undefined,
84
+ onCancelTrigger: undefined,
85
+ approveTrigger: false,
86
+ approveTriggerLabel: undefined,
87
+ onApproveTrigger: undefined,
88
+ });
89
+ const modalPropsRef = (0, react_1.useRef)(modalProps);
90
+ modalPropsRef.current = modalProps;
91
+ const [showModal, hideModal] = (0, ge_dialogs_lib_1.useModal)(() => React.createElement(ge_dialogs_lib_1.DefaultModal, { ...modalPropsRef.current }), [true, false]);
92
+ const [presetSaveModalHook] = (0, react_1.useState)(config.presetSaveModalHook
93
+ ? config.presetSaveModalHook
94
+ : (0, usePresetSaveModal_1.usePresetSaveModal)({
95
+ enforceCategories: config.enforceCategories ? config.enforceCategories : false,
96
+ modalStyle: saveModalStyle,
97
+ }));
98
+ const [cbbPresets, setCbbPresets] = (0, react_1.useState)([]);
99
+ const [saveDeleteEnabled, setSaveDeleteEnabled] = (0, react_1.useState)(true);
100
+ /**
101
+ * Triggered when state.presets changes due to initial content-scan
102
+ * or re-scan, see App.tsx
103
+ */
104
+ (0, react_1.useEffect)(() => {
105
+ const b = state.presets.map((item) => `${item.type}|${item.category ? item.category + '|' : ''}${item.name}`);
106
+ setCbbPresets(b);
107
+ }, [state.presets]);
108
+ /**
109
+ * Triggered after a preset was loaded
110
+ */
111
+ (0, react_1.useEffect)(() => {
112
+ if (state.loadPresetUUID) {
113
+ if (getLoadedPreset().type === configState.factoryPresetType) {
114
+ setSaveDeleteEnabled(false);
115
+ }
116
+ else {
117
+ setSaveDeleteEnabled(true);
118
+ }
119
+ }
120
+ }, [state.loadPresetUUID]);
121
+ (0, react_1.useEffect)(() => {
122
+ if (state.presetIndex < 0)
123
+ return;
124
+ handleChangedPresetFlag();
125
+ }, [state.presetChanged]);
126
+ const handleChangedPresetFlag = () => {
127
+ if (state.presetChanged) {
128
+ const s = cbbPresets[state.presetIndex];
129
+ if (s.slice(s.length - 2, s.length) !== ' *') {
130
+ const o = `${s} *`;
131
+ cbbPresets[state.presetIndex] = o;
132
+ }
133
+ setCbbPresets([...cbbPresets]);
134
+ }
135
+ else {
136
+ const b = cbbPresets.map((item) => {
137
+ if (item.slice(item.length - 2, item.length) === ' *') {
138
+ return item.slice(0, item.length - 2);
139
+ }
140
+ else {
141
+ return item;
142
+ }
143
+ });
144
+ setCbbPresets([...b]);
145
+ }
146
+ };
147
+ (0, react_1.useEffect)(() => { }, [cbbPresets]);
148
+ /**
149
+ * Triggered when the combo-box changes
150
+ * @param v - index
151
+ */
152
+ const onPresetChange = (v) => {
153
+ if (v === stateRef.current.presetIndex)
154
+ return;
155
+ loadPresetFromSource(stateRef.current.presets[v].filePath, false);
156
+ };
157
+ /**
158
+ * Load previous preset
159
+ */
160
+ const onPrevPreset = () => {
161
+ prevPreset();
162
+ };
163
+ /**
164
+ * Load next preset
165
+ */
166
+ const onNextPreset = () => {
167
+ nextPreset();
168
+ };
169
+ /**
170
+ * Save preset
171
+ */
172
+ const onSavePreset = async () => {
173
+ if (stateRef.current.presetIndex > -1) {
174
+ try {
175
+ const filePath = getLoadedPreset().filePath;
176
+ savePreset(filePath);
177
+ }
178
+ catch (err) { }
179
+ }
180
+ };
181
+ const onSaveAsPreset = async () => {
182
+ presetSaveModalHook.setSaveModalProps({
183
+ hideModal: presetSaveModalHook.hideSaveModal,
184
+ });
185
+ presetSaveModalHook.showSaveModal();
186
+ };
187
+ /**
188
+ * Delete preset
189
+ */
190
+ const onDeletePreset = () => {
191
+ if (stateRef.current.presetIndex > -1) {
192
+ setModalProps({
193
+ ...modalProps,
194
+ title: `Delete Preset ${stateRef.current.presets[stateRef.current.presetIndex].name}`,
195
+ message: `Are you sure you want do delete the selected preset ${stateRef.current.presets[stateRef.current.presetIndex].name}?`,
196
+ cancelTrigger: true,
197
+ onCancelTrigger: hideModal,
198
+ approveTrigger: true,
199
+ approveTriggerLabel: 'Delete Preset',
200
+ onApproveTrigger: () => {
201
+ hideModal();
202
+ deletePreset(stateRef.current.presets[stateRef.current.presetIndex].filePath);
203
+ },
204
+ });
205
+ }
206
+ showModal();
207
+ };
208
+ return (React.createElement(React.Fragment, null,
209
+ React.createElement("geLabel", { ...browserStyle.container },
210
+ React.createElement("geComboBox", { ...browserStyle.comboBox, items: cbbPresets, value: state.presetIndex, onChange: onPresetChange }),
211
+ React.createElement("geButton", { ...browserStyle.prevButton, onClick: onPrevPreset }),
212
+ React.createElement("geButton", { ...browserStyle.nextButton, onClick: onNextPreset }),
213
+ React.createElement("geButton", { ...browserStyle.deleteButton, ref: refDeleteButton, enabled: saveDeleteEnabled, onClick: () => {
214
+ if (saveDeleteEnabled)
215
+ onDeletePreset();
216
+ }, onMouseEnter: () => {
217
+ if (!saveDeleteEnabled)
218
+ showToolTip(refDeleteButton.current, `Factory preset can not be deleted!`);
219
+ }, onMouseExit: () => {
220
+ hideToolTip();
221
+ } }),
222
+ React.createElement("geButton", { ...browserStyle.saveButton, ref: refSaveButton, enabled: saveDeleteEnabled, onClick: () => {
223
+ if (saveDeleteEnabled)
224
+ onSavePreset();
225
+ }, onMouseEnter: () => {
226
+ if (!saveDeleteEnabled)
227
+ showToolTip(refSaveButton.current, `Factory preset can not be saved!`);
228
+ }, onMouseExit: () => {
229
+ hideToolTip();
230
+ } }),
231
+ React.createElement("geButton", { ...browserStyle.saveAsButton, text: "Save As", onClick: onSaveAsPreset }),
232
+ state.presetChanged && (React.createElement("geLabel", { x: 2, y: 2, width: 8, height: 8, cornerRadius: 4, backgroundColor: "ff0000" })))));
233
+ }
234
+ exports.default = PresetBrowser;
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJlc2V0QnJvd3Nlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92aWV3cy9QcmVzZXRCcm93c2VyLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUErQjtBQUUvQixpQ0FBK0Q7QUFFL0QsdUZBSW9EO0FBRXBELHVFQUF3RjtBQVN4RixvRUFBaUU7QUFDakUsNEVBR3NDO0FBRXRDLDhFQUEyRTtBQWMzRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxTQUFTLGFBQWEsQ0FBQyxLQUF5QjtJQUM5QyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBQSxnQkFBUSxFQUM3QixLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxxREFBeUIsQ0FDdEUsQ0FBQztJQUVGLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxJQUFBLGdCQUFRLEVBQy9CLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLDhEQUFrQyxDQUNqRixDQUFDO0lBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUEsZ0JBQVEsRUFBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyx1REFBMEIsQ0FBQyxDQUFDO0lBRXBGLE1BQU0sV0FBVyxHQUE0QixJQUFBLG1EQUEwQixHQUFFLENBQUM7SUFDMUUsTUFBTSxLQUFLLEdBQTJCLElBQUEsa0RBQXlCLEdBQUUsQ0FBQztJQUNsRSxNQUFNLFFBQVEsR0FBRyxJQUFBLGNBQU0sRUFBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixRQUFRLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUV6QixNQUFNLGVBQWUsR0FBRyxJQUFBLGlCQUFTLEdBQVksQ0FB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
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import { PresetBrowserSaveModalStyle } from '../PresetBrowserStyle';
3
+ type SavePresetWithCategorieProps = {
4
+ onCancelTrigger(): any;
5
+ onApproveTrigger(): any;
6
+ hideModal(): any;
7
+ enforceCategories: boolean;
8
+ modalStyle: PresetBrowserSaveModalStyle;
9
+ };
10
+ declare function SavePresetWithCategoriesModal(props: SavePresetWithCategorieProps): React.JSX.Element;
11
+ export default SavePresetWithCategoriesModal;
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const React = __importStar(require("react"));
37
+ const path = require("path");
38
+ const react_1 = require("react");
39
+ const ge_session_presets_lib_1 = require("@gorilla-engine-sdk/ge-session-presets-lib");
40
+ const ge_dialogs_lib_1 = require("@gorilla-engine-sdk/ge-dialogs-lib");
41
+ function SavePresetWithCategoriesModal(props) {
42
+ const modalStylesState = (0, ge_dialogs_lib_1.useDialogsStylesState)();
43
+ const sessionAndPresetsConfigState = (0, ge_session_presets_lib_1.useSessionAndPresetsConfig)();
44
+ const sessionAndPresetState = (0, ge_session_presets_lib_1.useSessionAndPresetsState)();
45
+ const sessionAndPresetsDispatch = (0, ge_session_presets_lib_1.useSessionAndPresetsStateDispatch)();
46
+ const { savePreset, loadPresetFromSource } = (0, ge_session_presets_lib_1.useSessionAndPresets)();
47
+ const textBoxRef = React.createRef();
48
+ // state for the preset name
49
+ const [presetName, setPresetName] = (0, react_1.useState)('');
50
+ // state for the presetFilePath to save the filt to
51
+ const [presetFilePath, setPresetFilePath] = (0, react_1.useState)('');
52
+ const [categories, setCategories] = (0, react_1.useState)([]);
53
+ const [selectedCategory, setSelectedCategory] = (0, react_1.useState)(0);
54
+ // state of the approve/save-button in footer
55
+ const [saveButtonEnabled, setSaveButtonEnabled] = (0, react_1.useState)(false);
56
+ // state indicating if a preset under the current name already exists
57
+ const [presetFileExists, setPresetFileExists] = (0, react_1.useState)(false);
58
+ // state to indicate if an existing preset should be overridden
59
+ const [overrideExistingPreset, setOverrideExistingPreset] = (0, react_1.useState)(false);
60
+ (0, react_1.useEffect)(() => {
61
+ textBoxRef.current.nativeHandle.grabKeyboardFocus();
62
+ if (sessionAndPresetState.presets) {
63
+ const c = {};
64
+ sessionAndPresetState.presets.map((preset) => {
65
+ const v = 0;
66
+ if (preset.category)
67
+ c[preset.category] = true;
68
+ });
69
+ if (Object.keys(c).length)
70
+ setCategories(Object.keys(c));
71
+ }
72
+ }, []);
73
+ /**
74
+ * useEffect triggers when the presets array changes after a save operation,
75
+ * selects the newly saved preset and closes the modal.
76
+ */
77
+ (0, react_1.useEffect)(() => {
78
+ if (presetFilePath !== '') {
79
+ // Don't load the newly saved preset - just find & select
80
+ //loadPresetFromSource(presetFilePath, false);
81
+ const preset = sessionAndPresetState.presets.find((p) => {
82
+ return p.filePath === presetFilePath;
83
+ });
84
+ sessionAndPresetsDispatch({
85
+ type: ge_session_presets_lib_1.SessionAndPresetsDispatchTypes.setPreset,
86
+ payload: {
87
+ preset: preset,
88
+ filePath: presetFilePath,
89
+ },
90
+ });
91
+ props.hideModal();
92
+ }
93
+ }, [sessionAndPresetState.presets]);
94
+ /**
95
+ * event-handler for the cancel button
96
+ */
97
+ const onCancelTrigger = () => {
98
+ props.onCancelTrigger();
99
+ props.hideModal();
100
+ };
101
+ /**
102
+ * event-handler for the save button
103
+ */
104
+ const onApproveTrigger = async () => {
105
+ // Create the file-path of the preset
106
+ let filePath = path.join(sessionAndPresetsConfigState.userPresetPath, `${presetName}${sessionAndPresetsConfigState.presetFileSuffix}`);
107
+ if (props.enforceCategories && selectedCategory > -1) {
108
+ filePath = path.join(sessionAndPresetsConfigState.userPresetPath, categories[selectedCategory], `${presetName}${sessionAndPresetsConfigState.presetFileSuffix}`);
109
+ }
110
+ setPresetFilePath(filePath);
111
+ await savePreset(filePath);
112
+ props.onApproveTrigger();
113
+ };
114
+ /**
115
+ * event-handler for the file-name textbox
116
+ */
117
+ const onPresetNameChange = (text) => {
118
+ // Check if a preset with same name exists
119
+ const p = sessionAndPresetState.presets?.find((preset) => {
120
+ // if the preset tyoe a factory preset, stop here
121
+ if (preset.type !== sessionAndPresetsConfigState.userPresetType)
122
+ return false;
123
+ // compare the texts
124
+ const pn = preset.name.slice(0, text.length).toLowerCase();
125
+ if (pn === text.toLowerCase() && preset.name.length === text.length) {
126
+ return true;
127
+ }
128
+ return false;
129
+ });
130
+ // Set flag exists true/false
131
+ setPresetFileExists(p ? true : false);
132
+ // if no preset exists or override is active & text has at least one character -
133
+ // activate save button, else deactivate
134
+ if ((!p || overrideExistingPreset) && text.length > 0) {
135
+ setSaveButtonEnabled(true);
136
+ }
137
+ else {
138
+ setSaveButtonEnabled(false);
139
+ }
140
+ // Set the state for the preset-name the user is typing
141
+ setPresetName(text);
142
+ };
143
+ // event-handler for the override toggle
144
+ const onOverridePresetChange = (v) => {
145
+ // if the set value is true, a preset-file by same name exists & the button is not yet active
146
+ if (v && presetFileExists && !saveButtonEnabled) {
147
+ setSaveButtonEnabled(true);
148
+ }
149
+ else if (!v && presetFileExists) {
150
+ setSaveButtonEnabled(false);
151
+ }
152
+ // set the state for the override flag
153
+ setOverrideExistingPreset(v);
154
+ };
155
+ // Dimensions of the modal
156
+ const modalWidth = 400;
157
+ const modalHeight = props.enforceCategories ? 320 : 280;
158
+ // Title of the modal
159
+ const title = 'Save Preset';
160
+ // Button labels in footer section -
161
+ const cancelTriggerLabel = 'Cancel';
162
+ const approveTriggerLabel = 'Save';
163
+ return (React.createElement(React.Fragment, null,
164
+ React.createElement(ge_dialogs_lib_1.Modal, { isBlocking: true, isBlockingClosable: true, modalStyle: modalStylesState.modal, modalWidth: modalWidth, modalHeight: modalHeight, title: title, closeTrigger: true, cancelTrigger: true, cancelTriggerLabel: cancelTriggerLabel, onCancelTrigger: onCancelTrigger, approveTrigger: true, approveTriggerEnabled: saveButtonEnabled, approveTriggerLabel: approveTriggerLabel, onApproveTrigger: onApproveTrigger },
165
+ React.createElement("geLabel", { width: modalWidth, height: 25, y: 0, ...props.modalStyle.fileNameLabel }),
166
+ React.createElement("geTextBox", { ref: textBoxRef, width: modalWidth, height: 30, y: 40, onChange: onPresetNameChange, ...props.modalStyle.fileNameInput, onKeyPressed: (value) => {
167
+ if (value === 'return')
168
+ onApproveTrigger();
169
+ } }),
170
+ React.createElement("geLabel", { visible: props.enforceCategories, width: modalWidth, height: 25, y: 85, ...props.modalStyle.categoryLabel }),
171
+ React.createElement("geComboBox", { visible: props.enforceCategories, width: modalWidth, height: 24, y: 125, backgroundColor: "999999", levelSeperator: "|", items: categories, value: selectedCategory, onChange: (v) => {
172
+ setSelectedCategory(v);
173
+ }, ...props.modalStyle.categoryComboBox }))));
174
+ }
175
+ exports.default = SavePresetWithCategoriesModal;
176
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2F2ZVByZXNldFdpdGhDYXRlZ29yaWVzTW9kYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmlld3MvU2F2ZVByZXNldFdpdGhDYXRlZ29yaWVzTW9kYWwudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQStCO0FBRy9CLDZCQUE4QjtBQUU5QixpQ0FBNEM7QUFJNUMsdUZBUW9EO0FBRXBELHVFQUk0QztBQVk1QyxTQUFTLDZCQUE2QixDQUFDLEtBQW1DO0lBQ3hFLE1BQU0sZ0JBQWdCLEdBQXVCLElBQUEsc0NBQXFCLEdBQUUsQ0FBQztJQUVyRSxNQUFNLDRCQUE0QixHQUE0QixJQUFBLG1EQUEwQixHQUFFLENBQUM7SUFFM0YsTUFBTSxxQkFBcUIsR0FBMkIsSUFBQSxrREFBeUIsR0FBRSxDQUFDO0lBQ2xGLE1BQU0seUJBQXlCLEdBQUcsSUFBQSwwREFBaUMsR0FBRSxDQUFDO0lBRXRFLE1BQU0sRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxJQUFBLDZDQUFvQixHQUFFLENBQUM7SUFFcEUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFNBQVMsRUFBYSxDQUFDO0lBRWhELDRCQUE0QjtJQUM1QixNQUFNLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxHQUFHLElBQUEsZ0JBQVEsRUFBQyxFQUFFLENBQUMsQ0FBQztJQUVqRCxtREFBbUQ7SUFDbkQsTUFBTSxDQUFDLGNBQWMsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHLElBQUEsZ0JBQVEsRUFBQyxFQUFFLENBQUMsQ0FBQztJQUV6RCxNQUFNLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxHQUFHLElBQUEsZ0JBQVEsRUFBQyxFQUFFLENBQUMsQ0FBQztJQUNqRCxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsbUJBQW1CLENBQUMsR0FBRyxJQUFBLGdCQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUM7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
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@gorilla-engine-sdk/ge-preset-browser",
3
+ "version": "0.5.6",
4
+ "description": "Simple and easy to use preset browser for Gorilla Engine plugins.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md",
10
+ "LICENSE.md"
11
+ ],
12
+ "scripts": {
13
+ "test": "echo \"No tests specified for ge-preset-browser\"",
14
+ "prepack": "npx tsc",
15
+ "start": "tsc -w",
16
+ "build": "npx tsc --declaration",
17
+ "ci:publish": "node ../../scripts/ci-publish.js"
18
+ },
19
+ "author": "UJAM Inc.",
20
+ "license": "SEE LICENSE IN LICENSE.md",
21
+ "peerDependencies": {
22
+ "@gorilla-engine-sdk/ge-dialogs-lib": "0.x",
23
+ "@gorilla-engine-sdk/ge-session-presets-lib": "0.x",
24
+ "@gorilla-engine-sdk/gorilla-engine-react": "^1.6.1",
25
+ "react": "^19.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@gorilla-engine-sdk/ge-dialogs-lib": "0.x",
29
+ "@gorilla-engine-sdk/ge-session-presets-lib": "0.x",
30
+ "@gorilla-engine-sdk/gorilla-engine-react": "^1.6.1",
31
+ "@types/gorilla-engine": "^1.1.11",
32
+ "@types/node": "^22.0.0",
33
+ "@types/react": "^19.2.16",
34
+ "@types/react-reconciler": "^0.33.0",
35
+ "react": "^19.0.0",
36
+ "typescript": "^6.0.3"
37
+ },
38
+ "dependencies": {},
39
+ "homepage": "https://www.gorilla-engine.com/",
40
+ "keywords": [
41
+ "gorilla-engine",
42
+ "UJAM"
43
+ ],
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "registry": "https://registry.npmjs.org/"
47
+ }
48
+ }