Eric Tröbs 4 years ago
parent
commit
2faa9947b5

+ 4 - 0
webui/src/assets/icons/flame.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
+    <path fill-rule="evenodd"
+          d="M7.998 14.5c2.832 0 5-1.98 5-4.5 0-1.463-.68-2.19-1.879-3.383l-.036-.037c-1.013-1.008-2.3-2.29-2.834-4.434-.322.256-.63.579-.864.953-.432.696-.621 1.58-.046 2.73.473.947.67 2.284-.278 3.232-.61.61-1.545.84-2.403.633a2.788 2.788 0 01-1.436-.874A3.21 3.21 0 003 10c0 2.53 2.164 4.5 4.998 4.5zM9.533.753C9.496.34 9.16.009 8.77.146 7.035.75 4.34 3.187 5.997 6.5c.344.689.285 1.218.003 1.5-.419.419-1.54.487-2.04-.832-.173-.454-.659-.762-1.035-.454C2.036 7.44 1.5 8.702 1.5 10c0 3.512 2.998 6 6.498 6s6.5-2.5 6.5-6c0-2.137-1.128-3.26-2.312-4.438-1.19-1.184-2.436-2.425-2.653-4.81z"></path>
+</svg>

+ 29 - 8
webui/src/components/media/annotated-image.vue

@@ -22,7 +22,7 @@
                      @play="videoPlay" @jump="videoJump"/>
     </template>
 
-    <!-- <div style="position: absolute; top: 0.5rem; left: 0.5rem">{{ data }}</div> -->
+    <!-- <div style="position: absolute; top: 0.5rem; left: 0.5rem">{{ extremeClicking }}</div> -->
 
     <annotation-box v-if="current"
                     :image="image"
@@ -51,7 +51,7 @@ import VideoControl from "@/components/media/video-control";
 export default {
   name: "annotated-image",
   components: {VideoControl, AnnotationBox},
-  props: ['data', 'project', 'socket', 'filter'],
+  props: ['data', 'project', 'socket', 'filter', 'extremeClicking'],
   mounted: function () {
     window.addEventListener("resize", this.resizeEvent);
     this.resizeEvent();
@@ -74,6 +74,11 @@ export default {
       };
 
       this.resizeEvent();
+    },
+    extremeClicking: function (newValue) {
+      if (!newValue && this.current) {
+        this.release();
+      }
     }
   },
   data: function () {
@@ -204,13 +209,29 @@ export default {
       return rectangle;
     },
     press: function (event) {
-      this.start = {
-        x: this.getX(event),
-        y: this.getY(event)
-      };
+      const x = this.getX(event);
+      const y = this.getY(event);
+
+      if (this.extremeClicking && this.start) {
+        if (this.current) {
+          const minX = Math.min(x, this.current.x);
+          const maxX = Math.max(x, this.current.x + this.current.w);
+          const minY = Math.min(y, this.current.y);
+          const maxY = Math.max(y, this.current.y + this.current.h);
+
+          this.current = this.buildRectangle(minX, minY, maxX, maxY);
+        } else {
+          this.current = this.buildRectangle(this.start.x, this.start.y, x, y);
+        }
+      } else {
+        this.start = {
+          x: x,
+          y: y
+        };
+      }
     },
     track: function (event) {
-      if (this.start) {
+      if (this.start && !this.extremeClicking) {
         const x = this.getX(event);
         const y = this.getY(event);
 
@@ -218,7 +239,7 @@ export default {
       }
     },
     release: function () {
-      if (this.start) {
+      if (this.start && !this.extremeClicking) {
         if (this.callback)
           this.callback(this.current);
         else

+ 7 - 3
webui/src/components/media/annotated-media-view.vue

@@ -4,7 +4,8 @@
       <annotated-image :data="currentMedia"
                        :project="currentProject"
                        :socket="socket"
-                       :filter="filterValue"/>
+                       :filter="filterValue"
+                       :extremeClicking="extremeClicking"/>
     </div>
 
     <div class="control">
@@ -17,7 +18,9 @@
                      :data="currentMedia"
                      :socket="socket"
                      :filter="filterValue"
-                     @filter="filter"/>
+                     @filter="filter"
+                     :extremeClicking="extremeClicking"
+                     @extremeClicking="extremeClicking = $event"/>
     </div>
 
     <div class="selector" v-if="showMediaSelector">
@@ -43,7 +46,8 @@ export default {
     return {
       current: 0,
       showMediaSelector: true,
-      filterValue: ''
+      filterValue: '',
+      extremeClicking: false
     };
   },
   computed: {

+ 15 - 2
webui/src/components/media/media-control.vue

@@ -69,6 +69,19 @@
       <option :selected="this.filter === 'user'" value="user">User</option>
       <option :selected="this.filter === 'pipeline'" value="pipeline">Pipeline</option>
     </select>
+
+    <button-input type="transparent"
+                  v-if="!extremeClicking && (project.model.supports.includes('bounding-boxes') || project.model.supports.includes('labeled-bounding-boxes'))">
+      <img alt="label" src="@/assets/icons/flame.svg"
+           @touchstart.stop @mousedown.stop
+           @click.stop="$emit('extremeClicking', true)">
+    </button-input>
+
+    <button-input type="transparent" v-if="extremeClicking">
+      <img alt="label" src="@/assets/icons/check.svg"
+           @touchstart.stop @mousedown.stop
+           @click.stop="$emit('extremeClicking', false)">
+    </button-input>
   </div>
 
 </template>
@@ -80,11 +93,11 @@ import ButtonRow from "@/components/base/button-row";
 export default {
   name: "media-control",
   components: {ButtonRow, ButtonInput},
-  props: ['hasPrevious', 'hasNext', 'control', 'data', 'project', 'socket', 'filter'],
+  props: ['hasPrevious', 'hasNext', 'control', 'data', 'project', 'socket', 'filter', 'extremeClicking'],
   data: function () {
     return {
       showLabelSelection: false,
-      showFilterSelection: false,
+      showFilterSelection: false
     }
   },
   computed: {