move controller connect to popup dialog
This commit is contained in:
@@ -63,7 +63,10 @@ BRAND_H = 36
|
||||
STRIP_H = 44
|
||||
RUNBAR_H = 40
|
||||
STATUS_H = 26
|
||||
RAIL_LEFT = 330
|
||||
#: Matches ``MAIN_SPLITTER_SIZES`` in the window: the rail narrowed when the two
|
||||
#: start-up panels moved into the device-setup dialog, and the mockup has to show the
|
||||
#: same proportions or it stops being a preview of anything.
|
||||
RAIL_LEFT = 300
|
||||
WORKSPACE_W = PAGE_W - RAIL_LEFT - 3 * MARGIN
|
||||
|
||||
PREVIEW_W, PREVIEW_H = 640, 340
|
||||
@@ -110,6 +113,23 @@ STRINGS = {
|
||||
"nodes": "节点数量",
|
||||
"axes_count": "轴数量",
|
||||
"busdata_group": "总线数据 (SDO / RTEX) ▶",
|
||||
"setup_open": "设备设置",
|
||||
"setup_title": "设备设置",
|
||||
"setup_hint": "连接与总线初始化每次开机只需确认一次,因此收进这里;顶栏状态条持续显示结果,设置窗口可以一直开着。",
|
||||
"setup_tabs": ["连接", "总线初始化"],
|
||||
"setup_rows": [
|
||||
["连接方式", "以太网 ▾"],
|
||||
["IP", "192.168.0.11"],
|
||||
["状态", "已连接"],
|
||||
["BAS 文件", "…\\bas\\ECAT.bas"],
|
||||
["初始化状态", "初始化成功"],
|
||||
["总线类型", "EtherCAT"],
|
||||
["节点数量", "5"],
|
||||
["轴数量", "5"],
|
||||
],
|
||||
"setup_connect": "连接",
|
||||
"setup_disconnect": "断开连接",
|
||||
"setup_close": "关闭",
|
||||
"tabs": ["轴调试", "测试序列", "手指调试", "传感器", "表面分布", "标定点"],
|
||||
"readout_title": "轴状态",
|
||||
"enabled": "已使能",
|
||||
@@ -247,6 +267,23 @@ STRINGS = {
|
||||
"nodes": "Nodes",
|
||||
"axes_count": "Axes",
|
||||
"busdata_group": "Bus data (SDO / RTEX) ▶",
|
||||
"setup_open": "Device setup",
|
||||
"setup_title": "Device setup",
|
||||
"setup_hint": "Connecting and bringing the bus up are checked once per machine start-up, so they live here. The status strip keeps reporting the result.",
|
||||
"setup_tabs": ["Connection", "Bus initialisation"],
|
||||
"setup_rows": [
|
||||
["Connection", "Ethernet ▾"],
|
||||
["IP", "192.168.0.11"],
|
||||
["State", "Connected"],
|
||||
["BAS file", "…\\bas\\ECAT.bas"],
|
||||
["Init state", "Initialised"],
|
||||
["Bus type", "EtherCAT"],
|
||||
["Nodes", "5"],
|
||||
["Axes", "5"],
|
||||
],
|
||||
"setup_connect": "Connect",
|
||||
"setup_disconnect": "Disconnect",
|
||||
"setup_close": "Close",
|
||||
"tabs": ["Axis debug", "Test sequence", "Finger debug", "Sensor", "Surface map", "Calibration points"],
|
||||
"readout_title": "Axis state",
|
||||
"enabled": "Enabled",
|
||||
@@ -543,13 +580,16 @@ def draw_status_strip(painter: QPainter, palette: Palette, s: dict, top: int) ->
|
||||
|
||||
_text(
|
||||
painter,
|
||||
QRect(PAGE_W - 600, top, 380, STRIP_H),
|
||||
QRect(PAGE_W - 600, top, 300, STRIP_H),
|
||||
"上次动作: 已使能轴0 / last action: enable axis 0",
|
||||
palette,
|
||||
size=10,
|
||||
muted=True,
|
||||
align=Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter,
|
||||
)
|
||||
# The device-setup button, before the run-screen buttons: connection and bus
|
||||
# initialisation live behind it now instead of in the rail.
|
||||
_button(painter, QRect(PAGE_W - 316, top + 10, 100, 24), s["setup_open"], palette)
|
||||
_button(painter, QRect(PAGE_W - 210, top + 10, 96, 24), s["pause"], palette)
|
||||
_button(painter, QRect(PAGE_W - 106, top + 10, 92, 24), s["stop_all"], palette, danger=True)
|
||||
|
||||
@@ -565,53 +605,13 @@ def draw_status_bar(painter: QPainter, palette: Palette, s: dict, top: int) -> N
|
||||
|
||||
|
||||
def draw_left_rail(painter: QPainter, palette: Palette, s: dict, rect: QRect) -> None:
|
||||
conn = QRect(rect.x(), rect.y(), rect.width(), 210)
|
||||
inner = _panel(painter, conn, palette)
|
||||
_box_title(painter, conn, s["conn_title"], palette)
|
||||
y = inner.y() + 6
|
||||
_text(painter, QRect(inner.x(), y, 76, 22), s["conn_mode"], palette, size=10, muted=True)
|
||||
_field(painter, QRect(inner.x() + 78, y, inner.width() - 78, 22), s["conn_mode_value"] + " ▾", palette)
|
||||
y += 30
|
||||
_text(painter, QRect(inner.x(), y, 30, 22), s["conn_ip"], palette, size=10, muted=True)
|
||||
_field(painter, QRect(inner.x() + 32, y, 140, 22), "192.168.0.11", palette)
|
||||
_button(painter, QRect(inner.x() + 180, y, 88, 22), s["scan"], palette)
|
||||
y += 32
|
||||
_button(painter, QRect(inner.x(), y, 104, 26), s["connect"], palette, primary=True)
|
||||
_button(painter, QRect(inner.x() + 112, y, 108, 26), s["disconnect"], palette)
|
||||
y += 36
|
||||
_text(painter, QRect(inner.x(), y, inner.width(), 20), s["connected"], palette, size=10, muted=True)
|
||||
y += 24
|
||||
_text(painter, QRect(inner.x(), y, inner.width(), 20), "demo (simulated platform)", palette, size=9, muted=True)
|
||||
"""The rail as it is now: only what is read while working.
|
||||
|
||||
bus = QRect(rect.x(), rect.y() + 222, rect.width(), 250)
|
||||
inner = _panel(painter, bus, palette)
|
||||
_box_title(painter, bus, s["bus_title"], palette)
|
||||
y = inner.y() + 6
|
||||
_text(painter, QRect(inner.x(), y, 60, 22), s["bus_file"], palette, size=10, muted=True)
|
||||
_field(painter, QRect(inner.x() + 62, y, 140, 22), "…\\bas\\ECAT.bas", palette)
|
||||
_button(painter, QRect(inner.x() + 208, y, 66, 22), s["choose"], palette)
|
||||
y += 30
|
||||
_text(painter, QRect(inner.x(), y, 74, 20), s["bus_state"], palette, size=10, muted=True)
|
||||
_text(painter, QRect(inner.x() + 76, y, 180, 20), s["bus_ok"], palette, size=10)
|
||||
y += 24
|
||||
_text(painter, QRect(inner.x(), y, 74, 20), s["bus_type"], palette, size=10, muted=True)
|
||||
_text(painter, QRect(inner.x() + 76, y, 180, 20), s["chip_bus"], palette, size=10)
|
||||
y += 24
|
||||
_text(painter, QRect(inner.x(), y, 90, 20), s["nodes"], palette, size=10, muted=True)
|
||||
_text(painter, QRect(inner.x() + 92, y, 40, 20), "5", palette, size=10)
|
||||
_text(painter, QRect(inner.x() + 146, y, 70, 20), s["axes_count"], palette, size=10, muted=True)
|
||||
_text(painter, QRect(inner.x() + 218, y, 40, 20), "5", palette, size=10)
|
||||
y += 32
|
||||
_button(painter, QRect(inner.x(), y, 146, 26), s["download"], palette, primary=True)
|
||||
_button(painter, QRect(inner.x() + 154, y, 104, 26), s["reinit"], palette)
|
||||
|
||||
group = QRect(rect.x(), rect.y() + 484, rect.width(), 32)
|
||||
_panel(painter, group.adjusted(0, 0, 0, -8), palette)
|
||||
_text(painter, QRect(group.x() + 12, group.y(), group.width() - 24, 30), s["busdata_group"], palette, size=10, muted=True)
|
||||
|
||||
# The axis readout lives in this rail now, not in a second one on the right:
|
||||
# two thin rails cost the workspace 240 px at every window size.
|
||||
readout = QRect(rect.x(), rect.y() + 526, rect.width(), 268)
|
||||
Connection and bus initialisation are in the device-setup dialog, so the rail
|
||||
starts with the axis readout instead of burying it under ~460 px of start-up
|
||||
controls.
|
||||
"""
|
||||
readout = QRect(rect.x(), rect.y(), rect.width(), 268)
|
||||
inner = _panel(painter, readout, palette)
|
||||
_box_title(painter, readout, s["readout_title"], palette)
|
||||
y = inner.y() + 6
|
||||
@@ -631,6 +631,54 @@ def draw_left_rail(painter: QPainter, palette: Palette, s: dict, rect: QRect) ->
|
||||
_button(painter, QRect(inner.x(), y + 40, inner.width(), 28), s["stop_all"], palette, danger=True)
|
||||
_button(painter, QRect(inner.x(), y + 76, inner.width(), 28), s["clear_alarms"], palette)
|
||||
|
||||
group = QRect(rect.x(), rect.y() + 280, rect.width(), 32)
|
||||
_panel(painter, group.adjusted(0, 0, 0, -8), palette)
|
||||
_text(painter, QRect(group.x() + 12, group.y(), group.width() - 24, 30), s["busdata_group"], palette, size=10, muted=True)
|
||||
|
||||
|
||||
def draw_setup_dialog(painter: QPainter, palette: Palette, s: dict, rect: QRect) -> None:
|
||||
"""The device-setup dialog: connection on one tab, bus initialisation on the other.
|
||||
|
||||
Drawn as its own panel so the proposal can be reviewed in the same image as the
|
||||
page it came out of.
|
||||
"""
|
||||
dialog = QRect(rect.x(), rect.y(), rect.width(), 400)
|
||||
inner = _panel(painter, dialog, palette)
|
||||
_box_title(painter, dialog, s["setup_title"], palette)
|
||||
_text(
|
||||
painter,
|
||||
QRect(inner.x(), inner.y(), inner.width(), 34),
|
||||
s["setup_hint"],
|
||||
palette,
|
||||
size=9,
|
||||
muted=True,
|
||||
)
|
||||
|
||||
tabs = QRect(inner.x(), inner.y() + 38, inner.width(), inner.height() - 74)
|
||||
tab_w = 130
|
||||
for index, label in enumerate(s["setup_tabs"]):
|
||||
tab = QRect(tabs.x() + index * tab_w, tabs.y(), tab_w, 26)
|
||||
active = index == 0
|
||||
painter.fillRect(tab, palette.window if active else palette.panel)
|
||||
painter.setPen(QPen(palette.border, 1))
|
||||
painter.drawRect(tab.adjusted(0, 0, -1, -1))
|
||||
if active:
|
||||
painter.setPen(QPen(palette.accent, 2))
|
||||
painter.drawLine(tab.bottomLeft(), tab.bottomRight())
|
||||
_text(painter, tab, label, palette, size=10, bold=active, align=Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
# The rows are both tabs' contents stacked, in order: the connection fields and
|
||||
# the bus readouts, which is what the two tabs hold between them.
|
||||
body = _panel(painter, tabs.adjusted(0, 26, 0, 0), palette)
|
||||
y = body.y() + 6
|
||||
for label, value in s["setup_rows"]:
|
||||
_text(painter, QRect(body.x(), y, 96, 22), label, palette, size=10, muted=True)
|
||||
_text(painter, QRect(body.x() + 104, y, body.width() - 104, 22), value, palette, size=10)
|
||||
y += 24
|
||||
_button(painter, QRect(body.x(), y + 6, 110, 26), s["setup_connect"], palette, primary=True)
|
||||
_button(painter, QRect(body.x() + 118, y + 6, 118, 26), s["setup_disconnect"], palette)
|
||||
_button(painter, QRect(dialog.right() - 110, dialog.bottom() - 34, 96, 26), s["setup_close"], palette)
|
||||
|
||||
|
||||
def draw_tabs(painter: QPainter, palette: Palette, s: dict, workspace: QRect, active: str) -> QRect:
|
||||
tab_h = 30
|
||||
@@ -1256,6 +1304,22 @@ TAB_PAINTERS = {
|
||||
#: Tab index -> painter key, for the tab strip labels.
|
||||
TAB_KEYS = ("axes", "sequence", "finger", "sensor", "surface", "points")
|
||||
|
||||
#: Pages that are not workspace tabs. The device setup is a dialog, so it is drawn as
|
||||
#: a page of its own: it has to be reviewable like everything else.
|
||||
EXTRA_PAGES = ("setup",)
|
||||
|
||||
|
||||
def draw_setup_page(painter: QPainter, palette: Palette, s: dict, rect: QRect) -> None:
|
||||
"""The device-setup dialog over the page it was opened from."""
|
||||
painter.fillRect(rect, palette.window)
|
||||
draw_page(painter, palette, s, rect, active="axes", with_chrome=True, with_rail=True)
|
||||
draw_setup_dialog(
|
||||
painter,
|
||||
palette,
|
||||
s,
|
||||
QRect(rect.center().x() - 300, rect.center().y() - 200, 600, 400),
|
||||
)
|
||||
|
||||
|
||||
def draw_page(
|
||||
painter: QPainter,
|
||||
@@ -1265,15 +1329,21 @@ def draw_page(
|
||||
*,
|
||||
active: str = "axes",
|
||||
with_chrome: bool = True,
|
||||
with_rail: bool = True,
|
||||
) -> None:
|
||||
"""The whole page: chrome, strip, run bar, rail, workspace, status bar."""
|
||||
"""The whole page: chrome, strip, run bar, rail, workspace, status bar.
|
||||
|
||||
``with_rail`` only exists for the setup page, which draws this page as the
|
||||
background behind the dialog and does not want to draw the rail twice.
|
||||
"""
|
||||
painter.fillRect(rect, palette.window)
|
||||
body_top = rect.y() + MENU_H + BRAND_H + STRIP_H + RUNBAR_H
|
||||
body_h = rect.height() - (MENU_H + BRAND_H + STRIP_H + RUNBAR_H) - STATUS_H
|
||||
|
||||
draw_left_rail(
|
||||
painter, palette, s, QRect(rect.x() + MARGIN, body_top + MARGIN, RAIL_LEFT, body_h - 2 * MARGIN)
|
||||
)
|
||||
if with_rail:
|
||||
draw_left_rail(
|
||||
painter, palette, s, QRect(rect.x() + MARGIN, body_top + MARGIN, RAIL_LEFT, body_h - 2 * MARGIN)
|
||||
)
|
||||
|
||||
workspace = QRect(
|
||||
rect.x() + 2 * MARGIN + RAIL_LEFT,
|
||||
@@ -1294,6 +1364,14 @@ def draw_page(
|
||||
draw_status_bar(painter, palette, s, rect.bottom() - STATUS_H)
|
||||
|
||||
|
||||
def draw_full_page(painter: QPainter, palette: Palette, s: dict, rect: QRect, key: str) -> None:
|
||||
"""One page of the proposal, by key — a workspace tab or the setup dialog."""
|
||||
if key in EXTRA_PAGES:
|
||||
draw_setup_page(painter, palette, s, rect)
|
||||
return
|
||||
draw_page(painter, palette, s, rect, active=key)
|
||||
|
||||
|
||||
def draw_run_bar(painter: QPainter, palette: Palette, s: dict, top: int) -> None:
|
||||
"""The run strip: phase, progress and the three controls."""
|
||||
painter.fillRect(QRect(0, top, PAGE_W, RUNBAR_H), palette.window)
|
||||
@@ -1356,7 +1434,7 @@ def main() -> int:
|
||||
default=TAB_KEYS[0],
|
||||
# Derived, not listed: a literal here silently rejects any tab added to
|
||||
# TAB_KEYS, which is how the finger page first went missing.
|
||||
choices=(*TAB_KEYS, "all"),
|
||||
choices=(*TAB_KEYS, *EXTRA_PAGES, "all"),
|
||||
help="which page to draw; 'all' writes one full-size image per page",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
@@ -1367,7 +1445,7 @@ def main() -> int:
|
||||
base = Path(args.out).resolve()
|
||||
base.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
pages = TAB_KEYS if args.page == "all" else (args.page,)
|
||||
pages = (*TAB_KEYS, *EXTRA_PAGES) if args.page == "all" else (args.page,)
|
||||
failures = 0
|
||||
for key in pages:
|
||||
target = base if args.page != "all" else base.with_name(f"{base.stem}_{key}{base.suffix or '.png'}")
|
||||
@@ -1376,7 +1454,7 @@ def main() -> int:
|
||||
painter = QPainter(pixmap)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
try:
|
||||
draw_page(painter, palette, s, QRect(0, 0, args.width, args.height), active=key)
|
||||
draw_full_page(painter, palette, s, QRect(0, 0, args.width, args.height), key)
|
||||
finally:
|
||||
painter.end()
|
||||
if pixmap.save(str(target)):
|
||||
|
||||
Reference in New Issue
Block a user