503 lines
18 KiB
GDScript
503 lines
18 KiB
GDScript
extends Control
|
||
## Дев-сцена: предпросмотр всех модальных окон на фейковом игровом экране.
|
||
##
|
||
## godot --path . --script scripts/ui/dev_capture.gd -- \
|
||
## --scene=res://scenes/ui/ModalsPreview.tscn --out=/tmp/modals.png --modal=shop
|
||
##
|
||
## --modal: shop | pause | settings | hour | run_win | run_lose | menu | confirm | grid
|
||
## Клавиши: 1–9 — окна, ← → — переключение, G — сетка.
|
||
|
||
const SHOP := preload("res://scripts/ui/shop_modal.gd")
|
||
const PAUSE := preload("res://scripts/ui/pause_modal.gd")
|
||
const SETTINGS := preload("res://scripts/ui/settings_modal.gd")
|
||
const HOUR := preload("res://scripts/ui/hour_result_modal.gd")
|
||
const RUN := preload("res://scripts/ui/run_result_modal.gd")
|
||
const MENU := preload("res://scripts/ui/main_menu.gd")
|
||
const CONFIRM := preload("res://scripts/ui/confirm_modal.gd")
|
||
const MASCOT_PREVIEW := preload("res://scripts/ui/tutorial_mascot_preview.gd")
|
||
|
||
const W := 1280.0
|
||
const H := 720.0
|
||
const TOOLBAR_H := 34.0
|
||
const GRID_SCALE := 0.285
|
||
const CELL := Vector2(1280.0 * GRID_SCALE, 720.0 * GRID_SCALE)
|
||
const GRID_X := 79.0
|
||
const GRID_Y := 50.0
|
||
const GRID_GAP_X := 14.0
|
||
const GRID_GAP_Y := 18.0
|
||
|
||
const TABS := ["МАГАЗИН", "ПАУЗА", "НАСТРОЙКИ", "ИТОГИ ЧАСА", "ПОБЕДА", "ПОРАЖЕНИЕ",
|
||
"МЕНЮ", "ВОПРОС", "МАСКОТ", "СЕТКА"]
|
||
const ARG_NAMES := ["shop", "pause", "settings", "hour", "run_win", "run_lose", "menu",
|
||
"confirm", "mascot", "grid"]
|
||
|
||
var _stage: Control
|
||
var _scrim: ColorRect
|
||
var _overlay: OverlayLayer
|
||
var _toolbar: Panel90
|
||
var _signal_label: Label
|
||
|
||
var _modals: Array[Control] = []
|
||
var _tab_buttons: Array[Button90] = []
|
||
var _active := 0
|
||
var _grid_mode := false
|
||
|
||
var _shop
|
||
var _pause
|
||
var _settings
|
||
var _hour
|
||
var _run_win
|
||
var _run_lose
|
||
var _menu
|
||
var _confirm
|
||
var _mascot_preview
|
||
|
||
var _money := 280
|
||
var _levels := {"shop_slot3": 1, "shop_buffer": 1, "shop_timer": 2}
|
||
|
||
|
||
func _ready() -> void:
|
||
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
mouse_filter = Control.MOUSE_FILTER_PASS
|
||
_build()
|
||
var start := _arg_start()
|
||
_show_tab(start)
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Сборка
|
||
# --------------------------------------------------------------------------
|
||
|
||
func _build() -> void:
|
||
var desk := FakeDesk.new()
|
||
desk.name = "FakeDesk"
|
||
add_child(desk)
|
||
desk.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
desk.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
|
||
_scrim = ColorRect.new()
|
||
_scrim.name = "GridScrim"
|
||
_scrim.color = Color(0.086, 0.098, 0.129)
|
||
_scrim.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
_scrim.visible = false
|
||
add_child(_scrim)
|
||
_scrim.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
|
||
_stage = Control.new()
|
||
_stage.name = "Stage"
|
||
add_child(_stage)
|
||
_stage.position = Vector2.ZERO
|
||
_stage.size = Vector2(W, H)
|
||
|
||
_build_modals()
|
||
|
||
_overlay = OverlayLayer.new()
|
||
_overlay.name = "Overlay"
|
||
_overlay.z_index = 6
|
||
_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
add_child(_overlay)
|
||
_overlay.position = Vector2.ZERO
|
||
_overlay.size = Vector2(W, H)
|
||
|
||
_build_toolbar()
|
||
|
||
|
||
func _build_modals() -> void:
|
||
_shop = SHOP.new()
|
||
_shop.name = "ShopModal"
|
||
_add_modal(_shop)
|
||
|
||
_pause = PAUSE.new()
|
||
_pause.name = "PauseModal"
|
||
_add_modal(_pause)
|
||
|
||
_settings = SETTINGS.new()
|
||
_settings.name = "SettingsModal"
|
||
_add_modal(_settings)
|
||
|
||
_hour = HOUR.new()
|
||
_hour.name = "HourResultModal"
|
||
_add_modal(_hour)
|
||
|
||
_run_win = RUN.new()
|
||
_run_win.name = "RunResultVictory"
|
||
_add_modal(_run_win)
|
||
|
||
_run_lose = RUN.new()
|
||
_run_lose.name = "RunResultDefeat"
|
||
_add_modal(_run_lose)
|
||
|
||
_menu = MENU.new()
|
||
_menu.name = "MainMenu"
|
||
_add_modal(_menu)
|
||
|
||
_confirm = CONFIRM.new()
|
||
_confirm.name = "ConfirmModal"
|
||
_add_modal(_confirm)
|
||
|
||
_mascot_preview = MASCOT_PREVIEW.new()
|
||
_mascot_preview.name = "MascotPreview"
|
||
_add_modal(_mascot_preview)
|
||
|
||
# фейковые данные
|
||
_shop.open(_money, _levels)
|
||
_pause.open()
|
||
_settings.open({"sfx": 70, "music": 55, "calm_bg": true, "fullscreen": false})
|
||
_hour.open({
|
||
"hour": 3, "hours_total": 9, "earned": 1240, "done": 8, "failed": 2,
|
||
"reflected": 3, "missed": 1, "sla_delta": -12, "sla": 168, "sla_max": 200,
|
||
})
|
||
_run_win.open({
|
||
"won": true, "reason": "Смена отработана. Все 9 часов закрыты.",
|
||
"score": 14820, "best": 15100, "hours": 9, "hours_total": 9,
|
||
"money": 2380, "sla": 96, "sla_max": 200,
|
||
})
|
||
_run_lose.open({
|
||
"won": false, "reason": "SLA упал до нуля на шестом часе.",
|
||
"score": 6310, "best": 15100, "hours": 5, "hours_total": 9,
|
||
"money": 940, "sla": 0, "sla_max": 200,
|
||
})
|
||
_menu.set_has_save(false)
|
||
_confirm.ask("Выйти в главное меню?", "Прогресс текущей смены не сохранится.",
|
||
"Да", "Нет", true)
|
||
|
||
# сигналы
|
||
_shop.buy_requested.connect(_on_shop_buy)
|
||
_shop.closed.connect(func() -> void: _status("МАГАЗИН ЗАКРЫТ"))
|
||
_pause.resumed.connect(func() -> void: _status("ПАУЗА · ПРОДОЛЖИТЬ"))
|
||
_pause.settings_requested.connect(func() -> void: _status("ПАУЗА · НАСТРОЙКИ"))
|
||
_pause.menu_requested.connect(func() -> void: _status("ПАУЗА · В ГЛАВНОЕ МЕНЮ"))
|
||
_pause.closed.connect(func() -> void: _status("ПАУЗА ЗАКРЫТА"))
|
||
_settings.settings_changed.connect(_on_settings_changed)
|
||
_settings.closed.connect(func() -> void: _status("НАСТРОЙКИ ЗАКРЫТЫ"))
|
||
_hour.next_pressed.connect(func() -> void:
|
||
_status("ИТОГИ ЧАСА · ДАЛЕЕ")
|
||
_hour.open({
|
||
"hour": 4, "hours_total": 9, "earned": 1580, "done": 11, "failed": 1,
|
||
"reflected": 4, "missed": 0, "sla_delta": 9, "sla": 177, "sla_max": 200,
|
||
}))
|
||
_run_win.new_run.connect(func() -> void: _status("ЗАБЕГ · НОВЫЙ ЗАБЕГ"))
|
||
_run_win.to_menu.connect(func() -> void: _status("ЗАБЕГ · В МЕНЮ"))
|
||
_run_lose.new_run.connect(func() -> void: _status("ЗАБЕГ · НОВЫЙ ЗАБЕГ"))
|
||
_run_lose.to_menu.connect(func() -> void: _status("ЗАБЕГ · В МЕНЮ"))
|
||
_menu.new_run.connect(func() -> void: _status("МЕНЮ · НОВЫЙ ЗАБЕГ"))
|
||
_menu.continue_run.connect(func() -> void: _status("МЕНЮ · ПРОДОЛЖИТЬ"))
|
||
_menu.settings.connect(func() -> void: _status("МЕНЮ · НАСТРОЙКИ"))
|
||
_menu.about.connect(func() -> void: _status("МЕНЮ · ОБ ИГРЕ"))
|
||
_confirm.answered.connect(func(yes: bool) -> void:
|
||
_status("ОТВЕТ: " + ("ДА" if yes else "НЕТ")))
|
||
|
||
|
||
func _add_modal(m: Control) -> void:
|
||
_stage.add_child(m)
|
||
# фиксированный размер: в сетке масштабируем сами
|
||
m.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
|
||
m.size = Vector2(W, H)
|
||
m.position = Vector2.ZERO
|
||
_modals.append(m)
|
||
|
||
|
||
func _build_toolbar() -> void:
|
||
_toolbar = Panel90.new()
|
||
_toolbar.name = "Toolbar"
|
||
_toolbar.kind = Panel90.Kind.FLAT
|
||
_toolbar.z_index = 10
|
||
add_child(_toolbar)
|
||
_toolbar.position = Vector2.ZERO
|
||
_toolbar.size = Vector2(W, TOOLBAR_H)
|
||
|
||
var sep := ColorRect.new()
|
||
sep.color = Theme90.SHADE
|
||
sep.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
sep.position = Vector2(0, TOOLBAR_H - 1)
|
||
sep.size = Vector2(W, 1)
|
||
_toolbar.add_child(sep)
|
||
|
||
var caption := Label.new()
|
||
caption.text = "ПРЕДПРОСМОТР"
|
||
caption.add_theme_font_override("font", Theme90.ui(700))
|
||
caption.add_theme_font_size_override("font_size", Theme90.FS_MICRO)
|
||
caption.add_theme_color_override("font_color", Theme90.DARK)
|
||
caption.position = Vector2(8, 11)
|
||
caption.size = Vector2(80, 12)
|
||
caption.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
_toolbar.add_child(caption)
|
||
|
||
var f := Theme90.ui()
|
||
var sep_x := 92.0
|
||
var vline := ColorRect.new()
|
||
vline.color = Theme90.SHADE
|
||
vline.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
vline.position = Vector2(sep_x, 5)
|
||
vline.size = Vector2(1, 24)
|
||
_toolbar.add_child(vline)
|
||
|
||
var x := 100.0
|
||
for i in TABS.size():
|
||
var b := Button90.new()
|
||
b.flat_style = true
|
||
b.caption = TABS[i]
|
||
b.caption_size = Theme90.FS_MICRO
|
||
b.size = Vector2(f.get_string_size(TABS[i], HORIZONTAL_ALIGNMENT_LEFT, -1,
|
||
Theme90.FS_MICRO).x + 18.0, 24)
|
||
b.position = Vector2(x, 5)
|
||
b.tooltip_text = "Клавиша %d" % (i + 1)
|
||
b.pressed.connect(_show_tab.bind(i))
|
||
_toolbar.add_child(b)
|
||
_tab_buttons.append(b)
|
||
x += b.size.x + 4.0
|
||
|
||
_signal_label = Label.new()
|
||
_signal_label.text = "СИГНАЛ: —"
|
||
_signal_label.add_theme_font_override("font", Theme90.ui(700))
|
||
_signal_label.add_theme_font_size_override("font_size", Theme90.FS_MICRO)
|
||
_signal_label.add_theme_color_override("font_color", Theme90.NAVY)
|
||
_signal_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||
_signal_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||
_signal_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
_signal_label.position = Vector2(770, 5)
|
||
_signal_label.size = Vector2(330, 24)
|
||
_toolbar.add_child(_signal_label)
|
||
|
||
var hint := Label.new()
|
||
hint.text = "1–9 · ← → · G"
|
||
hint.add_theme_font_override("font", Theme90.ui(700))
|
||
hint.add_theme_font_size_override("font_size", Theme90.FS_MICRO)
|
||
hint.add_theme_color_override("font_color", Theme90.DARK)
|
||
hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||
hint.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||
hint.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
hint.position = Vector2(1110, 5)
|
||
hint.size = Vector2(160, 24)
|
||
_toolbar.add_child(hint)
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Переключение
|
||
# --------------------------------------------------------------------------
|
||
|
||
func _arg_start() -> int:
|
||
for a in OS.get_cmdline_user_args():
|
||
if a.begins_with("--modal="):
|
||
var key := a.substr(8)
|
||
var idx := ARG_NAMES.find(key)
|
||
if idx >= 0:
|
||
return idx
|
||
return 0
|
||
|
||
|
||
func _show_tab(index: int) -> void:
|
||
_active = clampi(index, 0, TABS.size() - 1)
|
||
_grid_mode = _active == TABS.size() - 1
|
||
_scrim.visible = _grid_mode
|
||
for i in _tab_buttons.size():
|
||
_tab_buttons[i].active = i == _active
|
||
_tab_buttons[i].queue_redraw()
|
||
|
||
if _grid_mode:
|
||
_overlay.cells.clear()
|
||
for i in _modals.size():
|
||
var m := _modals[i]
|
||
if m == _mascot_preview:
|
||
m.visible = false
|
||
continue
|
||
var cell := _grid_cell(i)
|
||
m.visible = true
|
||
m.scale = Vector2(GRID_SCALE, GRID_SCALE)
|
||
m.position = cell
|
||
_overlay.cells.append({"rect": Rect2(cell, CELL), "title": _cell_title(i)})
|
||
else:
|
||
_overlay.cells.clear()
|
||
for i in _modals.size():
|
||
var m := _modals[i]
|
||
m.scale = Vector2.ONE
|
||
m.position = Vector2.ZERO
|
||
m.size = Vector2(W, H)
|
||
m.visible = i == _active
|
||
_overlay.queue_redraw()
|
||
_status("—")
|
||
|
||
|
||
func _grid_cell(i: int) -> Vector2:
|
||
var col := i % 3
|
||
var row := i / 3
|
||
return Vector2(GRID_X + col * (CELL.x + GRID_GAP_X),
|
||
GRID_Y + row * (CELL.y + GRID_GAP_Y))
|
||
|
||
|
||
func _cell_title(i: int) -> String:
|
||
var titles := ["МАГАЗИН", "ПАУЗА", "НАСТРОЙКИ", "ИТОГИ ЧАСА", "ЗАБЕГ: ПОБЕДА",
|
||
"ЗАБЕГ: ПОРАЖЕНИЕ", "ГЛАВНОЕ МЕНЮ", "ПОДТВЕРЖДЕНИЕ", "МАСКОТ"]
|
||
if i < titles.size():
|
||
return titles[i]
|
||
return TABS[i]
|
||
|
||
|
||
func _status(text: String) -> void:
|
||
if _signal_label != null:
|
||
var value := "СИГНАЛ: " + text
|
||
_signal_label.text = Theme90.fit(Theme90.ui(700), value, Theme90.FS_MICRO, 320)
|
||
|
||
|
||
func _on_shop_buy(id: String) -> void:
|
||
var price: int = _shop.item_price(id)
|
||
var level := int(_levels.get(id, 0))
|
||
var max_level: int = _shop.item_max_level(id)
|
||
if level >= max_level:
|
||
_status("МАКСИМУМ: " + _shop.item_name(id))
|
||
return
|
||
if _money < price:
|
||
_status("НЕ ХВАТАЕТ %d $: %s" % [price - _money, _shop.item_name(id)])
|
||
return
|
||
_money -= price
|
||
_levels[id] = level + 1
|
||
_shop.refresh(_money, _levels)
|
||
_status("КУПЛЕНО: %s · −%d $" % [_shop.item_name(id), price])
|
||
|
||
|
||
func _on_settings_changed(values: Dictionary) -> void:
|
||
_status("ЗВУК %d · МУЗЫКА %d · ФОН %s · ЭКРАН %s" % [
|
||
int(values.get("sfx", 0)), int(values.get("music", 0)),
|
||
"ВКЛ" if bool(values.get("calm_bg", false)) else "ВЫКЛ",
|
||
"ВКЛ" if bool(values.get("fullscreen", false)) else "ВЫКЛ"])
|
||
|
||
|
||
func _unhandled_input(event: InputEvent) -> void:
|
||
if not (event is InputEventKey) or not event.pressed or event.echo:
|
||
return
|
||
match event.keycode:
|
||
KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9:
|
||
_show_tab(event.keycode - KEY_1)
|
||
get_viewport().set_input_as_handled()
|
||
KEY_G:
|
||
_show_tab(TABS.size() - 1)
|
||
get_viewport().set_input_as_handled()
|
||
KEY_LEFT:
|
||
_show_tab((_active - 1 + TABS.size()) % TABS.size())
|
||
get_viewport().set_input_as_handled()
|
||
KEY_RIGHT:
|
||
_show_tab((_active + 1) % TABS.size())
|
||
get_viewport().set_input_as_handled()
|
||
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Служебные слои
|
||
# --------------------------------------------------------------------------
|
||
|
||
class OverlayLayer:
|
||
extends Control
|
||
|
||
var cells: Array = []
|
||
|
||
func _draw() -> void:
|
||
for cell in cells:
|
||
var r: Rect2 = cell["rect"]
|
||
draw_rect(r.grow(1), Color(0.55, 0.58, 0.66), false, 1.0)
|
||
draw_rect(r, Color(0.20, 0.22, 0.28), false, 1.0)
|
||
draw_rect(Rect2(r.position.x, r.position.y - 14, 5, 5), Theme90.ACCENT_LIGHT)
|
||
Theme90.text(self, Theme90.ui(), Vector2(r.position.x + 10, r.position.y - 14),
|
||
str(cell["title"]), Theme90.FS_MICRO, Color(0.86, 0.89, 0.95))
|
||
|
||
|
||
## Условный «игровой экран» под модалками — чтобы видеть затемнение.
|
||
class FakeDesk:
|
||
extends Control
|
||
|
||
func _draw() -> void:
|
||
draw_texture_rect(Theme90.dither_texture(), Rect2(Vector2.ZERO, size), true)
|
||
var f := Theme90.ui()
|
||
var lf := Theme90.logo()
|
||
|
||
# титлбар приложения — светлая полоса
|
||
draw_rect(Rect2(0, 0, size.x, 24), Theme90.PAPER_HI)
|
||
draw_rect(Rect2(0, 23, size.x, 1), Theme90.HAIRLINE)
|
||
Theme90.text(self, lf, Vector2(10, 7), "PEAK HOUR 97", 9, Theme90.NAVY)
|
||
Theme90.text(self, f, Vector2(size.x - 74, 7), "03:42", Theme90.FS_MICRO,
|
||
Theme90.SHADE)
|
||
|
||
# строка меню
|
||
draw_rect(Rect2(0, 24, size.x, 20), Theme90.PAPER)
|
||
draw_rect(Rect2(0, 43, size.x, 1), Theme90.HAIRLINE)
|
||
Theme90.text(self, f, Vector2(10, 27), "ФАЙЛ ПРАВКА ВИД СПРАВКА",
|
||
Theme90.FS_MICRO, Theme90.DARK)
|
||
Theme90.text(self, f, Vector2(1070, 27), "МАГАЗИН", Theme90.FS_MICRO, Theme90.DARK)
|
||
Theme90.text(self, f, Vector2(1140, 27), "НАЧАТЬ ЧАС", Theme90.FS_MICRO, Theme90.NAVY)
|
||
|
||
# рабочая область
|
||
draw_style_box(Theme90.box(Theme90.PAPER, Theme90.BORDER_SOFT, 4, 1), Rect2(8, 48, 840, 548))
|
||
_draw_window(Rect2(16, 72, 240, 516), "ДИСКИ")
|
||
_draw_window(Rect2(264, 72, 576, 516), "ФАЙЛЫ · ПРИЁМ")
|
||
_draw_window(Rect2(856, 48, 416, 264), "ПРИЁМ")
|
||
_draw_window(Rect2(856, 320, 416, 276), "ОТПРАВКА")
|
||
|
||
# дерево
|
||
Theme90.draw_folder_icon(self, Vector2(30, 108), Theme90.WARN, true)
|
||
Theme90.text(self, f, Vector2(50, 104), "C: ЛОКАЛЬНЫЙ", Theme90.FS_MICRO, Theme90.INK)
|
||
for i in 5:
|
||
Theme90.draw_folder_icon(self, Vector2(42, 132 + i * 20), Theme90.WARN, false)
|
||
Theme90.text(self, f, Vector2(62, 130 + i * 20),
|
||
["ПРИЁМ", "ОТПРАВКА", "АРХИВ", "ПРОЕКТЫ", "СКАНЫ"][i],
|
||
Theme90.FS_MICRO, Theme90.DARK)
|
||
|
||
# сетка файлов
|
||
for i in 18:
|
||
var col := i % 6
|
||
var row := i / 6
|
||
var r := Rect2(292 + col * 88, 112 + row * 72, 76, 60)
|
||
draw_style_box(Theme90.box(Theme90.WHITE, Theme90.BORDER_SOFT, 3, 1), r)
|
||
Theme90.draw_doc_icon(self, Rect2(r.position + Vector2(26, 6), Vector2(24, 24)),
|
||
["text", "sound", "photo", "video"][i % 4],
|
||
[Theme90.ACCENT, Theme90.WARN, Theme90.SUCCESS, Theme90.ERROR][i % 4])
|
||
Theme90.text(self, f, Vector2(r.position.x + 7, r.position.y + 38),
|
||
Theme90.fit(f, ["отчёт_смены", "реклама", "скан_пасп", "кадр_4", "договор",
|
||
"прайс"][i % 6] + ".xls", Theme90.FS_MICRO, 62),
|
||
Theme90.FS_MICRO, Theme90.DARK)
|
||
|
||
# карточки приёма и запросов
|
||
for i in 4:
|
||
var y := 80.0 + i * 52.0
|
||
var card := Rect2(866, y, 396, 44)
|
||
draw_style_box(Theme90.box(Theme90.WHITE, Theme90.BORDER_SOFT, 3, 1), card)
|
||
Theme90.draw_packet_icon(self, card.position + Vector2(10, 14), Theme90.ACCENT)
|
||
Theme90.text(self, f, card.position + Vector2(32, 9), "пакет_%02d.wav" % (i + 1),
|
||
Theme90.FS_MICRO, Theme90.INK)
|
||
Theme90.text(self, f, card.position + Vector2(32, 24), "1,8 МБ · 00:12",
|
||
Theme90.FS_MICRO, Theme90.SHADE)
|
||
|
||
for i in 3:
|
||
var y := 328.0 + i * 64.0
|
||
var card := Rect2(866, y, 396, 56)
|
||
draw_style_box(Theme90.box(Theme90.PAPER_HI, Theme90.BORDER_SOFT, 3, 1), card)
|
||
Theme90.text(self, f, card.position + Vector2(10, 7), "ООО «ВЕКТОР»",
|
||
Theme90.FS_MICRO, Theme90.INK)
|
||
Theme90.text(self, f, card.position + Vector2(10, 22), "Требуется 2 файла",
|
||
Theme90.FS_MICRO, Theme90.SHADE)
|
||
for j in 2:
|
||
draw_style_box(Theme90.well_box(Theme90.WHITE),
|
||
Rect2(card.position + Vector2(270 + j * 58, 12), Vector2(50, 32)))
|
||
|
||
# слоты
|
||
draw_style_box(Theme90.box(Theme90.PAPER_HI, Theme90.BORDER_SOFT, 4, 1), Rect2(8, 604, 1264, 52))
|
||
Theme90.text(self, f, Vector2(20, 620), "TCP", Theme90.FS_MICRO, Theme90.NAVY)
|
||
for i in 4:
|
||
draw_style_box(Theme90.well_box(Theme90.WHITE), Rect2(58 + i * 240, 610, 236, 40))
|
||
Theme90.text(self, f, Vector2(70 + i * 240, 622), "СЛОТ %d" % (i + 1),
|
||
Theme90.FS_MICRO, Theme90.SHADE)
|
||
|
||
# статус-бар
|
||
draw_rect(Rect2(0, 660, size.x, 60), Theme90.PAPER_HI)
|
||
draw_rect(Rect2(0, 660, size.x, 1), Theme90.HAIRLINE)
|
||
Theme90.text(self, f, Vector2(18, 672), "УЗЕЛ 7 НА СВЯЗИ · БУФЕР 3/4 · КАНАЛ 45%",
|
||
Theme90.FS_MICRO, Theme90.SHADE)
|
||
Theme90.text(self, f, Vector2(18, 693), "СМЕНА 3 · 03:42 / 08:00",
|
||
Theme90.FS_MICRO, Theme90.SHADE)
|
||
Theme90.text(self, lf, Vector2(1010, 680), "$ 1240", 12, Theme90.SUCCESS)
|
||
|
||
func _draw_window(r: Rect2, title: String) -> void:
|
||
draw_style_box(Theme90.box(Theme90.WHITE, Theme90.BORDER, 3, 1, Theme90.SHADOW), r)
|
||
var tr := Rect2(r.position.x + 1, r.position.y + 1, r.size.x - 2, 18)
|
||
draw_style_box(Theme90.top_box(Theme90.PAPER_HI, 3), tr)
|
||
draw_rect(Rect2(tr.position.x, tr.end.y, tr.size.x, 1), Theme90.HAIRLINE)
|
||
Theme90.text_vcenter(self, Theme90.ui(), Rect2(tr.position.x + 8, tr.position.y,
|
||
tr.size.x - 16, 18), title, Theme90.FS_MICRO, Theme90.NAVY)
|