aliyun-controller 0.2.3__tar.gz → 0.2.4__tar.gz

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.
Files changed (26) hide show
  1. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/PKG-INFO +1 -4
  2. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/README.md +0 -3
  3. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/__init__.py +1 -1
  4. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/dns.py +2 -2
  5. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/ui.py +14 -2
  6. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/widgets.py +27 -6
  7. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/PKG-INFO +1 -4
  8. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/pyproject.toml +1 -1
  9. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/app.py +0 -0
  10. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/app.tcss +0 -0
  11. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/billing.py +0 -0
  12. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/client.py +0 -0
  13. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/config.py +0 -0
  14. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/dns.py +0 -0
  15. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/main.py +0 -0
  16. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/__init__.py +0 -0
  17. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/billing.py +0 -0
  18. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/home.py +0 -0
  19. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/settings.py +0 -0
  20. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller/screens/setup.py +0 -0
  21. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/SOURCES.txt +0 -0
  22. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/dependency_links.txt +0 -0
  23. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/entry_points.txt +0 -0
  24. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/requires.txt +0 -0
  25. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/aliyun_controller.egg-info/top_level.txt +0 -0
  26. {aliyun_controller-0.2.3 → aliyun_controller-0.2.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aliyun_controller
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: A Textual TUI for managing Alibaba Cloud services including billing queries and DNS management
5
5
  Author-email: Moha-Master <hongkongreporter@outlook.com>
6
6
  License-Expression: MIT
@@ -61,9 +61,6 @@ Requires-Dist: pytest-asyncio; extra == "dev"
61
61
  | **弹窗** | `Esc` / `Ctrl+C` | 取消并关闭 |
62
62
  | | `回车` | 提交表单或确认 |
63
63
 
64
- > 鼠标全程可用:按钮 / 选项 / 列表行一律**单击即执行**(表格行单击即进入下一级或打开编辑),滚轮滚动光标所在的滚动区域。
65
- > 焦点进入输入框即切换为**文本编辑模式**:使用控件原生编辑键(`Home`/`End`、`Ctrl+Shift+A` 全选、`Ctrl+X/C/V` 剪切 / 复制 / 粘贴),底部提示栏同步切换,此时 `Ctrl+R` 刷新让位给输入框;`Ctrl+C` 有选中则复制、无选中则返回 / 取消。
66
-
67
64
  ## 安装指南
68
65
 
69
66
  ### 通过 pip 安装(推荐)
@@ -33,9 +33,6 @@
33
33
  | **弹窗** | `Esc` / `Ctrl+C` | 取消并关闭 |
34
34
  | | `回车` | 提交表单或确认 |
35
35
 
36
- > 鼠标全程可用:按钮 / 选项 / 列表行一律**单击即执行**(表格行单击即进入下一级或打开编辑),滚轮滚动光标所在的滚动区域。
37
- > 焦点进入输入框即切换为**文本编辑模式**:使用控件原生编辑键(`Home`/`End`、`Ctrl+Shift+A` 全选、`Ctrl+X/C/V` 剪切 / 复制 / 粘贴),底部提示栏同步切换,此时 `Ctrl+R` 刷新让位给输入框;`Ctrl+C` 有选中则复制、无选中则返回 / 取消。
38
-
39
36
  ## 安装指南
40
37
 
41
38
  ### 通过 pip 安装(推荐)
@@ -1,4 +1,4 @@
1
1
  """
2
2
  Aliyun Controller
3
3
  """
4
- __version__ = "0.2.3"
4
+ __version__ = "0.2.4"
@@ -46,7 +46,7 @@ class DomainListScreen(PageScreen):
46
46
  """域名列表,回车进入该域名的解析记录。"""
47
47
 
48
48
  TITLE = "DNS 解析管理"
49
- HINT = "↑↓ 移动 · 回车 管理解析记录 · / 搜索 · Ctrl+R 刷新 · Esc/Ctrl+C 返回"
49
+ HINT = "↑↓ 移动 · 双击/回车 管理解析记录 · / 搜索 · Ctrl+R 刷新 · Esc/Ctrl+C 返回"
50
50
 
51
51
  BINDINGS = [Binding("/", "focus_search", "搜索", show=False)]
52
52
 
@@ -203,7 +203,7 @@ class RecordListScreen(PageScreen):
203
203
  """某域名的解析记录列表,支持筛选、排序、增删改与启停。"""
204
204
 
205
205
  TITLE = "解析记录"
206
- HINT = "单击/回车 编辑 · Ctrl+N 新增 · Ctrl+E 编辑 · Ctrl+D 删除 · Ctrl+R 刷新 · Esc/Ctrl+C 返回"
206
+ HINT = "双击/回车 编辑 · Ctrl+N 新增 · Ctrl+E 编辑 · Ctrl+D 删除 · Ctrl+R 刷新 · Esc/Ctrl+C 返回"
207
207
 
208
208
  BINDINGS = [
209
209
  Binding("/", "focus_search", "搜索", show=False),
@@ -13,6 +13,7 @@ from rich.text import Text
13
13
  from textual import on
14
14
  from textual.binding import Binding
15
15
  from textual.containers import Horizontal, Vertical, VerticalScroll
16
+ from textual.css.query import NoMatches
16
17
  from textual.message import Message
17
18
  from textual.reactive import reactive
18
19
  from textual.screen import Screen
@@ -448,14 +449,25 @@ class PageScreen(Screen):
448
449
  # ------------------------------------------------------------ 标题 / 副标题
449
450
 
450
451
  def set_subtitle(self, text: str) -> None:
452
+ """更新顶栏副标题。
453
+
454
+ 判定不能用 ``is_mounted``:`on_mount` 里它仍是 `False`(Textual 派发完
455
+ Mount 事件之后才置位),首屏副标题会永远停在空串。改为按顶栏控件是否
456
+ 已组合判断:未组合时仅保存文本,交由 compose 使用。
457
+ """
451
458
  self.subtitle = text
452
- if self.is_mounted:
459
+ try:
453
460
  self.query_one("#tb-sub", Static).update(text)
461
+ except NoMatches:
462
+ pass
454
463
 
455
464
  def set_title(self, text: str) -> None:
465
+ """更新顶栏标题;判定口径同 set_subtitle。"""
456
466
  self.TITLE = text
457
- if self.is_mounted:
467
+ try:
458
468
  self.query_one(".tb-title", Static).update(Text(text, style="bold"))
469
+ except NoMatches:
470
+ pass
459
471
 
460
472
  # ------------------------------------------------------------ 折叠菜单
461
473
 
@@ -613,32 +613,53 @@ class MenuMarquee:
613
613
 
614
614
 
615
615
  class ClickTable(DataTable):
616
- """列表即操作的表格:单击数据单元格 = 移动光标并立即发 RowSelected。
616
+ """可操作表格:单击只选中,双击(或 Enter)才执行。
617
+
618
+ ``activate="double"``(默认):单击数据格只移动光标(发 ``RowHighlighted``,
619
+ 供状态栏 / 控制按钮刷新),``event.chain >= 2``(同格 0.5s 内第二次点击)
620
+ 才发 ``RowSelected``。避免误点一下就把详情 / 表单顶到脸上。
621
+
622
+ ``activate="click"``:单击即发 ``RowSelected``,用于「选中即生效」的选择器
623
+ (如格式列表、纯选择用途的主从列表)。
617
624
 
618
625
  注意:Textual 沿 MRO 逐类派发事件,重写 `_on_click` 后父类实现仍会被调用一次,
619
626
  因此接管分支与回落分支都必须 prevent_default(),防止 RowSelected 双发。
620
627
  """
621
628
 
629
+ def __init__(self, *, activate: str = "double", **kwargs) -> None:
630
+ super().__init__(**kwargs)
631
+ self.activate_mode = "click" if activate == "click" else "double"
632
+
622
633
  async def _on_click(self, event: events.Click) -> None:
623
634
  meta = event.style.meta if event.style is not None else {}
624
635
  row = meta.get("row", -1)
625
636
  col = meta.get("column", -1)
626
637
  is_data_cell = (
627
638
  self.cursor_type == "row"
628
- and isinstance(row, int) and isinstance(col, int)
629
- and 0 <= row < self.row_count and col >= 0
639
+ and isinstance(row, int)
640
+ and isinstance(col, int)
641
+ and 0 <= row < self.row_count
642
+ and col >= 0
630
643
  and not meta.get("out_of_bounds", False)
631
644
  )
632
645
  if is_data_cell:
633
646
  self.cursor_coordinate = Coordinate(row, col)
634
- self._post_selected_message()
647
+ if self.activate_mode == "click" or event.chain >= 2:
648
+ self._post_selected_message()
635
649
  else:
636
650
  await super()._on_click(event)
637
651
  event.prevent_default()
638
652
 
639
653
 
640
- def make_table(*headers, cursor: str = "row", zebra: bool = True, classes: str = "tbl", **kwargs) -> ClickTable:
641
- dt = ClickTable(cursor_type=cursor, zebra_stripes=zebra, classes=classes, **kwargs)
654
+ def make_table(
655
+ *headers,
656
+ cursor: str = "row",
657
+ zebra: bool = True,
658
+ classes: str = "tbl",
659
+ activate: str = "double",
660
+ **kwargs,
661
+ ) -> ClickTable:
662
+ dt = ClickTable(cursor_type=cursor, zebra_stripes=zebra, classes=classes, activate=activate, **kwargs)
642
663
  dt.add_columns(*headers)
643
664
  return dt
644
665
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aliyun_controller
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: A Textual TUI for managing Alibaba Cloud services including billing queries and DNS management
5
5
  Author-email: Moha-Master <hongkongreporter@outlook.com>
6
6
  License-Expression: MIT
@@ -61,9 +61,6 @@ Requires-Dist: pytest-asyncio; extra == "dev"
61
61
  | **弹窗** | `Esc` / `Ctrl+C` | 取消并关闭 |
62
62
  | | `回车` | 提交表单或确认 |
63
63
 
64
- > 鼠标全程可用:按钮 / 选项 / 列表行一律**单击即执行**(表格行单击即进入下一级或打开编辑),滚轮滚动光标所在的滚动区域。
65
- > 焦点进入输入框即切换为**文本编辑模式**:使用控件原生编辑键(`Home`/`End`、`Ctrl+Shift+A` 全选、`Ctrl+X/C/V` 剪切 / 复制 / 粘贴),底部提示栏同步切换,此时 `Ctrl+R` 刷新让位给输入框;`Ctrl+C` 有选中则复制、无选中则返回 / 取消。
66
-
67
64
  ## 安装指南
68
65
 
69
66
  ### 通过 pip 安装(推荐)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aliyun_controller"
7
- version = "0.2.3"
7
+ version = "0.2.4"
8
8
  description = "A Textual TUI for managing Alibaba Cloud services including billing queries and DNS management"
9
9
  readme = "README.md"
10
10
  authors = [