Browse Source

Specify minimum selected item count for CliMutliMenu

min_selection_count=n can be specify to indicate that at least n
items need to be selected before the selection is accepted.
Feature inspired by python pick.
Sebastian Lohff 1 year ago
parent
commit
24dab5f69b
1 changed files with 21 additions and 4 deletions
  1. 21
    4
      clintermission/climenu.py

+ 21
- 4
clintermission/climenu.py View File

@@ -230,11 +230,18 @@ class CliMenu:
230 230
     def _register_extra_kb_cbs(self, kb):
231 231
         pass
232 232
 
233
-    def _run(self):
233
+    def _preflight(self):
234 234
         if self._initial_pos < 0 or self._initial_pos >= self._item_num:
235 235
             raise ValueError("Initial position {} is out of range, needs to be in range of [0, {})"
236 236
                              .format(self._initial_pos, self._item_num))
237 237
 
238
+    def _accept(self, event):
239
+        self._success = True
240
+        event.app.exit()
241
+
242
+    def _run(self):
243
+        self._preflight()
244
+
238 245
         class MenuColorizer(Processor):
239 246
             def apply_transformation(_self, ti):
240 247
                 return self._transform_line(ti)
@@ -272,8 +279,7 @@ class CliMenu:
272 279
         @self._kb.add('c-m', filter=~is_searching)
273 280
         @self._kb.add('right', filter=~is_searching)
274 281
         def accept(event):
275
-            self._success = True
276
-            event.app.exit()
282
+            self._accept(event)
277 283
 
278 284
         @self._kb.add('c-m', filter=is_searching)
279 285
         def accept_search(event):
@@ -317,8 +323,9 @@ class CliMultiMenu(CliMenu):
317 323
     def set_default_selector_icons(cls, selection_icons):
318 324
         cls.default_selection_icons = selection_icons
319 325
 
320
-    def __init__(self, *args, selection_icons=None, **kwargs):
326
+    def __init__(self, *args, selection_icons=None, min_selection_count=0, **kwargs):
321 327
         self._multi_selected = []
328
+        self._min_selection_count = min_selection_count
322 329
         self._selection_icons = selection_icons if selection_icons is not None else self.default_selection_icons
323 330
         super().__init__(*args, **kwargs)
324 331
 
@@ -364,6 +371,16 @@ class CliMultiMenu(CliMenu):
364 371
         else:
365 372
             return prefix
366 373
 
374
+    def _preflight(self):
375
+        super()._preflight()
376
+        if self._min_selection_count > self._item_num:
377
+            raise ValueError("A minimum of {} items was requested for successful selection but only {} exist"
378
+                             .format(self._min_selection_count, self._item_num))
379
+
380
+    def _accept(self, event):
381
+        if len(self._multi_selected) >= self._min_selection_count:
382
+            super()._accept(event)
383
+
367 384
 
368 385
 def cli_select_item(options, header=None, abort_exc=ValueError, abort_text="Selection aborted.", style=None,
369 386
                     return_single=True):

Loading…
Cancel
Save