@@ -12,7 +12,6 @@ import NcFormGroup from '@nextcloud/vue/components/NcFormGroup'
1212import NcTextField from ' @nextcloud/vue/components/NcTextField'
1313import IconMinus from ' vue-material-design-icons/Minus.vue'
1414import IconPlus from ' vue-material-design-icons/Plus.vue'
15- import IconRestore from ' vue-material-design-icons/Restore.vue'
1615
1716/** Zoom factor ~0.5..4 */
1817const modelValue = defineModel <number >({ required: true })
@@ -27,24 +26,15 @@ const zoomHint = t('talk_desktop', 'Zoom can be also changed by {key} or mouse w
2726
2827const MIN_STEP = - 6
2928const MAX_STEP = 17
30- const STEPS = Array .from (Array (MAX_STEP - MIN_STEP ), (_ , i ) => i + MIN_STEP )
29+ const STEPS = Array .from (Array (MAX_STEP - MIN_STEP + 1 ), (_ , i ) => i + MIN_STEP )
3130const ZOOM_STEP = 1.2
3231const STEP_FACTOR = ZOOM_STEP ** 0.5
3332const stepToFactor = (step : number ) => STEP_FACTOR ** step
3433const factorToStep = (factor : number ) => Math .log (factor ) / Math .log (STEP_FACTOR )
3534const ZOOM_MIN = stepToFactor (MIN_STEP )
3635const ZOOM_MAX = stepToFactor (MAX_STEP )
3736
38- const showInput = ref (false )
39- const inputInstance = useTemplateRef (' input' )
40- /** Zoom factor in % and limits */
41- const inputValue = computed ({
42- get : () => Math .round (modelValue .value * 100 ),
43- set : (value : number ) => {
44- modelValue .value = isFinite (value ) ? Math .min (Math .max (value / 100 , ZOOM_MIN ), ZOOM_MAX ) : 1
45- },
46- })
47-
37+ /** Zoom factor ~0.5..4 on the range, separate from modelValue to not change the zoom during mouse moving */
4838const rangeValue = ref (0 )
4939watch (modelValue , () => {
5040 rangeValue .value = factorToStep (modelValue .value )
@@ -64,6 +54,19 @@ function onRangeChange(newValue: number) {
6454 }
6555}
6656
57+ const showInput = ref (false )
58+ const inputInstance = useTemplateRef (' input' )
59+ /** Zoom factor in % and limits */
60+ const inputValue = computed ({
61+ get : () => {
62+ console .log (isRangeMouseSliding .value , modelValue .value , rangeValue .value , Math .round (stepToFactor (rangeValue .value ) * 100 ))
63+ return ! isRangeMouseSliding .value ? Math .round (modelValue .value * 100 ) : Math .round (stepToFactor (rangeValue .value ) * 100 )
64+ },
65+ set : (value : number ) => {
66+ modelValue .value = isFinite (value ) ? Math .min (Math .max (value / 100 , ZOOM_MIN ), ZOOM_MAX ) : 1
67+ },
68+ })
69+
6770/**
6871 * Switch to input
6972 */
@@ -81,70 +84,66 @@ async function onShowInput() {
8184 <span v-html =" zoomHint" />
8285 </template >
8386
84- <NcFormBox v-slot =" { itemClass }" >
85- <NcFormBox class =" zoom-box__row" row >
86- <NcButton
87- :aria-label =" t('talk_desktop', 'Zoom out')"
88- class =" zoom-box__start-start"
89- variant =" secondary"
90- style =" flex : 0 1 "
91- @click =" modelValue /= ZOOM_STEP" >
92- <template #icon >
93- <IconMinus :size =" 20" />
94- </template >
95- </NcButton >
96-
97- <input
98- :aria-label =" t('talk_desktop', 'Zoom')"
99- class =" zoom-box__range"
100- type =" range"
101- :min =" MIN_STEP"
102- :max =" MAX_STEP"
103- step =" 1"
104- :list =" stepsDatalistId"
105- :value =" rangeValue"
106- @change =" onRangeChange(($event.target as HTMLInputElement).valueAsNumber)"
107- @mousedown =" isRangeMouseSliding = true"
108- @mouseup =" isRangeMouseSliding = false" >
109- <datalist :id =" stepsDatalistId" >
110- <option v-for =" step in STEPS" :key =" step" :value =" step" />
111- </datalist >
112-
113- <NcButton
114- v-if =" !showInput"
115- class =" zoom-box__edit-button"
116- :aria-description =" t('talk_desktop', 'Edit zoom')"
117- variant =" tertiary"
118- @click =" onShowInput" >
119- {{ inputValue }}%
120- </NcButton >
121- <NcTextField
122- v-else
123- ref =" input"
124- :aria-label =" t('talk_desktop', 'Zoom')"
125- inputmode =" number"
126- class =" zoom-box__edit"
127- :model-value =" inputValue"
128- @change =" inputValue = $event.target.value /* TODO: add lazy modifier support */"
129- @blur =" showInput = false" />
130-
131- <NcButton
132- :aria-label =" t('talk_desktop', 'Zoom in')"
133- class =" zoom-box__start-end"
134- variant =" secondary"
135- @click =" modelValue *= ZOOM_STEP" >
136- <template #icon >
137- <IconPlus :size =" 20" />
138- </template >
139- </NcButton >
140- </NcFormBox >
141-
142- <NcButton :class =" itemClass" wide @click =" modelValue = 1" >
87+ <NcFormBox v-slot =" { itemClass }" class =" zoom-box__row" row >
88+ <NcButton
89+ :class =" itemClass"
90+ variant =" tertiary"
91+ wide
92+ @click =" modelValue = 1" >
93+ {{ t('talk_desktop', 'Reset') }}
94+ </NcButton >
95+
96+ <NcButton
97+ :aria-label =" t('talk_desktop', 'Zoom out')"
98+ :class =" itemClass"
99+ @click =" modelValue /= STEP_FACTOR" >
143100 <template #icon >
144- <IconRestore :size =" 20" />
101+ <IconMinus :size =" 20" />
145102 </template >
146- {{ t('talk_desktop', 'Reset') }}
147103 </NcButton >
104+
105+ <input
106+ v-model =" rangeValue"
107+ :aria-label =" t('talk_desktop', 'Zoom')"
108+ class =" zoom-box__range"
109+ type =" range"
110+ :min =" MIN_STEP"
111+ :max =" MAX_STEP"
112+ step =" 1"
113+ :list =" stepsDatalistId"
114+ @change =" onRangeChange(($event.target as HTMLInputElement).valueAsNumber)"
115+ @mousedown =" isRangeMouseSliding = true"
116+ @mouseup =" isRangeMouseSliding = false" >
117+ <datalist :id =" stepsDatalistId" >
118+ <option v-for =" step in STEPS" :key =" step" :value =" step" />
119+ </datalist >
120+
121+ <NcButton
122+ :aria-label =" t('talk_desktop', 'Zoom in')"
123+ :class =" itemClass"
124+ @click =" modelValue *= STEP_FACTOR" >
125+ <template #icon >
126+ <IconPlus :size =" 20" />
127+ </template >
128+ </NcButton >
129+
130+ <NcButton
131+ v-if =" !showInput"
132+ class =" zoom-box__edit-button"
133+ :aria-description =" t('talk_desktop', 'Edit zoom')"
134+ variant =" tertiary"
135+ @click =" onShowInput" >
136+ {{ inputValue }}%
137+ </NcButton >
138+ <NcTextField
139+ v-else
140+ ref =" input"
141+ :aria-label =" t('talk_desktop', 'Zoom')"
142+ inputmode =" number"
143+ class =" zoom-box__edit"
144+ :model-value =" inputValue"
145+ @change =" inputValue = $event.target.value /* TODO: add lazy modifier support */"
146+ @blur =" showInput = false" />
148147 </NcFormBox >
149148 </NcFormGroup >
150149</template >
@@ -174,31 +173,18 @@ async function onShowInput() {
174173}
175174
176175.zoom-box__row > * {
177- flex : 0 0 ;
176+ flex : 0 0 fit-content ;
178177}
179178
180179.zoom-box__range {
181180 flex : 1 0 ;
182181 margin : 0 ;
183182 height : var (--default-clickable-area );
183+ accent-color : var (--color-primary-element );
184184}
185185
186186.zoom-box__edit ,
187187.zoom-box__edit-button {
188188 flex-basis : 75px ;
189189}
190-
191- .zoom-box__start-start {
192- border-start-start-radius : var (--border-radius-element ) !important ;
193- border-start-end-radius : var (--border-radius-small ) !important ;
194- border-end-start-radius : var (--border-radius-small ) !important ;
195- border-end-end-radius : var (--border-radius-small ) !important ;
196- }
197-
198- .zoom-box__start-end {
199- border-start-start-radius : var (--border-radius-small ) !important ;
200- border-start-end-radius : var (--border-radius-element ) !important ;
201- border-end-start-radius : var (--border-radius-small ) !important ;
202- border-end-end-radius : var (--border-radius-small ) !important ;
203- }
204190 </style >
0 commit comments