178 lines
5.1 KiB
Python
178 lines
5.1 KiB
Python
from kivy.app import App
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.uix.button import Button
|
|
from kivy.uix.label import Label
|
|
from kivy.metrics import dp
|
|
|
|
# 👉 import tvého numpadu (uprav cestu podle projektu)
|
|
from numberpad import NumberPad
|
|
|
|
|
|
# =====================================================
|
|
# IP + PORT INPUT (COMPACT)
|
|
# =====================================================
|
|
class IpPortInput(BoxLayout):
|
|
"""
|
|
mode:
|
|
"ip" → jen IP
|
|
"port" → jen port
|
|
"both" → IP + port
|
|
"""
|
|
|
|
def __init__(self, *, mode="both", ip="192.168.0.1", port=8000, on_done=None, **kwargs):
|
|
super().__init__(
|
|
orientation="vertical",
|
|
spacing=dp(5),
|
|
size_hint_y=None,
|
|
height=dp(120),
|
|
padding=dp(5),
|
|
**kwargs
|
|
)
|
|
|
|
self.mode = mode
|
|
self.on_done = on_done
|
|
|
|
self.ip_parts = self._parse_ip(ip)
|
|
self.port = str(port)
|
|
|
|
# ================= DISPLAY =================
|
|
self.lbl = Label(
|
|
text=self._format(),
|
|
size_hint_y=None,
|
|
height=dp(25),
|
|
halign="center",
|
|
valign="middle",
|
|
)
|
|
self.lbl.bind(size=lambda *_: setattr(self.lbl, "text_size", self.lbl.size))
|
|
self.add_widget(self.lbl)
|
|
|
|
# ================= BUTTON ROW =================
|
|
row = BoxLayout(spacing=dp(3), height=dp(45), size_hint_y=None)
|
|
|
|
self.btn_ip = []
|
|
if mode in ("ip", "both"):
|
|
for i in range(4):
|
|
b = Button(text=self.ip_parts[i], font_size=14)
|
|
b.bind(on_press=lambda inst, idx=i: self._edit_ip(idx))
|
|
self.btn_ip.append(b)
|
|
row.add_widget(b)
|
|
|
|
if mode in ("port", "both"):
|
|
self.btn_port = Button(text=self.port, font_size=14)
|
|
self.btn_port.bind(on_press=self._edit_port)
|
|
row.add_widget(self.btn_port)
|
|
|
|
self.add_widget(row)
|
|
|
|
# ================= OK BUTTON =================
|
|
btn_ok = Button(
|
|
text="OK",
|
|
size_hint_y=None,
|
|
height=dp(40),
|
|
background_color=(0.2, 0.6, 0.2, 1),
|
|
)
|
|
btn_ok.bind(on_press=self._done)
|
|
self.add_widget(btn_ok)
|
|
|
|
# =================================================
|
|
# PARSE / FORMAT
|
|
# =================================================
|
|
def _parse_ip(self, ip):
|
|
try:
|
|
parts = ip.split(".")
|
|
return [str(int(p)) for p in parts[:4]]
|
|
except Exception:
|
|
return ["192", "168", "0", "1"]
|
|
|
|
def _format(self):
|
|
if self.mode == "ip":
|
|
return ".".join(self.ip_parts)
|
|
if self.mode == "port":
|
|
return self.port
|
|
return f"{'.'.join(self.ip_parts)}:{self.port}"
|
|
|
|
def get_value(self):
|
|
if self.mode == "ip":
|
|
return ".".join(self.ip_parts)
|
|
if self.mode == "port":
|
|
return int(self.port)
|
|
return ".".join(self.ip_parts), int(self.port)
|
|
|
|
# =================================================
|
|
# EDIT IP PART
|
|
# =================================================
|
|
def _edit_ip(self, idx):
|
|
def done(val):
|
|
try:
|
|
v = int(val)
|
|
if 0 <= v <= 255:
|
|
self.ip_parts[idx] = str(v)
|
|
self.btn_ip[idx].text = str(v)
|
|
self._refresh()
|
|
except Exception:
|
|
pass
|
|
|
|
NumberPad(
|
|
mode="number",
|
|
max_len=3,
|
|
allow_fraction=False,
|
|
initial_value=self.ip_parts[idx],
|
|
on_accept=done,
|
|
).open()
|
|
|
|
# =================================================
|
|
# EDIT PORT
|
|
# =================================================
|
|
def _edit_port(self, *_):
|
|
def done(val):
|
|
try:
|
|
v = int(val)
|
|
if 0 <= v <= 65535:
|
|
self.port = str(v)
|
|
self.btn_port.text = str(v)
|
|
self._refresh()
|
|
except Exception:
|
|
pass
|
|
|
|
NumberPad(
|
|
mode="number",
|
|
max_len=5,
|
|
allow_fraction=False,
|
|
initial_value=self.port,
|
|
on_accept=done,
|
|
).open()
|
|
|
|
# =================================================
|
|
# REFRESH
|
|
# =================================================
|
|
def _refresh(self):
|
|
self.lbl.text = self._format()
|
|
|
|
# =================================================
|
|
# DONE
|
|
# =================================================
|
|
def _done(self, *_):
|
|
if self.on_done:
|
|
self.on_done(self.get_value())
|
|
|
|
|
|
# =====================================================
|
|
# TEST APP
|
|
# =====================================================
|
|
class TestApp(App):
|
|
def build(self):
|
|
root = BoxLayout(padding=dp(20))
|
|
|
|
widget = IpPortInput(
|
|
mode="both",
|
|
ip="10.0.0.5",
|
|
port=8080,
|
|
on_done=lambda v: print("RESULT:", v),
|
|
)
|
|
|
|
root.add_widget(widget)
|
|
return root
|
|
|
|
|
|
if __name__ == "__main__":
|
|
TestApp().run() |