@jbrowse/plugin-linear-genome-view 5.0.0-beta.7 → 5.0.0-beta.9
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/esm/FeatureTrack/configSchema.d.ts +140 -48
- package/esm/LinearGenomeView/afterAttach.d.ts +5 -5
- package/esm/LinearGenomeView/afterAttach.js +18 -24
- package/esm/LinearGenomeView/closeUps.d.ts +83 -0
- package/esm/LinearGenomeView/closeUps.js +211 -0
- package/esm/LinearGenomeView/components/AddCloseUpDialog.d.ts +19 -0
- package/esm/LinearGenomeView/components/AddCloseUpDialog.js +29 -0
- package/esm/LinearGenomeView/components/CloseUps.d.ts +5 -0
- package/esm/LinearGenomeView/components/CloseUps.js +75 -0
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +2 -1
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +6 -2
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
- package/esm/LinearGenomeView/components/Header.js +6 -1
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +4 -34
- package/esm/LinearGenomeView/components/Highlight.js +2 -4
- package/esm/LinearGenomeView/components/HighlightBand.js +2 -2
- package/esm/LinearGenomeView/components/HighlightChip.d.ts +1 -2
- package/esm/LinearGenomeView/components/HighlightChip.js +5 -7
- package/esm/LinearGenomeView/components/ImportForm.js +2 -2
- package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -3
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +3 -2
- package/esm/LinearGenomeView/components/OverviewHighlight.js +1 -1
- package/esm/LinearGenomeView/components/OverviewHighlightBand.js +2 -3
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +7 -1
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +22 -7
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +2 -3
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +6 -21
- package/esm/LinearGenomeView/components/SearchBox.js +2 -2
- package/esm/LinearGenomeView/components/TrackContainer.js +12 -5
- package/esm/LinearGenomeView/components/TrackLabel.js +1 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +3 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +3 -7
- package/esm/LinearGenomeView/components/TracksContainer.js +7 -15
- package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
- package/esm/LinearGenomeView/components/useSideScroll.js +1 -1
- package/esm/LinearGenomeView/consts.d.ts +2 -0
- package/esm/LinearGenomeView/consts.js +5 -0
- package/esm/LinearGenomeView/headerFit.d.ts +2 -1
- package/esm/LinearGenomeView/headerFit.js +7 -2
- package/esm/LinearGenomeView/index.d.ts +1 -1
- package/esm/LinearGenomeView/keyboardHandler.d.ts +2 -0
- package/esm/LinearGenomeView/keyboardHandler.js +11 -0
- package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
- package/esm/LinearGenomeView/launchKeys.js +15 -5
- package/esm/LinearGenomeView/lazyDialogs.d.ts +7 -0
- package/esm/LinearGenomeView/lazyDialogs.js +2 -0
- package/esm/LinearGenomeView/menuItems.d.ts +28 -16
- package/esm/LinearGenomeView/menuItems.js +213 -85
- package/esm/LinearGenomeView/model.d.ts +367 -199
- package/esm/LinearGenomeView/model.js +302 -143
- package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
- package/esm/LinearGenomeView/showRegionsWithUndo.js +7 -1
- package/esm/LinearGenomeView/svgcomponents/SVGCloseUpFrame.d.ts +5 -0
- package/esm/LinearGenomeView/svgcomponents/SVGCloseUpFrame.js +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +3 -4
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +95 -24
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +4 -5
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +13 -4
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +4 -4
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +1 -1
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +52 -63
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +8 -6
- package/esm/LinearGenomeView/svgcomponents/util.js +37 -16
- package/esm/LinearGenomeView/types.d.ts +5 -4
- package/esm/LinearGenomeView/util.d.ts +20 -37
- package/esm/LinearGenomeView/util.js +58 -141
- package/esm/displayKitTests/perRegionTestEnv.d.ts +64 -45
- package/esm/displayKitTests/perRegionTestEnv.js +6 -6
- package/esm/index.d.ts +9 -67
- package/esm/index.js +6 -22
- package/esm/searchUtils.d.ts +2 -3
- package/esm/searchUtils.js +2 -2
- package/package.json +7 -7
- package/esm/lazyPluginExports.d.ts +0 -23
- package/esm/lazyPluginExports.js +0 -36
|
@@ -1,41 +1,37 @@
|
|
|
1
|
-
import { TrackSelector as TrackSelectorIcon } from '@jbrowse/core/ui/Icons';
|
|
1
|
+
import { Highlighter, TrackSelector as TrackSelectorIcon, } from '@jbrowse/core/ui/Icons';
|
|
2
2
|
import { radioItems } from '@jbrowse/core/ui/menuItems';
|
|
3
3
|
import { assembleLocStrings, getDialogHost, getSession, isSessionWithAddSessionTrack, toLocale, } from '@jbrowse/core/util';
|
|
4
4
|
import { basePaintedAt } from '@jbrowse/core/util/Base1DUtils';
|
|
5
5
|
import { copyText } from '@jbrowse/core/util/copyText';
|
|
6
6
|
import CenterFocusStrongIcon from '@mui/icons-material/CenterFocusStrong';
|
|
7
7
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
|
8
|
-
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
|
9
|
-
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
10
8
|
import FolderOpenIcon from '@mui/icons-material/FolderOpen';
|
|
11
9
|
import LaunchIcon from '@mui/icons-material/Launch';
|
|
10
|
+
import LayersIcon from '@mui/icons-material/Layers';
|
|
11
|
+
import LayersClearIcon from '@mui/icons-material/LayersClear';
|
|
12
12
|
import MenuOpenIcon from '@mui/icons-material/MenuOpen';
|
|
13
|
-
import PaletteIcon from '@mui/icons-material/Palette';
|
|
14
13
|
import PhotoCameraIcon from '@mui/icons-material/PhotoCamera';
|
|
15
14
|
import SearchIcon from '@mui/icons-material/Search';
|
|
16
15
|
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
|
17
16
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
|
18
17
|
import ZoomInIcon from '@mui/icons-material/ZoomIn';
|
|
19
|
-
import {
|
|
18
|
+
import { closeUpHost } from './closeUps.js';
|
|
19
|
+
import { AddCloseUpDialog, ExportSvgDialog, GetSequenceDialog, RegionWidthEditorDialog, ReturnToImportFormDialog, SequenceSearchDialog, } from './lazyDialogs.js';
|
|
20
20
|
const TRACK_LABEL_OPTIONS = [
|
|
21
21
|
{ value: 'overlapping', label: 'Overlapping' },
|
|
22
22
|
{ value: 'offset', label: 'Offset' },
|
|
23
23
|
{ value: 'hidden', label: 'Hidden' },
|
|
24
24
|
];
|
|
25
25
|
/**
|
|
26
|
-
* Zoom all the way out
|
|
27
|
-
*
|
|
28
|
-
* only one of the two that survives `hideHeader`.
|
|
29
|
-
*
|
|
30
|
-
* The zoom menu earns it on the merits: this is the bottom of the same "Zoom
|
|
31
|
-
* out 100x" ladder, and it is where someone already zooming looks.
|
|
26
|
+
* Zoom all the way out — the bottom of the same "Zoom out 100x" ladder it sits
|
|
27
|
+
* under.
|
|
32
28
|
*
|
|
33
29
|
* The label is the import form's button text verbatim (`ImportForm.tsx`), which
|
|
34
30
|
* is where most people meet the phrase. No icon: the four-arrows glyph it
|
|
35
31
|
* carried reads as "fullscreen", and nothing else names the same gesture, so a
|
|
36
32
|
* substitute would be decoration rather than a distinction.
|
|
37
33
|
*/
|
|
38
|
-
|
|
34
|
+
function showAllRegionsMenuItem(self) {
|
|
39
35
|
return {
|
|
40
36
|
label: 'Show all regions in assembly',
|
|
41
37
|
onClick: () => {
|
|
@@ -44,33 +40,71 @@ export function showAllRegionsMenuItem(self) {
|
|
|
44
40
|
};
|
|
45
41
|
}
|
|
46
42
|
/**
|
|
47
|
-
*
|
|
43
|
+
* The zoom ladder, shared by the header's zoom button and the view menu's
|
|
44
|
+
* "Zoom" — one definition so the two cannot drift, and the view menu is the
|
|
45
|
+
* only one of the two that survives `hideHeader`.
|
|
46
|
+
*/
|
|
47
|
+
export function zoomMenuItems(self) {
|
|
48
|
+
return [
|
|
49
|
+
...[10, 50, 100].map(r => ({
|
|
50
|
+
label: `Zoom in ${r}x`,
|
|
51
|
+
onClick: () => {
|
|
52
|
+
self.zoom(self.bpPerPx / r);
|
|
53
|
+
},
|
|
54
|
+
})),
|
|
55
|
+
...[10, 50, 100].map(r => ({
|
|
56
|
+
label: `Zoom out ${r}x`,
|
|
57
|
+
onClick: () => {
|
|
58
|
+
self.zoom(self.bpPerPx * r);
|
|
59
|
+
},
|
|
60
|
+
})),
|
|
61
|
+
showAllRegionsMenuItem(self),
|
|
62
|
+
{
|
|
63
|
+
label: 'Custom zoom',
|
|
64
|
+
onClick: () => {
|
|
65
|
+
getDialogHost(self).queueDialog(handleClose => [
|
|
66
|
+
RegionWidthEditorDialog,
|
|
67
|
+
{ model: self, handleClose },
|
|
68
|
+
]);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Build the main view menu items. A row stacked in another view has no import
|
|
75
|
+
* form of its own, so only a top-level view offers the way back to one.
|
|
76
|
+
*
|
|
77
|
+
* Four actions, a Zoom group and a Show group. The four are what people open
|
|
78
|
+
* this menu to do — pick tracks, take a picture, search the sequence, start
|
|
79
|
+
* over — and the once-a-session settings that used to sit beside them are a
|
|
80
|
+
* popup away instead of in front of every reader every time.
|
|
48
81
|
*/
|
|
49
82
|
export function buildMenuItems(self) {
|
|
50
83
|
if (!self.hasDisplayedRegions) {
|
|
51
84
|
return [];
|
|
52
85
|
}
|
|
53
86
|
const session = getSession(self);
|
|
87
|
+
const host = closeUpHost(self);
|
|
54
88
|
const menuItems = [
|
|
55
89
|
{
|
|
56
|
-
label:
|
|
57
|
-
icon: self.scalebarOnly ? ExpandMoreIcon : ExpandLessIcon,
|
|
90
|
+
label: 'Open track selector',
|
|
58
91
|
onClick: () => {
|
|
59
|
-
self.
|
|
92
|
+
self.activateTrackSelector();
|
|
60
93
|
},
|
|
94
|
+
icon: TrackSelectorIcon,
|
|
61
95
|
},
|
|
62
96
|
{
|
|
63
|
-
label: '
|
|
97
|
+
label: 'Export SVG',
|
|
98
|
+
icon: PhotoCameraIcon,
|
|
64
99
|
onClick: () => {
|
|
65
100
|
session.queueDialog(handleClose => [
|
|
66
|
-
|
|
101
|
+
ExportSvgDialog,
|
|
67
102
|
{
|
|
68
103
|
model: self,
|
|
69
104
|
handleClose,
|
|
70
105
|
},
|
|
71
106
|
]);
|
|
72
107
|
},
|
|
73
|
-
icon: FolderOpenIcon,
|
|
74
108
|
},
|
|
75
109
|
...(isSessionWithAddSessionTrack(session)
|
|
76
110
|
? [
|
|
@@ -89,30 +123,37 @@ export function buildMenuItems(self) {
|
|
|
89
123
|
},
|
|
90
124
|
]
|
|
91
125
|
: []),
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
126
|
+
...(self.isTopLevelView
|
|
127
|
+
? [
|
|
128
|
+
{
|
|
129
|
+
label: 'Return to import form',
|
|
130
|
+
onClick: () => {
|
|
131
|
+
session.queueDialog(handleClose => [
|
|
132
|
+
ReturnToImportFormDialog,
|
|
133
|
+
{
|
|
134
|
+
model: self,
|
|
135
|
+
handleClose,
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
101
138
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
139
|
+
icon: FolderOpenIcon,
|
|
140
|
+
},
|
|
141
|
+
]
|
|
142
|
+
: []),
|
|
143
|
+
// The one row a close-up adds, and the only one of its own it needs.
|
|
144
|
+
// Top-level rather than under Zoom: a close-up is a second panel on the
|
|
145
|
+
// page, and taking a panel away is not a zoom.
|
|
146
|
+
...(host
|
|
147
|
+
? [
|
|
148
|
+
{
|
|
149
|
+
label: 'Remove close-up view',
|
|
150
|
+
icon: LayersClearIcon,
|
|
151
|
+
onClick: () => {
|
|
152
|
+
host.removeCloseUp(self);
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
]
|
|
156
|
+
: []),
|
|
116
157
|
{
|
|
117
158
|
label: 'Horizontally flip',
|
|
118
159
|
icon: SyncAltIcon,
|
|
@@ -121,24 +162,25 @@ export function buildMenuItems(self) {
|
|
|
121
162
|
},
|
|
122
163
|
},
|
|
123
164
|
{
|
|
124
|
-
label: '
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
icon: PaletteIcon,
|
|
128
|
-
onClick: () => {
|
|
129
|
-
self.setColorByCDS(!self.colorByCDS);
|
|
130
|
-
},
|
|
165
|
+
label: 'Zoom',
|
|
166
|
+
icon: ZoomInIcon,
|
|
167
|
+
subMenu: zoomMenuItems(self),
|
|
131
168
|
},
|
|
132
169
|
{
|
|
133
170
|
label: 'Show...',
|
|
134
171
|
icon: VisibilityIcon,
|
|
135
172
|
subMenu: [
|
|
173
|
+
// Collapsing a row is about height and what it hides is the tracks, so
|
|
174
|
+
// it is the widest of the visibility answers and heads them. A checkbox
|
|
175
|
+
// rather than the pair of labels it was: "Collapse to ruler" turning
|
|
176
|
+
// into "Expand tracks" names the current state nowhere, and among
|
|
177
|
+
// checkboxes there is no room for the trick anyway.
|
|
136
178
|
{
|
|
137
|
-
label: '
|
|
179
|
+
label: 'Collapse to ruler',
|
|
138
180
|
type: 'checkbox',
|
|
139
|
-
checked: self.
|
|
181
|
+
checked: self.scalebarOnly,
|
|
140
182
|
onClick: () => {
|
|
141
|
-
self.
|
|
183
|
+
self.setScalebarOnly(!self.scalebarOnly);
|
|
142
184
|
},
|
|
143
185
|
},
|
|
144
186
|
{
|
|
@@ -154,21 +196,49 @@ export function buildMenuItems(self) {
|
|
|
154
196
|
},
|
|
155
197
|
},
|
|
156
198
|
{
|
|
157
|
-
label: 'Show
|
|
199
|
+
label: 'Show header overview',
|
|
158
200
|
type: 'checkbox',
|
|
159
|
-
checked: self.
|
|
201
|
+
checked: !self.hideHeaderOverview,
|
|
160
202
|
onClick: () => {
|
|
161
|
-
self.
|
|
203
|
+
self.setHideHeaderOverview(!self.hideHeaderOverview);
|
|
204
|
+
},
|
|
205
|
+
disabled: self.hideHeader,
|
|
206
|
+
},
|
|
207
|
+
...(self.canShowCytobands
|
|
208
|
+
? [
|
|
209
|
+
{
|
|
210
|
+
label: 'Show ideogram',
|
|
211
|
+
type: 'checkbox',
|
|
212
|
+
checked: self.showCytobands,
|
|
213
|
+
onClick: () => {
|
|
214
|
+
self.setShowCytobands(!self.showCytobands);
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
]
|
|
218
|
+
: []),
|
|
219
|
+
{
|
|
220
|
+
label: 'Show center line',
|
|
221
|
+
type: 'checkbox',
|
|
222
|
+
checked: self.showCenterLine,
|
|
223
|
+
onClick: () => {
|
|
224
|
+
self.setShowCenterLine(!self.showCenterLine);
|
|
162
225
|
},
|
|
163
226
|
},
|
|
164
227
|
{
|
|
165
|
-
label: 'Show
|
|
228
|
+
label: 'Show guidelines',
|
|
166
229
|
type: 'checkbox',
|
|
167
|
-
checked:
|
|
230
|
+
checked: self.showGridlines,
|
|
168
231
|
onClick: () => {
|
|
169
|
-
self.
|
|
232
|
+
self.setShowGridlines(!self.showGridlines);
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
label: 'Show track outlines',
|
|
237
|
+
type: 'checkbox',
|
|
238
|
+
checked: self.showTrackOutlines,
|
|
239
|
+
onClick: () => {
|
|
240
|
+
self.setShowTrackOutlines(!self.showTrackOutlines);
|
|
170
241
|
},
|
|
171
|
-
disabled: self.hideHeader,
|
|
172
242
|
},
|
|
173
243
|
{
|
|
174
244
|
label: 'Show no tracks active button',
|
|
@@ -178,36 +248,43 @@ export function buildMenuItems(self) {
|
|
|
178
248
|
self.setHideNoTracksActive(!self.hideNoTracksActive);
|
|
179
249
|
},
|
|
180
250
|
},
|
|
251
|
+
{ type: 'subHeader', label: 'Highlights' },
|
|
181
252
|
{
|
|
182
|
-
|
|
183
|
-
// color-by-CDS one above it, which is the reason it moved here
|
|
184
|
-
label: 'Show amino acids when zoomed in',
|
|
253
|
+
label: 'Show highlights',
|
|
185
254
|
type: 'checkbox',
|
|
186
|
-
checked:
|
|
255
|
+
checked: session.highlightsVisible,
|
|
187
256
|
onClick: () => {
|
|
188
|
-
|
|
257
|
+
session.setHighlightsVisible(!session.highlightsVisible);
|
|
189
258
|
},
|
|
190
259
|
},
|
|
191
260
|
{
|
|
192
|
-
label: 'Show
|
|
261
|
+
label: 'Show highlight labels',
|
|
193
262
|
type: 'checkbox',
|
|
194
|
-
checked: self.
|
|
263
|
+
checked: self.labelsVisible,
|
|
195
264
|
onClick: () => {
|
|
196
|
-
self.
|
|
265
|
+
self.setLabelsVisible(!self.labelsVisible);
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
// The two answers to what the sequence draws as: one colours the
|
|
269
|
+
// codons, the other spells them out. Both lost the palette icon they
|
|
270
|
+
// used to carry — nothing else in this list has one.
|
|
271
|
+
{ type: 'subHeader', label: 'Sequence' },
|
|
272
|
+
{
|
|
273
|
+
label: 'Color CDS by reading frame',
|
|
274
|
+
type: 'checkbox',
|
|
275
|
+
checked: self.colorByCDS,
|
|
276
|
+
onClick: () => {
|
|
277
|
+
self.setColorByCDS(!self.colorByCDS);
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
label: 'Show amino acids when zoomed in',
|
|
282
|
+
type: 'checkbox',
|
|
283
|
+
checked: self.showAminoAcids,
|
|
284
|
+
onClick: () => {
|
|
285
|
+
self.setShowAminoAcids(!self.showAminoAcids);
|
|
197
286
|
},
|
|
198
287
|
},
|
|
199
|
-
...(self.canShowCytobands
|
|
200
|
-
? [
|
|
201
|
-
{
|
|
202
|
-
label: 'Show ideogram',
|
|
203
|
-
type: 'checkbox',
|
|
204
|
-
checked: self.showCytobands,
|
|
205
|
-
onClick: () => {
|
|
206
|
-
self.setShowCytobands(!self.showCytobands);
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
]
|
|
210
|
-
: []),
|
|
211
288
|
// Where a track's name is drawn, and "Hidden" is one of the three
|
|
212
289
|
// answers, so this is a visibility setting like everything above it.
|
|
213
290
|
// Inline under a subheader rather than in a submenu of its own: it was a
|
|
@@ -225,10 +302,24 @@ export function buildMenuItems(self) {
|
|
|
225
302
|
return menuItems;
|
|
226
303
|
}
|
|
227
304
|
/**
|
|
228
|
-
* Build rubberband selection menu items.
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
305
|
+
* Build rubberband selection menu items. What a selection can open collects
|
|
306
|
+
* under one "Launch" submenu, which sorts last, below any row a plugin appends
|
|
307
|
+
* to the menu itself: a close-up view first, then `launchItems`, the
|
|
308
|
+
* plugin-supplied ones (`rubberBandLaunchMenuItems()`).
|
|
309
|
+
*
|
|
310
|
+
* A close-up is offered from HERE and nowhere else, because a drag is what the
|
|
311
|
+
* feature was always asking for and a menu item could not: the close-up shows
|
|
312
|
+
* one span of one place, and this is the gesture that names both. From the view
|
|
313
|
+
* menu it could only guess — a tenth of the middle, which is a span nobody
|
|
314
|
+
* picked.
|
|
315
|
+
*
|
|
316
|
+
* Only a view of its own offers it, which `isTopLevelView` is the whole of. A
|
|
317
|
+
* row of a comparative stack is already part of somebody's figure: the synteny
|
|
318
|
+
* ribbons and the breakpoint split panels are placed against each row's own
|
|
319
|
+
* height, and those views' exports draw one row per view, so a close-up grown
|
|
320
|
+
* there walks the ribbons off their rows and is dropped from the picture
|
|
321
|
+
* without a word. A close-up, living under a view rather than under the
|
|
322
|
+
* session, is not a top-level view either.
|
|
232
323
|
*/
|
|
233
324
|
export function buildRubberBandMenuItems(self, launchItems) {
|
|
234
325
|
// captured once here and used by the items below rather than re-read inside
|
|
@@ -242,6 +333,32 @@ export function buildRubberBandMenuItems(self, launchItems) {
|
|
|
242
333
|
// in ascending order, and a `leftRef === rightRef` test calls a selection
|
|
243
334
|
// crossing a collapsed intron one range when it is two.
|
|
244
335
|
const rangeString = assembleLocStrings(self.getSelectedRegions(leftOffset, rightOffset));
|
|
336
|
+
const launch = [
|
|
337
|
+
...(self.isTopLevelView
|
|
338
|
+
? [
|
|
339
|
+
{
|
|
340
|
+
label: 'Close-up view',
|
|
341
|
+
icon: LayersIcon,
|
|
342
|
+
helpText: 'A zoomed-in copy of this view, opened below its tracks. It stays centred on this view and pans with it.',
|
|
343
|
+
onClick: () => {
|
|
344
|
+
getDialogHost(self).queueDialog(handleClose => [
|
|
345
|
+
AddCloseUpDialog,
|
|
346
|
+
{
|
|
347
|
+
model: self,
|
|
348
|
+
leftOffset,
|
|
349
|
+
rightOffset,
|
|
350
|
+
handleClose: () => {
|
|
351
|
+
handleClose();
|
|
352
|
+
self.setOffsets();
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
]);
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
]
|
|
359
|
+
: []),
|
|
360
|
+
...launchItems,
|
|
361
|
+
];
|
|
245
362
|
return [
|
|
246
363
|
{
|
|
247
364
|
label: 'Zoom to region',
|
|
@@ -275,13 +392,24 @@ export function buildRubberBandMenuItems(self, launchItems) {
|
|
|
275
392
|
void copyText(self, rangeString, 'range');
|
|
276
393
|
},
|
|
277
394
|
},
|
|
278
|
-
|
|
395
|
+
{
|
|
396
|
+
label: 'Highlight region',
|
|
397
|
+
icon: Highlighter,
|
|
398
|
+
onClick: () => {
|
|
399
|
+
const [region] = self.getSelectedRegions(leftOffset, rightOffset);
|
|
400
|
+
if (region) {
|
|
401
|
+
getSession(self).addHighlight(region);
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
...(launch.length
|
|
279
406
|
? [
|
|
280
407
|
{
|
|
281
408
|
label: 'Launch',
|
|
282
409
|
icon: LaunchIcon,
|
|
283
410
|
type: 'subMenu',
|
|
284
|
-
|
|
411
|
+
priority: -1000,
|
|
412
|
+
subMenu: launch,
|
|
285
413
|
},
|
|
286
414
|
]
|
|
287
415
|
: []),
|