Skip to content

Commit fd4e60c

Browse files
committed
5.6.0
### Version 5.6.0 (current version) Fixed: - Issues and possible errors with dropdowns/checkboxes/cell edits - `delete_dropdown()`/`delete_checkbox()` issues Changed: - Deprecated external functions `create_text_editor()`/`get_text_editor_value()`/`bind_text_editor_set()` as they no longer worked both externally and internally, use `open_cell()` instead - Renamed internal function `get_text_editor_value()` to `close_text_editor()` Improved: - Slightly boost performance if there are many cells onscreen and gridlines are showing - You can now use the scroll wheel in the header to vertically scroll if there are multiple lines in the column headers - Improvements to text editor - Text now draws slightly closer to cell edges in certain scenarios - Improved visibility of dropdown box against sheet background - Improved dropdown window height - black theme selected cells border color - light green theme selected cells background color
1 parent 6ce8311 commit fd4e60c

File tree

6 files changed

+145
-143
lines changed

6 files changed

+145
-143
lines changed

DOCUMENTATION.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,8 +1094,10 @@ get_selected_min_max()
10941094
## 15 Modifying Selected Cells
10951095

10961096
```python
1097-
set_currently_selected(current_tuple_0 = 0, current_tuple_1 = 0, selection_binding = True)
1097+
set_currently_selected(row, column, type_ = "cell", selection_binding = True)
10981098
```
1099+
- `type_` (`str`) either `"cell"`, `"row"` or `"column"`.
1100+
- `selection_binding` if `True` runs extra bindings selection function if one has been specified using `extra_bindings()`.
10991101

11001102
___
11011103

@@ -1297,27 +1299,32 @@ show(canvas = "all")
12971299

12981300
## 20 Cell Text Editor
12991301

1302+
Open the currently selected cell in the main table.
13001303
```python
1301-
create_text_editor(row = 0, column = 0, text = None, state = "normal", see = True, set_data_ref_on_destroy = False,
1302-
binding = None)
1304+
open_cell(ignore_existing_editor = True)
13031305
```
1306+
- Function utilises the currently selected cell in the main table, even if a column/row is selected, to open a non selected cell first use `set_currently_selected()` to set the cell to open.
13041307

13051308
___
13061309

1310+
Open the currently selected cell but in the header.
13071311
```python
1308-
set_text_editor_value(text = "", r = None, c = None)
1312+
open_header_cell(ignore_existing_editor = True)
13091313
```
1314+
- Also uses currently selected cell, which you can set with `set_currently_selected()`.
13101315

13111316
___
13121317

1318+
Open the currently selected cell but in the index.
13131319
```python
1314-
bind_text_editor_set(func, row, column)
1320+
open_index_cell(ignore_existing_editor = True)
13151321
```
1322+
- Also uses currently selected cell, which you can set with `set_currently_selected()`.
13161323

13171324
___
13181325

13191326
```python
1320-
get_text_editor_value(editor_info = None, r = None, c = None, set_data_ref_on_destroy = True, event = None, destroy = True, move_down = True, redraw = True, recreate = True)
1327+
set_text_editor_value(text = "", r = None, c = None)
13211328
```
13221329

13231330
___

RELEASE_NOTES.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
### Version 5.6.0 (in development)
1+
### Version 5.6.0 (current version)
22
Fixed:
3-
- Issues and possible errors with dropdowns/checkboxes
3+
- Issues and possible errors with dropdowns/checkboxes/cell edits
44
- `delete_dropdown()`/`delete_checkbox()` issues
55

66
Changed:
7-
- Improvements to text editor
7+
- Deprecated external functions `create_text_editor()`/`get_text_editor_value()`/`bind_text_editor_set()` as they no longer worked both externally and internally, use `open_cell()` instead
8+
- Renamed internal function `get_text_editor_value()` to `close_text_editor()`
9+
10+
Improved:
11+
- Slightly boost performance if there are many cells onscreen and gridlines are showing
812
- You can now use the scroll wheel in the header to vertically scroll if there are multiple lines in the column headers
9-
- Main table text now draws slightly closer to cell edges
13+
- Improvements to text editor
14+
- Text now draws slightly closer to cell edges in certain scenarios
1015
- Improved visibility of dropdown box against sheet background
1116
- Improved dropdown window height
1217
- black theme selected cells border color

tksheet/_tksheet.py

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,22 +1111,12 @@ def move_columns(self, moveto: int, to_move_min: int, number_of_columns: int, mo
11111111
# works on currently selected box
11121112
def open_cell(self, ignore_existing_editor = True):
11131113
self.MT.open_cell(event = GeneratedMouseEvent(), ignore_existing_editor = ignore_existing_editor)
1114-
1115-
def create_text_editor(self,
1116-
row = 0,
1117-
column = 0,
1118-
text = None,
1119-
state = "normal",
1120-
see = True,
1121-
set_data_ref_on_destroy = False,
1122-
binding = None):
1123-
self.MT.create_text_editor(r = row,
1124-
c = column,
1125-
text = text,
1126-
state = state,
1127-
see = see,
1128-
set_data_ref_on_destroy = set_data_ref_on_destroy,
1129-
binding = binding)
1114+
1115+
def open_header_cell(self, ignore_existing_editor = True):
1116+
self.CH.open_cell(event = GeneratedMouseEvent(), ignore_existing_editor = ignore_existing_editor)
1117+
1118+
def open_index_cell(self, ignore_existing_editor = True):
1119+
self.RI.open_cell(event = GeneratedMouseEvent(), ignore_existing_editor = ignore_existing_editor)
11301120

11311121
def set_text_editor_value(self, text = "", r = None, c = None):
11321122
if self.MT.text_editor is not None and r is None and c is None:
@@ -1137,17 +1127,6 @@ def set_text_editor_value(self, text = "", r = None, c = None):
11371127
def bind_text_editor_set(self, func, row, column):
11381128
self.MT.bind_text_editor_destroy(func, row, column)
11391129

1140-
def get_text_editor_value(self, editor_info = None, r = None, c = None, set_data_ref_on_destroy = True, event = None, destroy = True, move_down = True, redraw = True, recreate = True):
1141-
return self.MT.get_text_editor_value(editor_info = editor_info,
1142-
r = r,
1143-
c = c,
1144-
set_data_ref_on_destroy = set_data_ref_on_destroy,
1145-
event = event,
1146-
destroy = destroy,
1147-
move_down = move_down,
1148-
redraw = redraw,
1149-
recreate = recreate)
1150-
11511130
def destroy_text_editor(self, event = None):
11521131
self.MT.destroy_text_editor(event = event)
11531132

tksheet/_tksheet_column_headers.py

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def __init__(self,
6565

6666
self.centre_alignment_text_mod_indexes = (slice(1, None), slice(None, -1))
6767
self.c_align_cyc = cycle(self.centre_alignment_text_mod_indexes)
68+
self.grid_cyctup = ("st", "end")
69+
self.grid_cyc = cycle(self.grid_cyctup)
6870
self.parentframe = parentframe
6971
self.column_drag_and_drop_perform = column_drag_and_drop_perform
7072
self.being_drawn_rect = None
@@ -111,7 +113,7 @@ def __init__(self,
111113
self.edit_cell_enabled = False
112114
self.show_default_header_for_empty = show_default_header_for_empty
113115
self.dragged_col = None
114-
self.visible_col_dividers = []
116+
self.visible_col_dividers = {}
115117
self.col_height_resize_bbox = tuple()
116118
self.cell_options = {}
117119
self.rsz_w = None
@@ -195,15 +197,13 @@ def disable_bindings(self, binding):
195197
if binding == "hide_columns":
196198
self.hide_columns_enabled = False
197199

198-
def check_mouse_position_width_resizers(self, event):
199-
x = self.canvasx(event.x)
200-
y = self.canvasy(event.y)
201-
ov = None
202-
for x1, y1, x2, y2 in self.visible_col_dividers:
203-
if x >= x1 and y >= y1 and x <= x2 and y <= y2:
204-
ov = self.find_overlapping(x1, y1, x2, y2)
205-
break
206-
return ov
200+
def check_mouse_position_width_resizers(self, x, y):
201+
for c, (x1, y1, x2, y2) in self.visible_col_dividers.items():
202+
if (x >= x1 and
203+
y >= y1 and
204+
x <= x2 and
205+
y <= y2):
206+
return c
207207

208208
def rc(self, event):
209209
self.MT.mouseclick_outside_editor_or_dropdown()
@@ -288,16 +288,10 @@ def mouse_motion(self, event):
288288
y = self.canvasy(event.y)
289289
mouse_over_resize = False
290290
if self.width_resizing_enabled:
291-
ov = self.check_mouse_position_width_resizers(event)
292-
if ov is not None:
293-
tgs = tuple()
294-
for itm in ov:
295-
tgs = self.gettags(itm)
296-
if tgs and "v" == tgs[0]:
297-
c = int(tgs[1])
298-
self.rsz_w, mouse_over_resize = c, True
299-
self.config(cursor = "sb_h_double_arrow")
300-
break
291+
c = self.check_mouse_position_width_resizers(x, y)
292+
if c is not None:
293+
self.rsz_w, mouse_over_resize = c, True
294+
self.config(cursor = "sb_h_double_arrow")
301295
else:
302296
self.rsz_w = None
303297
if self.height_resizing_enabled and not mouse_over_resize:
@@ -349,12 +343,14 @@ def b1_press(self, event = None):
349343
self.focus_set()
350344
self.MT.mouseclick_outside_editor_or_dropdown()
351345
self.closed_dropdown = self.mouseclick_outside_editor_or_dropdown()
352-
x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
353-
if self.check_mouse_position_width_resizers(event) is None:
354-
self.rsz_w = None
346+
x = self.canvasx(event.x)
347+
y = self.canvasy(event.y)
355348
c = self.MT.identify_col(x = event.x)
356349
self.b1_pressed_loc = c
350+
if self.check_mouse_position_width_resizers(x, y) is None:
351+
self.rsz_w = None
357352
if self.width_resizing_enabled and self.rsz_w is not None:
353+
x1, y1, x2, y2 = self.MT.get_canvas_visible_area()
358354
self.currently_resizing_width = True
359355
x = self.MT.col_positions[self.rsz_w]
360356
line2x = self.MT.col_positions[self.rsz_w - 1]
@@ -859,17 +855,17 @@ def redraw_text(self, x, y, text, fill, font, anchor, tag):
859855
self.disp_text[t] = True
860856
return t
861857

862-
def redraw_gridline(self, x1, y1, x2, y2, fill, width, tag):
858+
def redraw_gridline(self,points, fill, width, tag):
863859
if self.hidd_grid:
864860
t, sh = self.hidd_grid.popitem()
865-
self.coords(t, x1, y1, x2, y2)
861+
self.coords(t, points)
866862
if sh:
867863
self.itemconfig(t, fill = fill, width = width, tag = tag, capstyle = tk.BUTT, joinstyle = tk.ROUND)
868864
else:
869865
self.itemconfig(t, fill = fill, width = width, tag = tag, capstyle = tk.BUTT, joinstyle = tk.ROUND, state = "normal")
870866
self.disp_grid[t] = True
871867
else:
872-
self.disp_grid[self.create_line(x1, y1, x2, y2, fill = fill, width = width, tag = tag)] = True
868+
self.disp_grid[self.create_line(points, fill = fill, width = width, tag = tag)] = True
873869

874870
def redraw_dropdown(self, x1, y1, x2, y2, fill, outline, tag, draw_outline = True, draw_arrow = True, dd_is_open = False):
875871
if draw_outline:
@@ -984,18 +980,30 @@ def redraw_grid_and_text(self, last_col_line_pos, x1, x_stop, start_col, end_col
984980
self.disp_dropdown = {}
985981
self.hidd_checkbox.update(self.disp_checkbox)
986982
self.disp_checkbox = {}
987-
self.visible_col_dividers = []
983+
self.visible_col_dividers = {}
988984
x = self.MT.col_positions[start_col]
989-
self.redraw_gridline(x, 0, x, self.current_height, fill = self.header_grid_fg, width = 1, tag = "fv")
990985
self.col_height_resize_bbox = (x1, self.current_height - 2, x_stop, self.current_height)
991986
yend = self.current_height - 5
992987
if self.MT.show_vertical_grid or self.width_resizing_enabled:
988+
self.grid_cyc = cycle(self.grid_cyctup)
989+
points = []
993990
for c in range(start_col + 1, end_col):
994991
x = self.MT.col_positions[c]
995992
if self.width_resizing_enabled:
996-
self.visible_col_dividers.append((x - 2, 1, x + 2, yend))
997-
self.redraw_gridline(x, 0, x, self.current_height, fill = self.header_grid_fg, width = 1, tag = ("v", f"{c}"))
998-
self.redraw_gridline(x1, self.current_height - 1, x_stop, self.current_height - 1, fill = self.header_border_fg, width = 1, tag = "h")
993+
self.visible_col_dividers[c] = (x - 2, 1, x + 2, yend)
994+
st_or_end = next(self.grid_cyc)
995+
if st_or_end == "st":
996+
points.extend([x, -1,
997+
x, self.current_height,
998+
self.MT.col_positions[c + 1] if len(self.MT.col_positions) - 1 > c else x, self.current_height])
999+
elif st_or_end == "end":
1000+
points.extend([x, self.current_height,
1001+
x, -1,
1002+
self.MT.col_positions[c + 1] if len(self.MT.col_positions) - 1 > c else x, -1])
1003+
if points:
1004+
self.redraw_gridline(points = points, fill = self.header_grid_fg, width = 1, tag = "v")
1005+
self.redraw_gridline(points = (x, 0, x, self.current_height), fill = self.header_grid_fg, width = 1, tag = "fv")
1006+
self.redraw_gridline(points = (x1, self.current_height - 1, x_stop, self.current_height - 1), fill = self.header_border_fg, width = 1, tag = "h")
9991007
top = self.canvasy(0)
10001008
c_2 = self.header_selected_cells_bg if self.header_selected_cells_bg.startswith("#") else Color_Map_[self.header_selected_cells_bg]
10011009
c_3 = self.header_selected_columns_bg if self.header_selected_columns_bg.startswith("#") else Color_Map_[self.header_selected_columns_bg]
@@ -1054,8 +1062,8 @@ def redraw_grid_and_text(self, last_col_line_pos, x1, x_stop, start_col, end_col
10541062
if cell_alignment == "w":
10551063
x += box_w
10561064
elif cell_alignment == "center":
1057-
x += ceil(box_w / 2)
1058-
mw = mw - box_w
1065+
x += ceil(box_w / 2) + 1
1066+
mw = mw - box_w - 1
10591067
self.redraw_checkbox(dcol,
10601068
fc + 2,
10611069
0,
@@ -1098,6 +1106,7 @@ def redraw_grid_and_text(self, last_col_line_pos, x1, x_stop, start_col, end_col
10981106
txt = txt[tmod - 1:-tmod]
10991107
self.itemconfig(t, text = txt)
11001108
wd = self.bbox(t)
1109+
self.c_align_cyc = cycle(self.centre_alignment_text_mod_indexes)
11011110
while wd[2] - wd[0] > mw:
11021111
txt = txt[next(self.c_align_cyc)]
11031112
self.itemconfig(t, text = txt)
@@ -1167,8 +1176,8 @@ def redraw_grid_and_text(self, last_col_line_pos, x1, x_stop, start_col, end_col
11671176
self.itemconfig(t, state = "hidden")
11681177
self.hidd_checkbox[t] = False
11691178

1170-
def open_cell(self, event = None):
1171-
if not self.MT.anything_selected() or self.text_editor_id is not None:
1179+
def open_cell(self, event = None, ignore_existing_editor = False):
1180+
if not self.MT.anything_selected() or (not ignore_existing_editor and self.text_editor_id is not None):
11721181
return
11731182
currently_selected = self.MT.currently_selected()
11741183
if not currently_selected:
@@ -1316,11 +1325,11 @@ def create_text_editor(self,
13161325
self.text_editor.textedit.bind("<FocusOut>", lambda x: binding((c, "FocusOut")))
13171326
self.text_editor.textedit.bind("<Escape>", lambda x: binding((c, "Escape")))
13181327
elif binding is None and set_data_ref_on_destroy:
1319-
self.text_editor.textedit.bind("<Tab>", lambda x: self.get_text_editor_value((c, "Tab")))
1320-
self.text_editor.textedit.bind("<Return>", lambda x: self.get_text_editor_value((c, "Return")))
1328+
self.text_editor.textedit.bind("<Tab>", lambda x: self.close_text_editor((c, "Tab")))
1329+
self.text_editor.textedit.bind("<Return>", lambda x: self.close_text_editor((c, "Return")))
13211330
if not dropdown:
1322-
self.text_editor.textedit.bind("<FocusOut>", lambda x: self.get_text_editor_value((c, "FocusOut")))
1323-
self.text_editor.textedit.bind("<Escape>", lambda x: self.get_text_editor_value((c, "Escape")))
1331+
self.text_editor.textedit.bind("<FocusOut>", lambda x: self.close_text_editor((c, "FocusOut")))
1332+
self.text_editor.textedit.bind("<Escape>", lambda x: self.close_text_editor((c, "Escape")))
13241333
else:
13251334
self.text_editor.textedit.bind("<Escape>", lambda x: self.destroy_text_editor("Escape"))
13261335

@@ -1396,7 +1405,7 @@ def destroy_text_editor(self, event = None):
13961405
self.focus_set()
13971406

13981407
# c is displayed col
1399-
def get_text_editor_value(self, editor_info = None, c = None, set_data_ref_on_destroy = True, event = None, destroy = True, move_down = True, redraw = True, recreate = True):
1408+
def close_text_editor(self, editor_info = None, c = None, set_data_ref_on_destroy = True, event = None, destroy = True, move_down = True, redraw = True, recreate = True):
14001409
if self.focus_get() is None and editor_info:
14011410
return
14021411
if editor_info is not None and len(editor_info) >= 2 and editor_info[1] == "Escape":
@@ -1429,7 +1438,7 @@ def get_text_editor_value(self, editor_info = None, c = None, set_data_ref_on_de
14291438
self.MT.refresh()
14301439
if editor_info is not None and len(editor_info) >= 2 and editor_info[1] != "FocusOut":
14311440
self.focus_set()
1432-
return self.text_editor_value
1441+
return "break"
14331442

14341443
#internal event use
14351444
def _set_cell_data(self, c = 0, dcol = None, value = "", cell_resize = True, undo = True, redraw = True):
@@ -1633,7 +1642,7 @@ def mouseclick_outside_editor_or_dropdown(self):
16331642
else:
16341643
closed_dd_coords = None
16351644
if self.text_editor_loc is not None and self.text_editor is not None:
1636-
self.get_text_editor_value(editor_info = (self.text_editor_loc, "ButtonPress-1"))
1645+
self.close_text_editor(editor_info = (self.text_editor_loc, "ButtonPress-1"))
16371646
else:
16381647
self.destroy_text_editor("Escape")
16391648
if closed_dd_coords:

0 commit comments

Comments
 (0)