tkfluent 0.1.4__py3-none-any.whl → 0.1.5__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.
tkflu/scrollbar.py CHANGED
@@ -1,28 +1,44 @@
1
- from tkdeft.windows.draw import DSvgDraw
2
1
  from tkdeft.windows.canvas import DCanvas
2
+ from tkdeft.windows.draw import DSvgDraw
3
3
  from tkdeft.windows.drawwidget import DDrawWidget
4
4
 
5
5
 
6
6
  class FluScrollBarDraw(DSvgDraw):
7
- def create_roundrect(self,
8
- x1, y1, x2, y2, radius, radiusy=None, temppath=None,
9
- fill="transparent", outline="black", outline2="black", width=1
10
- ):
7
+ def create_track(
8
+ self,
9
+ x1, y1, x2, y2, radius, radiusy=None, temppath=None,
10
+ fill="transparent"
11
+ ):
11
12
  if radiusy:
12
13
  _rx = radius
13
14
  _ry = radiusy
14
15
  else:
15
16
  _rx, _ry = radius, radius
16
17
  drawing = self.create_drawing(x2 - x1, y2 - y1, temppath=temppath)
17
- border = drawing[1].linearGradient(start=(x1, y1), end=(x1, y2), id="DButton.Border")
18
- border.add_stop_color("0%", outline)
19
- border.add_stop_color("100%", outline2)
20
- drawing[1].defs.add(border)
21
18
  drawing[1].add(
22
19
  drawing[1].rect(
23
20
  (x1, y1), (x2 - x1, y2 - y1), _rx, _ry,
24
- fill=fill, stroke_width=width,
25
- stroke=f"url(#{border.get_id()})",
21
+ fill=fill,
22
+ )
23
+ )
24
+ drawing[1].save()
25
+ return drawing[0]
26
+
27
+ def create_thumb(
28
+ self,
29
+ x1, y1, x2, y2, radius, radiusy=None, temppath=None,
30
+ fill="transparent"
31
+ ):
32
+ if radiusy:
33
+ _rx = radius
34
+ _ry = radiusy
35
+ else:
36
+ _rx, _ry = radius, radius
37
+ drawing = self.create_drawing(x2 - x1, y2 - y1, temppath=temppath)
38
+ drawing[1].add(
39
+ drawing[1].rect(
40
+ (x1, y1), (x2 - x1, y2 - y1), _rx, _ry,
41
+ fill=fill,
26
42
  )
27
43
  )
28
44
  drawing[1].save()
@@ -32,31 +48,57 @@ class FluScrollBarDraw(DSvgDraw):
32
48
  class FluScrollBarCanvas(DCanvas):
33
49
  draw = FluScrollBarDraw
34
50
 
35
- def create_round_rectangle(self,
36
- x1, y1, x2, y2, r1, r2=None, temppath=None,
37
- fill="transparent", outline="black", outline2="black", width=1
38
- ):
39
- self._img = self.svgdraw.create_roundrect(
51
+ def create_track(
52
+ self,
53
+ x1, y1, x2, y2, r1, r2=None, temppath=None,
54
+ fill="transparent"
55
+ ):
56
+ self._img = self.svgdraw.create_track(
40
57
  x1, y1, x2, y2, r1, r2, temppath=temppath,
41
- fill=fill, outline=outline, outline2=outline2, width=width
58
+ fill=fill
42
59
  )
43
60
  self._tkimg = self.svgdraw.create_tksvg_image(self._img)
44
61
  return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
45
62
 
46
- create_roundrect = create_round_rectangle
63
+ def create_thumb(
64
+ self,
65
+ x1, y1, x2, y2, r1, r2=None, temppath=None,
66
+ fill="transparent"
67
+ ):
68
+ self._img2 = self.svgdraw.create_thumb(
69
+ x1, y1, x2, y2, r1, r2, temppath=temppath,
70
+ fill=fill
71
+ )
72
+ self._tkimg2 = self.svgdraw.create_tksvg_image(self._img2)
73
+ return self.create_image(x1, y1, anchor="nw", image=self._tkimg2)
74
+
75
+
76
+ from .constants import MODE
77
+ from typing import Union
78
+ from tkinter import Event
47
79
 
48
80
 
49
81
  class FluScrollBar(FluScrollBarCanvas, DDrawWidget):
50
82
  def __init__(self, *args,
51
- text="",
52
- width=120,
53
- height=32,
83
+ width=None,
84
+ height=None,
54
85
  command=None,
55
- font=None,
86
+ state="normal",
56
87
  mode="light",
57
- style="standard",
88
+ orient= "vertical",
58
89
  **kwargs):
59
- self._init(mode, style)
90
+ self._init(mode)
91
+ if orient == "horizontal":
92
+ if width is None:
93
+ width = 120
94
+ if height is None:
95
+ height = 6
96
+ else:
97
+ if width is None:
98
+ width = 6
99
+ if height is None:
100
+ height = 120
101
+
60
102
 
61
103
  super().__init__(*args, width=width, height=height, **kwargs)
62
104
 
@@ -66,135 +108,307 @@ class FluScrollBar(FluScrollBarCanvas, DDrawWidget):
66
108
  command = empty
67
109
 
68
110
  self.dconfigure(
69
- text=text,
70
- command=command
111
+ command=command,
112
+ state=state,
113
+ orient=orient
71
114
  )
72
115
 
73
116
  self.bind("<<Clicked>>", lambda event=None: self.focus_set(), add="+")
74
117
  self.bind("<<Clicked>>", lambda event=None: self.attributes.command(), add="+")
75
118
 
76
- self.bind("<Return>", lambda event=None: self.attributes.command(), add="+") # 可以使用回车键模拟点击
77
-
78
- if font is None:
79
- from tkdeft.utility.fonts import SegoeFont
80
- self.attributes.font = SegoeFont()
119
+ def _init(self, mode: MODE = "light"):
120
+ from easydict import EasyDict
81
121
 
82
- def _init(self, mode, style):
122
+ self.enter = False
123
+ self.button1 = False
83
124
 
84
- from easydict import EasyDict
125
+ self.thumb_height = 100
126
+ self.thumb_y = 10
85
127
 
86
128
  self.attributes = EasyDict(
87
129
  {
88
- "text": "",
89
130
  "command": None,
90
- "font": None,
91
-
92
- "rest": {
93
- "back_color": "#ffffff",
94
- "border_color": "#f0f0f0",
95
- "border_color2": "#d6d6d6",
96
- "border_width": 1,
97
- "radius": 6,
98
- "text_color": "#1b1b1b",
99
- },
100
- "hover": {
101
- "back_color": "#fcfcfc",
102
- "border_color": "#f0f0f0",
103
- "border_color2": "#d6d6d6",
104
- "border_width": 1,
105
- "radius": 6,
106
- "text_color": "#1b1b1b",
107
- },
108
- "pressed": {
109
- "back_color": "#fdfdfd",
110
- "border_color": "#f0f0f0",
111
- "border_color2": "#f0f0f0",
112
- "border_width": 1,
113
- "radius": 6,
114
- "text_color": "#636363",
115
- }
131
+ "state": "normal",
132
+ "expanded": False,
133
+ "orient": "vertical",
134
+
135
+ "rest": {},
136
+ "expand": {},
137
+ "disabled": {}
116
138
  }
117
139
  )
118
140
 
119
- self.theme(mode=mode, style=style)
141
+ self.theme(mode=mode)
142
+
143
+
144
+ def theme(self, mode: MODE = None):
145
+ if mode:
146
+ self.mode = mode
147
+ from .designs.scrollbar import scrollbar
148
+ m = scrollbar(mode)
149
+ self.attributes.rest = m["rest"]
150
+ self.attributes.expand = m["expand"]
151
+ self.attributes.disabled = m["disabled"]
152
+
153
+ def _event_enter(self, event=None):
154
+ self.enter = True
155
+ self.attributes.expanded = True
120
156
 
121
- def _draw(self, event=None):
157
+ self._draw(event)
158
+
159
+ def _event_leave(self, event=None):
160
+ self.enter = False
161
+ self.attributes.expanded = False
162
+
163
+ self._draw(event)
164
+
165
+ def set(self, start=None, end=None):
166
+ if start is not None:
167
+ self.start = start
168
+ if end is not None:
169
+ self.end = end
170
+
171
+ orient = self.dcget("orient")
172
+ width = self.winfo_width()
173
+ height = self.winfo_height()
174
+
175
+ if orient == "vertical":
176
+ # 计算垂直滑块位置 (轨道高度 = 总高度 - 20px 边距)
177
+ track_height = height - 20
178
+ thumb_y1 = 10 + self.start * track_height
179
+ thumb_y2 = 10 + self.end * track_height
180
+
181
+ # 更新滑块坐标
182
+ if hasattr(self, 'element_thumb'):
183
+ self.coords(self.element_thumb,
184
+ 1, thumb_y1,
185
+ width - 1, thumb_y2)
186
+ else:
187
+ # 计算水平滑块位置 (轨道宽度 = 总宽度 - 20px 边距)
188
+ track_width = width - 20
189
+ thumb_x1 = 10 + self.start * track_width
190
+ thumb_x2 = 10 + self.end * track_width
191
+
192
+ # 更新滑块坐标
193
+ if hasattr(self, 'element_thumb'):
194
+ self.coords(self.element_thumb,
195
+ thumb_x1, 1,
196
+ thumb_x2, height - 1)
197
+
198
+ def _draw(self, event: Union[Event, None] = None, tempcolor: Union[dict, None] = None):
199
+ """
200
+
201
+ Parameters:
202
+ 绘制按钮
203
+ """
122
204
  super()._draw(event)
123
205
 
124
- self.delete("all")
206
+ width = self.winfo_width()
207
+ height = self.winfo_height()
208
+ # 提前定义,反正多次调用浪费资源
125
209
 
126
- if self.enter:
127
- if self.button1:
128
- _back_color = self.attributes.pressed.back_color
129
- _border_color = self.attributes.pressed.border_color
130
- _border_color2 = self.attributes.pressed.border_color2
131
- _border_width = self.attributes.pressed.border_width
132
- _radius = self.attributes.pressed.radius
133
- _text_color = self.attributes.pressed.text_color
210
+ state = self.dcget("state")
211
+ orient = self.dcget("orient")
212
+ expanded = self.dcget("expanded")
213
+
214
+ _dict = None
215
+
216
+ if not tempcolor:
217
+ if state == "normal":
218
+ if self.attributes.expanded:
219
+ _dict = self.attributes.expand
220
+ else:
221
+ _dict = self.attributes.rest
134
222
  else:
135
- _back_color = self.attributes.hover.back_color
136
- _border_color = self.attributes.hover.border_color
137
- _border_color2 = self.attributes.hover.border_color2
138
- _border_width = self.attributes.hover.border_width
139
- _radius = self.attributes.hover.radius
140
- _text_color = self.attributes.hover.text_color
141
- else:
142
- _back_color = self.attributes.rest.back_color
143
- _border_color = self.attributes.rest.border_color
144
- _border_color2 = self.attributes.rest.border_color2
145
- _border_width = self.attributes.rest.border_width
146
- _radius = self.attributes.rest.radius
147
- _text_color = self.attributes.rest.text_color
148
-
149
- self.element_border = self.create_round_rectangle(
150
- 0, 0, self.winfo_width(), self.winfo_height(), _radius, temppath=self.temppath,
151
- fill=_back_color, outline=_border_color, outline2=_border_color2, width=_border_width
152
- )
153
- self.element_text = self.create_text(
154
- self.winfo_width() / 2, self.winfo_height() / 2, anchor="center",
155
- fill=_text_color, text=self.attributes.text, font=self.attributes.font
156
- )
223
+ _dict = self.attributes.disabled
157
224
 
158
- def theme(self, mode="light", style="standard"):
159
- self.mode = mode
160
- if style:
161
- self.style = style
162
- self._light()
163
- """if mode.lower() == "dark":
164
- if style.lower() == "accent":
165
- self._dark_accent()
225
+ _thumb_color = _dict.thumb_color
226
+ if hasattr(_dict, "track_color"):
227
+ _track_color = _dict.track_color
166
228
  else:
167
- self._dark()
229
+ _track_color = None
230
+ _radius = _dict.radius
168
231
  else:
169
- if style.lower() == "accent":
170
- self._light_accent()
232
+ _thumb_color = tempcolor.thumb_color
233
+ _track_color = tempcolor.track_color
234
+
235
+ self.delete("all")
236
+
237
+ if expanded:
238
+ if orient == "vertical":
239
+ self.element_track = self.create_track(
240
+ 0, 0, width, height, _radius, temppath=self.temppath,
241
+ fill=_track_color,
242
+ )
243
+
244
+ self.element_thumb = self.create_thumb(
245
+ 1, 10, width-1, height-10, _radius, temppath=self.temppath2,
246
+ fill=_thumb_color,
247
+ )
171
248
  else:
172
- self._light()"""
249
+ self.element_track = self.create_track(
250
+ 0, 0, width, height, _radius, temppath=self.temppath,
251
+ fill=_track_color,
252
+ )
173
253
 
174
- def _light(self):
175
- self.dconfigure(
176
- rest={
177
- "back_color": "#ffffff",
178
- "border_color": "#f0f0f0",
179
- "border_color2": "#d6d6d6",
180
- "border_width": 1,
181
- "radius": 6,
182
- "text_color": "#1b1b1b",
183
- },
184
- hover={
185
- "back_color": "#fcfcfc",
186
- "border_color": "#f0f0f0",
187
- "border_color2": "#d6d6d6",
188
- "border_width": 1,
189
- "radius": 6,
190
- "text_color": "#1b1b1b",
191
- },
192
- pressed={
193
- "back_color": "#fdfdfd",
194
- "border_color": "#f0f0f0",
195
- "border_color2": "#f0f0f0",
196
- "border_width": 1,
197
- "radius": 6,
198
- "text_color": "#636363",
199
- }
200
- )
254
+ self.element_thumb = self.create_thumb(
255
+ 0, 0, width, height, _radius, temppath=self.temppath2,
256
+ fill=_thumb_color,
257
+ )
258
+ else:
259
+ if orient == "vertical":
260
+ self.element_thumb = self.create_thumb(
261
+ 3, 10, width-1, height-10, _radius, temppath=self.temppath2,
262
+ fill=_thumb_color,
263
+ )
264
+
265
+ self.update()
266
+
267
+
268
+ """
269
+ def add_scrollbar(self,pos:tuple,widget,height:int=200,direction='y',bg='#f0f0f0',color='#999999',oncolor='#89898b'):#绘制滚动条
270
+ #滚动条宽度7px,未激活宽度3px;建议与widget相隔5xp
271
+ def enter(event):#鼠标进入
272
+ self.itemconfig(sc,outline=oncolor,width=7)
273
+ def leave(event):#鼠标离开
274
+ self.itemconfig(sc,outline=color,width=3)
275
+ def widget_move(sp,ep):#控件控制滚动条滚动
276
+ if mode=='y' and use_widget:
277
+ startp=start+canmove*float(sp)
278
+ endp=start+canmove*float(ep)
279
+ self.coords(sc,(pos[0]+5,startp+5,pos[0]+5,endp-5))
280
+ elif mode=='x' and use_widget:
281
+ startp=start+canmove*float(sp)
282
+ endp=start+canmove*float(ep)
283
+ self.coords(sc,(startp+5,pos[1]+5,endp+5,pos[1]+5))
284
+ def mousedown(event):
285
+ nonlocal use_widget#当该值为真,才允许响应widget_move函数
286
+ use_widget=False
287
+ if mode=='y':
288
+ scroll.start=self.canvasy(event.y)#定义起始纵坐标
289
+ elif mode=='x':
290
+ scroll.start=self.canvasx(event.x)#横坐标
291
+ def mouseup(event):
292
+ nonlocal use_widget
293
+ use_widget=True
294
+ def drag(event):
295
+ bbox=self.bbox(sc)
296
+ if mode=='y':#纵向
297
+ move=self.canvasy(event.y)-scroll.start#将窗口坐标转化为画布坐标
298
+ #防止被拖出范围
299
+ if bbox[1]+move<start-1 or bbox[3]+move>end+1:
300
+ return
301
+ self.move(sc,0,move)
302
+ elif mode=='x':#横向
303
+ move=self.canvasx(event.x)-scroll.start
304
+ if bbox[0]+move<start-1 or bbox[2]+move>end+1:
305
+ return
306
+ self.move(sc,move,0)
307
+ #重新定义画布中的起始拖动位置
308
+ scroll.start+=move
309
+ sc_move()
310
+ def topmove(event):#top
311
+ bbox=self.bbox(sc)
312
+ if mode=='y':
313
+ move=-(bbox[3]-bbox[1])/2
314
+ if bbox[1]+move<start:
315
+ move=-(bbox[1]-start)
316
+ self.move(sc,0,move)
317
+ elif mode=='x':
318
+ move=-(bbox[2]-bbox[0])/2
319
+ if bbox[0]+move<start:
320
+ move=-(bbox[0]-start)
321
+ self.move(sc,move,0)
322
+ sc_move()
323
+ def bottommove(event):#bottom
324
+ bbox=self.bbox(sc)
325
+ if mode=='y':
326
+ move=(bbox[3]-bbox[1])/2
327
+ if bbox[3]+move>end:
328
+ move=(end-bbox[3])
329
+ self.move(sc,0,move)
330
+ elif mode=='x':
331
+ move=(bbox[2]-bbox[0])/2
332
+ if bbox[2]+move>end:
333
+ move=(end-bbox[2])
334
+ self.move(sc,0,move)
335
+ sc_move()
336
+ def backmove(event):#back
337
+ bbox=self.bbox(sc)
338
+ if mode=='y':
339
+ posy=self.canvasy(event.y)
340
+ move=posy-bbox[1]
341
+ if move>0 and move+bbox[3]>end:
342
+ move=end-bbox[3]
343
+ if move<0 and move+bbox[1]<start:
344
+ move=start-bbox[1]
345
+ self.move(sc,0,move)
346
+ elif mode=='x':
347
+ posx=self.canvasx(event.x)
348
+ move=posx-bbox[0]
349
+ if move>0 and move+bbox[2]>end:
350
+ move=end-bbox[2]
351
+ if move<0 and move+bbox[0]<start:
352
+ move=start-bbox[0]
353
+ self.move(sc,move,0)
354
+ sc_move()
355
+ def sc_move():#滚动条控制控件滚动
356
+ bbox=self.bbox(sc)
357
+ if mode=='y':
358
+ startp=(bbox[1]-start)/canmove
359
+ widget.yview('moveto',startp)
360
+ elif mode=='x':
361
+ startp=(bbox[0]-start)/canmove
362
+ widget.xview('moveto',startp*1.2)
363
+ if direction.upper()=='X':
364
+ mode='x'
365
+ elif direction.upper()=='Y':
366
+ mode='y'
367
+ else:
368
+ return None
369
+ #上标、下标 ▲▼
370
+ if mode=='y':
371
+ #back=self.create_rectangle((pos[0],pos[1],pos[0]+10,pos[1]+height),fill=bg,width=0)
372
+ back=self.create_polygon((pos[0]+5,pos[1]+5,pos[0]+5,pos[1]+height-5,pos[0]+5,pos[1]+5),
373
+ width=12,outline=bg)
374
+ uid='scrollbar'+str(back)
375
+ self.itemconfig(back,tags=uid)
376
+ top=self.create_text(pos,text='▲',font='微软雅黑 8',anchor='nw',fill=oncolor,tags=uid)
377
+ bottom=self.create_text((pos[0],pos[1]+height),text='▼',font='微软雅黑 8',anchor='sw',fill=oncolor,tags=uid)
378
+ #sc=self.create_rectangle((pos[0],pos[1]+15,pos[0]+10,pos[1]+height-15),fill=color,width=0,tags=uid)
379
+ sc=self.create_polygon((pos[0]+5,pos[1]+20,pos[0]+5,pos[1]+height-20,pos[0]+5,pos[1]+20,),
380
+ width=3,outline=color,tags=uid)
381
+ #起始和终止位置
382
+ start=pos[1]+15
383
+ end=pos[1]+height-15
384
+ canmove=end-start
385
+ #绑定组件
386
+ widget.config(yscrollcommand=widget_move)
387
+ elif mode=='x':
388
+ back=self.create_polygon((pos[0]+5,pos[1]+5,pos[0]+height-5,pos[1]+5,pos[0],pos[1]+5),
389
+ width=12,outline=bg)
390
+ uid='scrollbar'+str(back)
391
+ self.itemconfig(back,tags=uid)
392
+ top=self.create_text((pos[0]+2,pos[1]+11),text='▲',angle=90,font='微软雅黑 8',anchor='w',fill=oncolor,tags=uid)
393
+ bottom=self.create_text((pos[0]+height,pos[1]),text='▼',angle=90,font='微软雅黑 8',anchor='se',fill=oncolor,tags=uid)
394
+ sc=self.create_polygon((pos[0]+20,pos[1]+5,pos[0]+height-20,pos[1]+5,pos[0]+20,pos[1]+5),
395
+ width=3,outline=color,tags=uid)
396
+ start=pos[0]+8
397
+ end=pos[0]+height-13
398
+ canmove=(end-start)*0.95
399
+ widget.config(xscrollcommand=widget_move)
400
+ scroll=TinUINum()
401
+ use_widget=True#是否允许控件控制滚动条
402
+ self.tag_bind(sc,'<Button-1>',mousedown)
403
+ self.tag_bind(sc,'<ButtonRelease-1>',mouseup)
404
+ self.tag_bind(sc,'<B1-Motion>',drag)
405
+ #绑定样式
406
+ self.tag_bind(sc,'<Enter>',enter)
407
+ self.tag_bind(sc,'<Leave>',leave)
408
+ #绑定点击滚动
409
+ self.tag_bind(top,'<Button-1>',topmove)
410
+ self.tag_bind(bottom,'<Button-1>',bottommove)
411
+ self.tag_bind(back,'<Button-1>',backmove)
412
+ return top,bottom,back,sc,uid
413
+
414
+ """