listpick 0.1.13.55__py3-none-any.whl → 0.1.13.57__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
listpick/listpick_app.py CHANGED
@@ -140,7 +140,6 @@ class Picker:
140
140
  footer_string_refresh_function: Optional[Callable] = None,
141
141
  footer_timer: float=1,
142
142
  get_footer_string_startup=False,
143
- unicode_char_width: bool = True,
144
143
 
145
144
  colours_start: int =0,
146
145
  colours_end: int =-1,
@@ -257,7 +256,7 @@ class Picker:
257
256
  self.footer_string_refresh_function = footer_string_refresh_function
258
257
  self.footer_timer = footer_timer
259
258
  self.get_footer_string_startup = get_footer_string_startup,
260
- self.unicode_char_width = unicode_char_width
259
+
261
260
 
262
261
 
263
262
  self.colours_start = colours_start
@@ -313,16 +312,16 @@ class Picker:
313
312
  self.debug_level = debug_level
314
313
 
315
314
 
315
+
316
+
316
317
  self.initialise_picker_state(reset_colours=self.reset_colours)
317
318
 
318
319
 
319
320
  # Note: We have to set the footer after initialising the picker state so that the footer can use the get_function_data method
320
- # self.footer_options = [StandardFooter(self.stdscr, colours_start, self.get_function_data), CompactFooter(self.stdscr, colours_start, self.get_function_data), NoFooter(self.stdscr, colours_start, self.get_function_data)]
321
- self.footer_options = []
322
- # self.footer = self.footer_options[self.footer_style]
323
-
324
- self.footer = CompactFooter(self.stdscr, colours_start, self.get_function_data)
321
+ self.footer_options = [StandardFooter(self.stdscr, colours_start, self.get_function_data), CompactFooter(self.stdscr, colours_start, self.get_function_data), NoFooter(self.stdscr, colours_start, self.get_function_data)]
322
+ self.footer = self.footer_options[self.footer_style]
325
323
 
324
+ # self.footer = CompactFooter(self.stdscr, colours_start, self.get_function_data)
326
325
 
327
326
 
328
327
  def calculate_section_sizes(self):
@@ -385,6 +384,7 @@ class Picker:
385
384
  def initialise_picker_state(self, reset_colours=False) -> None:
386
385
  """ Initialise state variables for the picker. These are: debugging and colours. """
387
386
 
387
+
388
388
  if curses.has_colors() and self.colours != None:
389
389
  # raise Exception("Terminal does not support color")
390
390
  curses.start_color()
@@ -474,6 +474,7 @@ class Picker:
474
474
 
475
475
  if len(self.indexed_items) > 0 and len(self.indexed_items) >= self.cursor_pos and len(self.indexed_items[0][1]) >= self.id_column:
476
476
  self.cursor_pos_id = self.indexed_items[self.cursor_pos][1][self.id_column]
477
+ self.cursor_pos_prev = self.cursor_pos
477
478
 
478
479
  self.items, self.header = self.refresh_function()
479
480
 
@@ -597,8 +598,6 @@ class Picker:
597
598
  else:
598
599
  self.cursor_pos = 0
599
600
 
600
- # if self.display_infobox:
601
- # self.infobox_picker = self.infobox(self.stdscr, self.infobox_items, self.infobox_title)
602
601
 
603
602
 
604
603
  def move_column(self, direction: int) -> None:
@@ -658,14 +657,15 @@ class Picker:
658
657
  pass
659
658
  self.stdscr.refresh()
660
659
 
661
- def draw_screen_wr(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
662
- """ Try-except wrapper for the draw_screen_() method to prevent crashes when rapidly resizing the terminal. """
660
+ def draw_screen(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
661
+ """ Try-except wrapper for the draw_screen_ function. """
663
662
  try:
664
- self.draw_screen(self.indexed_items, self.highlights, clear=clear)
665
- except:
666
- self.logger.warning(f"draw_screen function error")
663
+ self.draw_screen_(self.indexed_items, self.highlights)
664
+ except Exception as e:
665
+ self.logger.warning(f"self.draw_screen_() error. {e}")
666
+ pass
667
667
 
668
- def draw_screen(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
668
+ def draw_screen_(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
669
669
  """ Draw Picker screen. """
670
670
  self.logger.debug("Draw screen.")
671
671
 
@@ -694,7 +694,7 @@ class Picker:
694
694
  # rows = [v[1] for v in self.indexed_items] if len(self.indexed_items) else self.items
695
695
  # Determine widths based only on the currently displayed indexed rows
696
696
  rows = [v[1] for v in self.indexed_items[start_index:end_index]] if len(self.indexed_items) else self.items
697
- self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
697
+ self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
698
698
  visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
699
699
  visible_columns_total_width = sum(visible_column_widths) + len(self.separator)*(len(visible_column_widths)-1)
700
700
 
@@ -793,10 +793,10 @@ class Picker:
793
793
  else:
794
794
  cell_value = self.indexed_items[row][1][col] + self.separator
795
795
  # cell_value = cell_value[:min(cell_width, cell_max_width)-len(self.separator)]
796
- cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator), self.unicode_char_width)
796
+ cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator))
797
797
  cell_value = cell_value + self.separator
798
798
  # cell_value = cell_value
799
- cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width), self.unicode_char_width)
799
+ cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width))
800
800
  # row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
801
801
  self.stdscr.addstr(y, cell_pos, cell_value, curses.color_pair(self.colours_start+colour_pair_number) | curses.A_BOLD)
802
802
  # Part of the cell is on screen
@@ -838,7 +838,7 @@ class Picker:
838
838
  def draw_highlights(highlights: list[dict], idx: int, y: int, item: tuple[int, list[str]]):
839
839
  self.logger.debug(f"function: draw_highlights()")
840
840
  if len(highlights) == 0: return None
841
- full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
841
+ full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
842
842
  row_str = full_row_str[self.leftmost_char:]
843
843
  for highlight in highlights:
844
844
  if "row" in highlight:
@@ -854,13 +854,13 @@ class Picker:
854
854
  continue
855
855
 
856
856
  elif type(highlight["field"]) == type(0) and highlight["field"] not in self.hidden_columns:
857
- match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False, unicode_char_width=self.unicode_char_width), re.IGNORECASE)
857
+ match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False), re.IGNORECASE)
858
858
  if not match: continue
859
859
  field_start = sum([width for i, width in enumerate(self.column_widths[:highlight["field"]]) if i not in self.hidden_columns]) + sum([1 for i in range(highlight["field"]) if i not in self.hidden_columns])*wcswidth(self.separator)
860
860
 
861
861
  ## We want to search the non-centred values but highlight the centred values.
862
862
  if self.centre_in_cols:
863
- tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols, self.unicode_char_width)
863
+ tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols)
864
864
  field_start += (len(tmp) - len(tmp.lstrip()))
865
865
 
866
866
  highlight_start = field_start + match.start()
@@ -882,11 +882,11 @@ class Picker:
882
882
  item = self.indexed_items[idx]
883
883
  y = idx - start_index + self.top_space
884
884
 
885
- # row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
885
+ row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
886
886
  # row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))
887
- row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
887
+ row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
888
888
  row_str_left_adj = clip_left(row_str_orig, self.leftmost_char)
889
- row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width), self.unicode_char_width)
889
+ row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
890
890
  # row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))[self.leftmost_char:]
891
891
 
892
892
  ## Display the standard row
@@ -899,7 +899,7 @@ class Picker:
899
899
 
900
900
  # Higlight cursor cell and selected cells
901
901
  if self.cell_cursor:
902
- # self.selected_cells_by_row = get_selected_cells_by_row(self.cell_selections)
902
+ self.selected_cells_by_row = get_selected_cells_by_row(self.cell_selections)
903
903
  if item[0] in self.selected_cells_by_row:
904
904
  for j in self.selected_cells_by_row[item[0]]:
905
905
  highlight_cell(idx, j, visible_column_widths, colour_pair_number=25)
@@ -979,8 +979,6 @@ class Picker:
979
979
  else:
980
980
  self.stdscr.addstr(0,w-3,"  ", curses.color_pair(self.colours_start+23) | curses.A_BOLD)
981
981
 
982
- # self.stdscr.refresh()
983
-
984
982
  ## Display footer
985
983
  if self.show_footer:
986
984
  # self.footer = NoFooter(self.stdscr, self.colours_start, self.get_function_data)
@@ -995,77 +993,11 @@ class Picker:
995
993
  self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
996
994
  self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
997
995
 
998
-
999
- self.stdscr.refresh()
1000
-
1001
996
  ## Display infobox
1002
997
  if self.display_infobox:
1003
998
  self.infobox(self.stdscr, message=self.infobox_items, title=self.infobox_title)
1004
999
  # self.stdscr.timeout(2000) # timeout is set to 50 in order to get the infobox to be displayed so here we reset it to 2000
1005
- # self.stdscr.refresh()
1006
1000
 
1007
- # if self.display_infobox:
1008
- # # self.stdscr.refresh()
1009
- # # self.infobox(self.stdscr, message=self.infobox_items, title=self.infobox_title)
1010
- #
1011
- # infobox_width, infobox_height = w//2, 3*h//5
1012
- # infobox_x, infobox_y = w - (infobox_width + 4), 3
1013
- # self.infobox_picker.stdscr.mvwin(infobox_y, infobox_x)
1014
- # self.infobox_picker.stdscr.resize(infobox_height, infobox_width)
1015
- # self.infobox_picker.run()
1016
- # self.infobox_picker.stdscr.noutrefresh()
1017
- # else:
1018
- # # self.stdscr.noutrefresh()
1019
- # pass
1020
- #
1021
- #
1022
- # if not self.display_only:
1023
- # curses.doupdate()
1024
- # self.stdscr.refresh()
1025
- # pass
1026
-
1027
-
1028
- # def infobox___(self, stdscr: curses.window, message: list =[], title: str ="Infobox", colours_end: int = 0, duration: int = 4):
1029
- # """ Display non-interactive infobox window. """
1030
- #
1031
- # self.logger.info(f"function: infobox()")
1032
- # h, w = stdscr.getmaxyx()
1033
- # notification_width, notification_height = w//2, 3*h//5
1034
- # message_width = notification_width-5
1035
- #
1036
- # notification_x, notification_y = w-(notification_width+4), 3
1037
- # if not message: message = "!!"
1038
- # if isinstance(message, str):
1039
- # submenu_items = [" "+message[i*message_width:(i+1)*message_width] for i in range(len(message)//message_width+1)]
1040
- # else:
1041
- # submenu_items = message
1042
- #
1043
- # notification_remap_keys = {
1044
- # curses.KEY_RESIZE: curses.KEY_F5,
1045
- # 27: ord('q')
1046
- # }
1047
- # if len(submenu_items) > notification_height - 2:
1048
- # submenu_items = submenu_items[:notification_height-3] + [f"{'....':^{notification_width}}"]
1049
- # # while True:
1050
- # h, w = stdscr.getmaxyx()
1051
- #
1052
- # submenu_win = self.stdscr.derwin(notification_height, notification_width, 3, w - (notification_width+4))
1053
- # infobox_data = {
1054
- # "items": submenu_items,
1055
- # "colours": notification_colours,
1056
- # "colours_start": self.notification_colours_start,
1057
- # "disabled_keys": [ord('z'), ord('c')],
1058
- # "show_footer": False,
1059
- # "top_gap": 0,
1060
- # "key_remappings": notification_remap_keys,
1061
- # "display_only": True,
1062
- # "hidden_columns": [],
1063
- # "title": title,
1064
- # "reset_colours": False,
1065
- # }
1066
- # submenu_win.noutrefresh()
1067
- # OptionPicker = Picker(submenu_win, **infobox_data)
1068
- # return OptionPicker
1069
1001
 
1070
1002
 
1071
1003
  def infobox(self, stdscr: curses.window, message: str ="", title: str ="Infobox", colours_end: int = 0, duration: int = 4) -> curses.window:
@@ -1208,7 +1140,6 @@ class Picker:
1208
1140
  "debug": self.debug,
1209
1141
  "debug_level": self.debug_level,
1210
1142
  "reset_colours": self.reset_colours,
1211
- "unicode_char_width": self.unicode_char_width,
1212
1143
  }
1213
1144
  return function_data
1214
1145
 
@@ -1307,7 +1238,7 @@ class Picker:
1307
1238
  while True:
1308
1239
  h, w = stdscr.getmaxyx()
1309
1240
 
1310
- choose_opts_widths = get_column_widths(options, unicode_char_width=self.unicode_char_width)
1241
+ choose_opts_widths = get_column_widths(options)
1311
1242
  window_width = min(max(sum(choose_opts_widths) + 6, 50) + 6, w)
1312
1243
  window_height = min(h//2, max(6, len(options)+3))
1313
1244
 
@@ -1462,8 +1393,6 @@ class Picker:
1462
1393
  self.initialise_variables()
1463
1394
  elif setting == "pc":
1464
1395
  self.pin_cursor = not self.pin_cursor
1465
- elif setting == "unicode":
1466
- self.unicode_char_width = not self.unicode_char_width
1467
1396
 
1468
1397
  elif setting.startswith("ft"):
1469
1398
  if len(setting) > 2 and setting[2:].isnumeric():
@@ -1527,6 +1456,7 @@ class Picker:
1527
1456
  self.draw_screen(self.indexed_items, self.highlights)
1528
1457
  self.notification(self.stdscr, message=f"Theme {self.colour_theme_number} applied.")
1529
1458
 
1459
+
1530
1460
  else:
1531
1461
  self.user_settings = ""
1532
1462
  return None
@@ -1550,6 +1480,7 @@ class Picker:
1550
1480
  """ Toggle selection of item at index. """
1551
1481
  self.logger.info(f"function: toggle_item()")
1552
1482
  self.selections[index] = not self.selections[index]
1483
+ self.draw_screen(self.indexed_items, self.highlights)
1553
1484
 
1554
1485
  def select_all(self) -> None:
1555
1486
  """ Select all in indexed_items. """
@@ -1558,8 +1489,8 @@ class Picker:
1558
1489
  self.selections[self.indexed_items[i][0]] = True
1559
1490
  for i in self.cell_selections.keys():
1560
1491
  self.cell_selections[i] = True
1561
- for row in range(len(self.indexed_items)):
1562
- self.selected_cells_by_row[row] = list(range(len(self.indexed_items[row][1])))
1492
+
1493
+ self.draw_screen(self.indexed_items, self.highlights)
1563
1494
 
1564
1495
  def deselect_all(self) -> None:
1565
1496
  """ Deselect all items in indexed_items. """
@@ -1568,7 +1499,7 @@ class Picker:
1568
1499
  self.selections[i] = False
1569
1500
  for i in self.cell_selections.keys():
1570
1501
  self.cell_selections[i] = False
1571
- self.selected_cells_by_row = {}
1502
+ self.draw_screen(self.indexed_items, self.highlights)
1572
1503
 
1573
1504
  def handle_visual_selection(self, selecting:bool = True) -> None:
1574
1505
  """ Toggle visual selection or deselection. """
@@ -1596,22 +1527,15 @@ class Picker:
1596
1527
  xend = max(self.start_selection_col, self.selected_column)
1597
1528
  for i in range(ystart, yend + 1):
1598
1529
  if self.indexed_items[i][0] not in self.unselectable_indices:
1599
- row = self.indexed_items[i][0]
1600
- if row not in self.selected_cells_by_row:
1601
- self.selected_cells_by_row[row] = []
1602
-
1603
- for col in range(xstart, xend+1):
1604
- cell_index = (row, col)
1530
+ for j in range(xstart, xend+1):
1531
+ cell_index = (self.indexed_items[i][0], j)
1605
1532
  self.cell_selections[cell_index] = True
1606
-
1607
- self.selected_cells_by_row[row].append(col)
1608
- # Remove duplicates
1609
- self.selected_cells_by_row[row] = list(set(self.selected_cells_by_row[row]))
1610
-
1611
1533
  self.start_selection = -1
1612
1534
  self.end_selection = -1
1613
1535
  self.is_selecting = False
1614
1536
 
1537
+ self.draw_screen(self.indexed_items, self.highlights)
1538
+
1615
1539
  elif self.is_deselecting:
1616
1540
  self.end_selection = self.indexed_items[self.cursor_pos][0]
1617
1541
  self.end_selection = self.cursor_pos
@@ -1627,22 +1551,14 @@ class Picker:
1627
1551
  xstart = min(self.start_selection_col, self.selected_column)
1628
1552
  xend = max(self.start_selection_col, self.selected_column)
1629
1553
  for i in range(ystart, yend + 1):
1630
- row = self.indexed_items[i][0]
1631
1554
  if self.indexed_items[i][0] not in self.unselectable_indices:
1632
- if row in self.selected_cells_by_row:
1633
- for col in range(xstart, xend+1):
1634
- try:
1635
- self.selected_cells_by_row[row].remove(col)
1636
- except:
1637
- pass
1638
- cell_index = (row, col)
1639
- self.cell_selections[cell_index] = False
1640
- if self.selected_cells_by_row[row] == []:
1641
- del self.selected_cells_by_row[row]
1642
-
1555
+ for j in range(xstart, xend+1):
1556
+ cell_index = (self.indexed_items[i][0], j)
1557
+ self.cell_selections[cell_index] = False
1643
1558
  self.start_selection = -1
1644
1559
  self.end_selection = -1
1645
1560
  self.is_deselecting = False
1561
+ self.draw_screen(self.indexed_items, self.highlights)
1646
1562
 
1647
1563
  def cursor_down(self, count=1) -> bool:
1648
1564
  """ Move cursor down. """
@@ -1760,6 +1676,7 @@ class Picker:
1760
1676
  if not acceptable_data_type:
1761
1677
  break
1762
1678
  if not acceptable_data_type:
1679
+ self.draw_screen(self.indexed_items, self.highlights)
1763
1680
  self.notification(self.stdscr, message="Error pasting data.")
1764
1681
  return None
1765
1682
 
@@ -1870,7 +1787,6 @@ class Picker:
1870
1787
  with self.data_lock:
1871
1788
  self.items, self.header = tmp_items, tmp_header
1872
1789
  self.data_ready = True
1873
- self.draw_screen(self.indexed_items, self.highlights)
1874
1790
 
1875
1791
  def save_input_history(self, file_path: str) -> bool:
1876
1792
  """ Save input field history. Returns True if successful save. """
@@ -1917,7 +1833,7 @@ class Picker:
1917
1833
 
1918
1834
  def get_word_list(self) -> list[str]:
1919
1835
  """ Get a list of all words used in any cell of the picker. Used for completion in search/filter input_field. """
1920
- self.logger.info(f"function: get_word_list()")
1836
+ self.logger.info(f"function: infobox()")
1921
1837
  translator = str.maketrans('', '', string.punctuation)
1922
1838
 
1923
1839
  words = []
@@ -2018,7 +1934,8 @@ class Picker:
2018
1934
 
2019
1935
  if self.display_only:
2020
1936
  self.stdscr.refresh()
2021
- return [], "", {}
1937
+ function_data = self.get_function_data()
1938
+ return [], "", function_data
2022
1939
 
2023
1940
  # Main loop
2024
1941
 
@@ -2039,7 +1956,7 @@ class Picker:
2039
1956
  initial_time = time.time()
2040
1957
 
2041
1958
  self.draw_screen(self.indexed_items, self.highlights, clear=False)
2042
-
1959
+
2043
1960
  self.refreshing_data = False
2044
1961
  self.data_ready = False
2045
1962
 
@@ -2159,7 +2076,6 @@ class Picker:
2159
2076
  options += [["rh", "Toggle row header"]]
2160
2077
  options += [["modes", "Toggle modes"]]
2161
2078
  options += [["ft", "Cycle through footer styles (accepts ft#)"]]
2162
- options += [["unicode", "Toggle b/w using len and wcwidth to calculate char width."]]
2163
2079
  options += [[f"s{i}", f"Select col. {i}"] for i in range(len(self.items[0]))]
2164
2080
  options += [[f"!{i}", f"Toggle col. {i}"] for i in range(len(self.items[0]))]
2165
2081
  options += [["ara", "Add empty row after cursor."]]
@@ -2224,31 +2140,11 @@ class Picker:
2224
2140
  if len(self.indexed_items) > 0:
2225
2141
  item_index = self.indexed_items[self.cursor_pos][0]
2226
2142
  cell_index = (self.indexed_items[self.cursor_pos][0], self.selected_column)
2227
- row, col = cell_index
2228
2143
  selected_count = sum(self.selections.values())
2229
2144
  if self.max_selected == -1 or selected_count >= self.max_selected:
2230
2145
  self.toggle_item(item_index)
2231
2146
 
2232
2147
  self.cell_selections[cell_index] = not self.cell_selections[cell_index]
2233
- ## Set self.selected_cells_by_row
2234
- # If any cells in the current row are selected
2235
- if row in self.selected_cells_by_row:
2236
- # If the current cell is selected then remove it
2237
- if col in self.selected_cells_by_row[row]:
2238
- # If the current cell is the only cell in the row that is selected then remove the row from the dict
2239
- if len(self.selected_cells_by_row[row]) == 1:
2240
-
2241
- del self.selected_cells_by_row[row]
2242
- # else remove only the index of the current cell
2243
- else:
2244
- self.selected_cells_by_row[row].remove(col)
2245
- # If there are cells in the row that are selected then append the current cell to the row
2246
- else:
2247
- self.selected_cells_by_row[row].append(col)
2248
- # Add the a list containing only the current column
2249
- else:
2250
- self.selected_cells_by_row[row] = [col]
2251
-
2252
2148
  self.cursor_down()
2253
2149
  elif self.check_key("select_all", key, self.keys_dict): # Select all (m or ctrl-a)
2254
2150
  self.select_all()
@@ -2264,6 +2160,8 @@ class Picker:
2264
2160
  if new_pos < len(self.indexed_items):
2265
2161
  self.cursor_pos = new_pos
2266
2162
 
2163
+ self.draw_screen(self.indexed_items, self.highlights)
2164
+
2267
2165
  elif self.check_key("cursor_bottom", key, self.keys_dict):
2268
2166
  new_pos = len(self.indexed_items)-1
2269
2167
  while True:
@@ -2271,7 +2169,12 @@ class Picker:
2271
2169
  else: break
2272
2170
  if new_pos < len(self.items) and new_pos >= 0:
2273
2171
  self.cursor_pos = new_pos
2274
-
2172
+ self.draw_screen(self.indexed_items, self.highlights)
2173
+ # current_row = items_per_page - 1
2174
+ # if current_page + 1 == (len(self.indexed_items) + items_per_page - 1) // items_per_page:
2175
+ #
2176
+ # current_row = (len(self.indexed_items) +items_per_page - 1) % items_per_page
2177
+ # self.draw_screen(self.indexed_items, self.highlights)
2275
2178
  elif self.check_key("enter", key, self.keys_dict):
2276
2179
  self.logger.info(f"key_function enter")
2277
2180
  # Print the selected indices if any, otherwise print the current index
@@ -2351,6 +2254,7 @@ class Picker:
2351
2254
  if len(self.indexed_items) > 0:
2352
2255
  current_index = self.indexed_items[self.cursor_pos][0]
2353
2256
  sort_items(self.indexed_items, sort_method=self.columns_sort_method[self.sort_column], sort_column=self.sort_column, sort_reverse=self.sort_reverse[self.sort_column]) # Re-sort self.items based on new column
2257
+ self.draw_screen(self.indexed_items, self.highlights)
2354
2258
  self.cursor_pos = [row[0] for row in self.indexed_items].index(current_index)
2355
2259
  self.logger.info(f"key_function cycle_sort_order. (sort_column, sort_method, sort_reverse) = ({self.sort_column}, {self.columns_sort_method[self.sort_column]}, {self.sort_reverse[self.sort_column]})")
2356
2260
  elif self.check_key("col_select", key, self.keys_dict):
@@ -2374,7 +2278,7 @@ class Picker:
2374
2278
 
2375
2279
  ## Scroll with column select
2376
2280
  rows = self.get_visible_rows()
2377
- self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
2281
+ self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
2378
2282
  visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
2379
2283
  column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
2380
2284
  start_of_cell = sum(visible_column_widths[:self.selected_column])+len(self.separator)*self.selected_column
@@ -2401,7 +2305,8 @@ class Picker:
2401
2305
 
2402
2306
  ## Scroll with column select
2403
2307
  rows = self.get_visible_rows()
2404
- self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
2308
+ self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
2309
+
2405
2310
  visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
2406
2311
  column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
2407
2312
  start_of_cell = sum(visible_column_widths[:self.selected_column])+len(self.separator)*self.selected_column
@@ -2416,13 +2321,18 @@ class Picker:
2416
2321
  self.leftmost_char = start_of_cell
2417
2322
 
2418
2323
  self.leftmost_char = max(0, min(column_set_width - display_width + 5, self.leftmost_char))
2419
-
2324
+ #
2420
2325
  elif self.check_key("scroll_right", key, self.keys_dict):
2421
2326
  self.logger.info(f"key_function scroll_right")
2422
- if len(self.indexed_items):
2423
- row_width = sum(self.column_widths) + len(self.separator)*(len(self.column_widths)-1)
2424
- if row_width-self.leftmost_char >= w-self.startx:
2425
- self.leftmost_char = self.leftmost_char+5
2327
+ rows = self.get_visible_rows()
2328
+ longest_row_str_len = 0
2329
+ for i in range(len(rows)):
2330
+ item = rows[i]
2331
+ row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
2332
+ if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
2333
+
2334
+ if longest_row_str_len >= w-self.startx:
2335
+ self.leftmost_char = self.leftmost_char+5
2426
2336
 
2427
2337
  elif self.check_key("scroll_left", key, self.keys_dict):
2428
2338
  self.logger.info(f"key_function scroll_left")
@@ -2439,7 +2349,7 @@ class Picker:
2439
2349
  rows = self.get_visible_rows()
2440
2350
  for i in range(len(rows)):
2441
2351
  item = rows[i]
2442
- row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols, self.unicode_char_width)
2352
+ row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
2443
2353
  if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
2444
2354
  # for i in range(len(self.indexed_items)):
2445
2355
  # item = self.indexed_items[i]
@@ -2510,37 +2420,44 @@ class Picker:
2510
2420
 
2511
2421
  # elif self.check_key("increase_lines_per_page", key, self.keys_dict):
2512
2422
  # self.items_per_page += 1
2423
+ # self.draw_screen(self.indexed_items, self.highlights)
2513
2424
  # elif self.check_key("decrease_lines_per_page", key, self.keys_dict):
2514
2425
  # if self.items_per_page > 1:
2515
2426
  # self.items_per_page -= 1
2516
-
2427
+ # self.draw_screen(self.indexed_items, self.highlights)
2517
2428
  elif self.check_key("decrease_column_width", key, self.keys_dict):
2518
2429
  self.logger.info(f"key_function decrease_column_width")
2519
2430
  if self.max_column_width > 10:
2520
2431
  self.max_column_width -= 10
2521
2432
  # self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=2)
2433
+ self.draw_screen(self.indexed_items, self.highlights)
2522
2434
  elif self.check_key("increase_column_width", key, self.keys_dict):
2523
2435
  self.logger.info(f"key_function increase_column_width")
2524
2436
  if self.max_column_width < 1000:
2525
2437
  self.max_column_width += 10
2526
2438
  # self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
2439
+ self.draw_screen(self.indexed_items, self.highlights)
2527
2440
  elif self.check_key("visual_selection_toggle", key, self.keys_dict):
2528
2441
  self.logger.info(f"key_function visual_selection_toggle")
2529
2442
  self.handle_visual_selection()
2443
+ self.draw_screen(self.indexed_items, self.highlights)
2530
2444
 
2531
2445
  elif self.check_key("visual_deselection_toggle", key, self.keys_dict):
2532
2446
  self.logger.info(f"key_function visual_deselection_toggle")
2533
2447
  self.handle_visual_selection(selecting=False)
2448
+ self.draw_screen(self.indexed_items, self.highlights)
2534
2449
 
2535
2450
  elif key == curses.KEY_RESIZE: # Terminal resize signal
2536
2451
 
2537
2452
  self.calculate_section_sizes()
2538
- self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w, unicode_char_width=self.unicode_char_width)
2453
+ self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
2539
2454
 
2455
+ self.draw_screen(self.indexed_items, self.highlights)
2540
2456
 
2541
2457
 
2542
2458
  elif self.check_key("filter_input", key, self.keys_dict):
2543
2459
  self.logger.info(f"key_function filter_input")
2460
+ self.draw_screen(self.indexed_items, self.highlights)
2544
2461
  usrtxt = f"{self.filter_query} " if self.filter_query else ""
2545
2462
  field_end_f = lambda: self.stdscr.getmaxyx()[1]-38 if self.show_footer else lambda: self.stdscr.getmaxyx()[1]-3
2546
2463
  if self.show_footer and self.footer.height >= 2: field_end_f = lambda: self.stdscr.getmaxyx()[1]-38
@@ -2585,6 +2502,7 @@ class Picker:
2585
2502
 
2586
2503
  elif self.check_key("search_input", key, self.keys_dict):
2587
2504
  self.logger.info(f"key_function search_input")
2505
+ self.draw_screen(self.indexed_items, self.highlights)
2588
2506
  usrtxt = f"{self.search_query} " if self.search_query else ""
2589
2507
  field_end_f = lambda: self.stdscr.getmaxyx()[1]-38 if self.show_footer else lambda: self.stdscr.getmaxyx()[1]-3
2590
2508
  if self.show_footer and self.footer.height >= 3: field_end_f = lambda: self.stdscr.getmaxyx()[1]-38
@@ -2692,6 +2610,7 @@ class Picker:
2692
2610
  # self.mode_index = 0
2693
2611
  # self.highlights = [highlight for highlight in self.highlights if "type" not in highlight or highlight["type"] != "search" ]
2694
2612
  # continue
2613
+ self.draw_screen(self.indexed_items, self.highlights)
2695
2614
 
2696
2615
  elif self.check_key("opts_input", key, self.keys_dict):
2697
2616
  self.logger.info(f"key_function opts_input")
@@ -2930,12 +2849,9 @@ class Picker:
2930
2849
  self.stdscr.clear()
2931
2850
  self.stdscr.refresh()
2932
2851
  self.initialise_variables()
2852
+ self.draw_screen(self.indexed_items, self.highlights)
2933
2853
 
2934
2854
 
2935
- # The refresh symbol colour is not updated when the data is retrieved so remains white until a key is pressed.
2936
- # if key != -1:
2937
- # self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
2938
-
2939
2855
 
2940
2856
  self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
2941
2857
 
@@ -3177,28 +3093,21 @@ def main() -> None:
3177
3093
  pass
3178
3094
 
3179
3095
  function_data["colour_theme_number"] = 3
3180
- function_data["modes"] = [
3181
- {
3182
- 'filter': '',
3183
- 'sort': 0,
3184
- 'name': 'All',
3185
- },
3186
- {
3187
- 'filter': '--2 miss',
3188
- 'name': 'miss',
3189
- },
3190
- {
3191
- 'filter': '--2 mp4',
3192
- 'name': 'mp4',
3193
- },
3194
- ]
3195
- highlights = [
3196
- {
3197
- "field": 1,
3198
- "match": "a",
3199
- "color": 8,
3200
- }
3201
- ]
3096
+ # function_data["modes"] = [
3097
+ # {
3098
+ # 'filter': '',
3099
+ # 'sort': 0,
3100
+ # 'name': 'All',
3101
+ # },
3102
+ # {
3103
+ # 'filter': '--2 miss',
3104
+ # 'name': 'miss',
3105
+ # },
3106
+ # {
3107
+ # 'filter': '--2 mp4',
3108
+ # 'name': 'mp4',
3109
+ # },
3110
+ # ]
3202
3111
  function_data["cell_cursor"] = True
3203
3112
  function_data["display_modes"] = True
3204
3113
  function_data["centre_in_cols"] = True
@@ -3209,19 +3118,9 @@ def main() -> None:
3209
3118
  function_data["centre_in_terminal_vertical"] = True
3210
3119
  function_data["highlight_full_row"] = True
3211
3120
  function_data["pin_cursor"] = True
3212
- function_data["display_infobox"] = True
3213
- function_data["infobox_items"] = [["1"], ["2"], ["3"]]
3214
- function_data["infobox_title"] = "Title"
3215
- function_data["footer_string"] = "Title"
3216
- function_data["highlights"] = highlights
3217
- function_data["show_footer"] = False
3218
-
3219
-
3220
3121
  # function_data["debug"] = True
3221
3122
  # function_data["debug_level"] = 1
3222
3123
  stdscr = start_curses()
3223
- # h, w = stdscr.getmaxyx()
3224
- # win = stdscr.derwin(h, w//2, 0, 0)
3225
3124
  try:
3226
3125
  # Run the Picker
3227
3126
  # h, w = stdscr.getmaxyx()