Changeset 35955 for main/trunk


Ignore:
Timestamp:
2022-01-11T13:16:54+13:00 (2 years ago)
Author:
cstephen
Message:

Improve controls display and implement spellchecking control

Location:
main/trunk/model-interfaces-dev/atea/ocr/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/model-interfaces-dev/atea/ocr/src/components/MainPage.vue

    r35825 r35955  
    66import { SnackController } from "./Snackbar.vue"
    77import OcrService, { OcrOptions } from "../js/OcrService"
    8 import { log } from "../js/Util";
     8import Util, { log } from "../js/Util";
    99
    1010const ocrService = new OcrService();
     
    3131
    3232            showEditor: false,
    33             ocrTextEdited: false
     33            ocrTextEdited: false,
     34            enableMagnifier: false,
     35            magnifierZoom: 1.5,
     36            enableSpellcheck: false
    3437        }
    3538    },
     
    5558            const blob = new Blob([ arrayView ], { type: this.imageType });
    5659            this.imageUrl = URL.createObjectURL(blob);
     60        },
     61        enableMagnifier(newValue) {
     62            localStorage.setItem("enableMagnifier", newValue);
     63        },
     64        magnifierZoom(newValue) {
     65            localStorage.setItem("magnifierZoom", newValue);
     66            this.enableMagnifier = true;
     67        },
     68        enableSpellcheck(newValue) {
     69            localStorage.setItem("enableSpellcheck", newValue);
    5770        }
    5871    },
     
    193206            saveAs(blob, fileName);
    194207        }
     208    },
     209    beforeMount() {
     210        this.enableMagnifier = localStorage.getItem("enableMagnifier") === "true";
     211        this.magnifierZoom = parseFloat(localStorage.getItem("magnifierZoom") ?? "1.5");
     212
     213        const enableSpellcheck = localStorage.getItem("enableSpellcheck");
     214        if (enableSpellcheck) {
     215            this.enableSpellcheck = enableSpellcheck === "true";
     216        }
     217        else {
     218            this.enableSpellcheck = Util.getNavigatorLanguage().startsWith("mi");
     219        }
    195220    }
    196221}
     
    236261            </div>
    237262
    238             <ocr-image-display :imageUrl="imageUrl" :thresholdedImageUrl="thresholdedImageUrl" />
    239 
    240             <textarea class="text-container" v-model="ocrResult" :placeholder="translations.get('MainPage_OCRHint')"
    241                 @input="ocrTextEdited = true" :disabled="!isValidOcrResult || ocrInProgress" autocomplete="off" spellcheck="false"/>
     263            <div class="content-controls">
     264                <div>
     265                    <div class="flex-h">
     266                        <input id="chk-enable-magnifier" type="checkbox" v-model="enableMagnifier" />
     267                        <label for="chk-enable-magnifier">{{ translations.get('MainPage_EnableMagnifier') }}</label>
     268                    </div>
     269
     270                    <div class="flex-h" style="margin-top: 0.5em">
     271                        <span>1.5x</span>
     272                        <input type="range" min="1.5" max="3" step="0.1" v-model.number="magnifierZoom" />
     273                        <span>3x</span>
     274                    </div>
     275                </div>
     276
     277                <div style="max-width: 450px; word-wrap: normal;">
     278                    <div class="flex-h">
     279                        <input id="chk-show-thresholded-image" type="checkbox" v-model="showThresholdedImage" :disabled="!ocrResult" />
     280                        <label for="chk-show-thresholded-image">{{ translations.get('MainPage_ShowThresholdedImage') }}</label>
     281                    </div>
     282
     283                    <span class="body2">
     284                        {{ translations.get('MainPage_ThresholdedImageDescription') }}
     285                    </span>
     286                </div>
     287
     288                <div class="flex-h">
     289                    <input id="chk-enable-spellcheck" type="checkbox" v-model="enableSpellcheck" />
     290                    <label for="chk-enable-spellcheck">{{ translations.get('MainPage_EnableSpellcheck') }}</label>
     291                </div>
     292            </div>
     293
     294            <div class="main-content-columns">
     295                <ocr-image-display
     296                    :imageUrl="imageUrl"
     297                    :thresholdedImageUrl="thresholdedImageUrl"
     298                    :enableMagnifier="enableMagnifier"
     299                    :magnifierZoom="magnifierZoom"
     300                    :showThresholdedImage="showThresholdedImage" />
     301
     302                <textarea
     303                    class="text-container"
     304                    v-model="ocrResult"
     305                    :placeholder="translations.get('MainPage_OCRHint')"
     306                    @input="ocrTextEdited = true"
     307                    :disabled="!isValidOcrResult || ocrInProgress"
     308                    autocomplete="off"
     309                    :spellcheck="enableSpellcheck"/>
     310            </div>
    242311        </div>
    243312    </div>
     
    303372
    304373.main-area {
    305     display: grid;
    306     grid-template-columns: 1fr 1fr;
    307     grid-template-rows: auto auto 1fr;
     374    display: flex;
     375    flex-direction: column;
    308376    height: 100%;
    309377
     
    324392    display: flex;
    325393    gap: 1em;
    326     grid-column-start: span 2;
    327 }
    328 
    329 .ocr-progress {
    330     grid-column-start: span 2;
     394}
     395
     396.content-controls {
     397    display: flex;
     398    align-items: flex-start;
     399    gap: 1em;
     400}
     401
     402.main-content-columns {
     403    display: grid;
     404    grid-template-columns: 1fr 1fr;
     405    grid-template-rows: 1fr;
     406    flex-grow: 1;
     407    width: 100%;
     408
     409    gap: 1em;
     410    align-items: center;
     411    justify-items: center;
    331412}
    332413</style>
  • main/trunk/model-interfaces-dev/atea/ocr/src/components/OcrImageDisplay.vue

    r35954 r35955  
    66    props: {
    77        imageUrl: String,
    8         thresholdedImageUrl: String
     8        thresholdedImageUrl: String,
     9        enableMagnifier: Boolean,
     10        magnifierZoom: Number,
     11        showThresholdedImage: Boolean
    912    },
    1013    data() {
    1114        return {
    12             showThresholdedImage: false,
    1315            /** @type {DOMRect} */
    14             magnifierBounds: null,
    15             magnifierZoom: 1.5,
    16             showControls: false,
    17             enableMagnifier: false
     16            magnifierBounds: null
    1817        }
    1918    },
     
    146145            }, 100);
    147146        },
    148         magnifierZoom(newValue) {
     147        magnifierZoom() {
    149148            if (this.showThresholdedImage) {
    150149                this.updateMagnifier(this.$refs.thresholdedImage);
     
    153152                this.updateMagnifier(this.$refs.ocrImage);
    154153            }
    155 
    156             localStorage.setItem("magnifierZoom", newValue);
    157         },
    158         enableMagnifier(newValue) {
    159             localStorage.setItem("enableMagnifier", newValue);
    160         }
    161     },
    162     beforeMount() {
    163         this.enableMagnifier = localStorage.getItem("enableMagnifier") === "true";
     154        }
    164155    },
    165156    mounted() {
     
    167158            this.updateMagnifier(this.$refs.ocrImage);
    168159        }, 100);
    169 
    170         this.magnifierZoom = localStorage.getItem("magnifierZoom") ?? "1.5";
    171160    }
    172161}
     
    178167    <img ref="ocrImage" class="ocr-image" :src="imageUrl" />
    179168    <img v-if="showThresholdedImage" ref="thresholdedImage" class="ocr-image" :src="thresholdedImageUrl" />
    180 
    181     <button class="control-tip btn-fab" @click="showControls = !showControls">
    182         <span class="material-icons mdi-l">settings</span>
    183     </button>
    184 
    185     <div v-if="showControls" class="controls card">
    186         <button class="spacer btn-fab">
    187             <span class="material-icons mdi-l">settings</span>
    188         </button>
    189 
    190         <div class="flex-h">
    191             <input id="chk-enable-magnifier" type="checkbox" v-model="enableMagnifier" />
    192             <label for="chk-enable-magnifier">{{ translations.get('OcrImageDisplay_EnableMagnifier') }}</label>
    193         </div>
    194 
    195         <div class="flex-h">
    196             <span>1.5x</span>
    197             <input :disabled="!enableMagnifier" type="range" min="1.5" max="3" step="0.1" v-model="magnifierZoom" />
    198             <span>3x</span>
    199         </div>
    200 
    201         <div v-if="thresholdedImageUrl" class="flex-h">
    202             <input id="chk-show-thresholded-image" type="checkbox" v-model="showThresholdedImage" />
    203             <label for="chk-show-thresholded-image">{{ translations.get('OcrImageDisplay_ShowThresholdedImage') }}</label>
    204         </div>
    205 
    206         <span v-if="thresholdedImageUrl" class="body2">{{ translations.get('OcrImageDisplay_ThresholdedImageDescription') }}</span>
    207     </div>
    208169</div>
    209170</template>
     
    212173.ocr-image-container {
    213174    position: relative;
    214     height: 100%;
    215     width: 100%;
    216 
    217     display: grid;
    218     grid-template-columns: 1fr;
    219     grid-template-rows: 1fr;
    220 
    221     align-items: center;
    222     justify-items: center;
    223175
    224176    &:hover {
     
    247199}
    248200
    249 .control-tip {
    250     position: absolute;
    251     top: 0.5em;
    252     left: 0.5em;
    253 
    254     opacity: 0;
    255     z-index: 3;
    256 }
    257 
    258 .controls {
    259     position: absolute;
    260     left: 0.2em;
    261     top: 0.2em;
    262 
    263     display: flex;
    264     flex-direction: column;
    265     gap: 0.5em;
    266 
    267     transition-duration: var(--transition-duration);
    268     opacity: 0;
    269     z-index: 2;
    270 
    271     .spacer {
    272         visibility: hidden;
    273     }
    274 
    275     span {
    276         grid-column: span 2;
    277     }
    278 }
    279 
    280201.magnifier {
    281202    position: absolute;
     
    290211
    291212    transition: opacity var(--transition-duration);
    292     opacity: 0;
     213    opacity: 0.2;
    293214}
    294215</style>
  • main/trunk/model-interfaces-dev/atea/ocr/src/js/Util.js

    r35734 r35955  
    6868            this.lut[d3 & 0xff] + this.lut[d3 >> 8 & 0xff] + this.lut[d3 >> 16 & 0xff] + this.lut[d3 >> 24 & 0xff];
    6969    }
     70
     71    /**
     72     * Gets the navigator's primary language.
     73     * @returns {String} The primary language code.
     74     */
     75    static getNavigatorLanguage() {
     76        if (navigator.languages && navigator.languages.length) {
     77            return navigator.languages[0];
     78        }
     79
     80        if (navigator.language) {
     81            return navigator.language;
     82        }
     83
     84        // IE Support
     85        return navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage;
     86    }
    7087}
  • main/trunk/model-interfaces-dev/atea/ocr/src/styles/_material.scss

    r35779 r35955  
    222222
    223223    height: 16px;
    224     width: 38px;
     224    max-width: 38px;
     225    min-width: 38px;
    225226    border-radius: 8px;
    226227    display: inline-block;
Note: See TracChangeset for help on using the changeset viewer.