Skip to content

Commit

Permalink
feat: indicator scaleWith dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
Tucsky committed Oct 29, 2024
1 parent 5da0b43 commit 70ef817
Show file tree
Hide file tree
Showing 18 changed files with 563 additions and 216 deletions.
16 changes: 7 additions & 9 deletions src/assets/sass/dialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,12 @@
border-radius: 0.75rem 0.75rem 0 0;
cursor: grab;

&-wrapper {
position: relative;
}

#{$self}--contrasted & {
border-bottom: 0 !important;
padding-bottom: 0;
background-color: var(--theme-base-o25);
}

Expand All @@ -153,10 +156,11 @@
}

&__subheader {
position: relative;
z-index: 1;

#{$self}--contrasted & {
background-color: var(--theme-base-o25);
padding-top: 0.5rem;
}
}

Expand Down Expand Up @@ -239,13 +243,7 @@

.dialog__close {
text-align: center;
padding: 0.75rem;
margin: -0.75rem -0.75rem -0.75rem 0.75rem;
display: flex;
align-items: center;
justify-content: center;
align-self: stretch;
border-radius: 0 $border-radius-base 0 0;
margin: 0 -0.5rem 0 0.5rem;
color: var(--theme-color-100);

&:hover {
Expand Down
110 changes: 19 additions & 91 deletions src/components/chart/IndicatorsOverlay.vue
Original file line number Diff line number Diff line change
@@ -1,69 +1,11 @@
<template>
<div class="chart-overlay__panel indicators-overlay">
<div class="chart-overlay__content" v-if="value">
<dropdown v-model="dropdownTrigger">
<button
type="button"
class="dropdown-item"
@click="editIndicator(selectedIndicator)"
>
<i class="icon-edit"></i>
<span>Edit</span>
</button>
<button
type="button"
class="dropdown-item"
@click="resizeIndicator(selectedIndicator)"
>
<i class="icon-resize-height"></i>
<span>Resize</span>
</button>
<button
type="button"
class="dropdown-item"
@click="duplicateIndicator(selectedIndicator)"
>
<i class="icon-copy-paste"></i>
<span>Duplicate</span>
</button>
<button
type="button"
class="dropdown-item"
@click="downloadIndicator(selectedIndicator)"
>
<i class="icon-download"></i>
<span>Download</span>
</button>
<button
type="button"
class="dropdown-item"
@click="setIndicatorOrder(selectedIndicator, 0)"
v-if="selectedIndicatorIsFront"
>
<i class="icon-up"></i>
<span>Send to back</span>
</button>
<button
v-else
type="button"
class="dropdown-item"
@click="
setIndicatorOrder(selectedIndicator, indicatorOrder.length - 1)
"
>
<i class="icon-down -lower"></i>
<span>Bring to front</span>
</button>
<div class="dropdown-divider"></div>
<button
type="button"
class="dropdown-item"
@click="removeIndicator(selectedIndicator)"
>
<i class="icon-trash"></i>
<span>Remove</span>
</button>
</dropdown>
<IndicatorDropdown
v-model="dropdownTrigger"
:indicator-id="indicatorId"
:pane-id="paneId"
/>
<IndicatorControl
v-for="id in indicatorOrder"
:key="id"
Expand Down Expand Up @@ -93,11 +35,13 @@ import { ChartPaneState } from '../../store/panesSettings/chart'
import dialogService from '../../services/dialogService'
import IndicatorControl from '@/components/chart/IndicatorControl.vue'
import IndicatorDropdown from '@/components/indicators/IndicatorDropdown.vue'
@Component({
name: 'IndicatorsOverlay',
components: {
IndicatorControl
IndicatorControl,
IndicatorDropdown
},
props: {
paneId: {
Expand All @@ -114,8 +58,7 @@ export default class IndicatorsOverlay extends Vue {
private value: boolean
dropdownTrigger: HTMLElement = null
selectedIndicator: string = null
selectedIndicatorIsFront: boolean = null
indicatorId: string = null
sorting: {
id: string
height: number
Expand Down Expand Up @@ -151,18 +94,14 @@ export default class IndicatorsOverlay extends Vue {
toggleDropdown(event?: Event, id?: string) {
if (
event &&
(!this.dropdownTrigger ||
!this.selectedIndicator ||
this.selectedIndicator !== id)
(!this.dropdownTrigger || !this.indicatorId || this.indicatorId !== id)
) {
const triggerElement = event.currentTarget as HTMLElement
this.indicatorId = id
this.dropdownTrigger = triggerElement
this.selectedIndicator = id
this.selectedIndicatorIsFront =
this.indicatorOrder.indexOf(id) === this.indicatorOrder.length - 1
} else {
this.dropdownTrigger = null
this.selectedIndicator = null
this.indicatorId = null
}
}
Expand All @@ -175,22 +114,6 @@ export default class IndicatorsOverlay extends Vue {
this.dropdownTrigger = null
}
removeIndicator(indicatorId: string) {
this.$store.dispatch(this.paneId + '/removeIndicator', { id: indicatorId })
}
resizeIndicator(indicatorId: string) {
this.$store.commit(this.paneId + '/TOGGLE_LAYOUTING', indicatorId)
}
duplicateIndicator(indicatorId: string) {
this.$store.dispatch(this.paneId + '/duplicateIndicator', indicatorId)
}
downloadIndicator(indicatorId: string) {
this.$store.dispatch(this.paneId + '/downloadIndicator', indicatorId)
}
async addIndicator() {
dialogService.open(
(await import('@/components/indicators/IndicatorLibraryDialog.vue'))
Expand All @@ -217,9 +140,14 @@ export default class IndicatorsOverlay extends Vue {
case 'menu':
return this.toggleDropdown(event, indicatorId)
case 'remove':
return this.removeIndicator(indicatorId)
return this.$store.dispatch(this.paneId + '/removeIndicator', {
id: indicatorId
})
case 'resize':
return this.resizeIndicator(indicatorId)
return this.$store.commit(
this.paneId + '/TOGGLE_LAYOUTING',
indicatorId
)
}
return this.editIndicator(indicatorId)
Expand Down
2 changes: 1 addition & 1 deletion src/components/chart/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ export function getChartScales(
return scales
},
{
...{ [indicatorId]: `Own scale 📍` },
...{ [indicatorId]: `Own scale` },
left: 'Left ←',
right: 'Right →'
}
Expand Down
45 changes: 45 additions & 0 deletions src/components/framework/BlobImage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<img v-if="imageObjectUrl" :src="imageObjectUrl" />
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
@Component({
name: 'BlobImage',
props: {
value: {
type: String,
required: true
}
}
})
export default class BlobImage extends Vue {
value: Blob | File
imageObjectUrl: string = null
@Watch('value', { immediate: true })
onBlobChange() {
this.loadBlob()
}
beforeDestroy() {
this.clearBlob()
}
loadBlob() {
this.clearBlob()
if (this.value instanceof Blob || (this.value as any) instanceof File) {
this.imageObjectUrl = URL.createObjectURL(this.value)
}
}
clearBlob() {
if (this.imageObjectUrl) {
URL.revokeObjectURL(this.imageObjectUrl)
this.imageObjectUrl = null
}
}
}
</script>
1 change: 1 addition & 0 deletions src/components/framework/Dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@mousedown="handleDrag"
@touchstart="handleDrag"
>
<slot name="cover"></slot>
<div class="dialog__header">
<slot name="header"></slot>
<button
Expand Down
28 changes: 28 additions & 0 deletions src/components/framework/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ export default {
margin: 0.5em 0;
position: relative;
&:first-child {
margin-top: 0.75rem;
}
&[data-label]:before {
content: attr(data-label);
position: absolute;
Expand Down Expand Up @@ -452,11 +456,21 @@ export default {
box-shadow: none;
line-height: 1;
cursor: pointer;
text-decoration: none;
&:hover {
background-color: var(--theme-color-o10);
}
&--active {
font-weight: 600;
background-color: var(--theme-background-100);
&:hover {
background-color: var(--theme-background-100);
}
}
&--group {
padding: 0;
Expand All @@ -465,12 +479,26 @@ export default {
}
}
&--narrow {
padding-block: 0.375rem;
}
&__subtitle {
opacity: 0.5;
font-size: 0.875em;
margin-top: 0.25em;
}
&__emoji {
width: 1em;
padding-right: 1em;
font-size: 0.75em;
}
&__icon {
padding: 0 0.375rem;
}
&--space-between {
justify-content: space-between;
}
Expand Down
Loading

0 comments on commit 70ef817

Please sign in to comment.