__init__.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #!/usr/bin/env python3.5
  2. # Copyright 2017 Digital
  3. #
  4. # This file is part of DigiLib.
  5. #
  6. # DigiLib is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # DigiLib is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with DigiLib. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. ## Imports
  20. # Python Libraries
  21. import gi
  22. gi.require_version('Gtk', '3.0')
  23. from gi.repository import Gtk
  24. from gi.repository import Gdk
  25. import logging
  26. import logging.config
  27. import os
  28. import pprint
  29. import random
  30. import string
  31. import sys
  32. import time
  33. import yaml
  34. # My libraries
  35. import digilib.misc
  36. ## Logging
  37. log = logging.getLogger(__name__+".gui")
  38. ## Global Variables
  39. ## Classes
  40. class LabelName(Gtk.Label):
  41. def __init__(self, *args,**kwargs):
  42. super(LabelName, self).__init__(*args,**kwargs)
  43. self.set_css_name("namelabel")
  44. self.set_halign(Gtk.Align(2))
  45. class LabelValue(Gtk.Label):
  46. """docstring for LabelValue"""
  47. def __init__(self, *args,**kwargs):
  48. super(LabelValue, self).__init__(*args,**kwargs)
  49. self.set_css_name("valuelabel")
  50. self.set_halign(Gtk.Align(1))
  51. class InfoFrame(Gtk.Frame):
  52. """docstring for InfoFrame."""
  53. def __init__(self,**kwargs):
  54. super(InfoFrame, self).__init__(**kwargs)
  55. self.lines = {
  56. # id:{
  57. # "layout": layout,
  58. # "widgets": [label_name,label_value,widget],
  59. # "update_func":widget_update_func
  60. # }
  61. }
  62. self.current_line_no = 0
  63. # self.layout = Gtk.Grid(halign=Gtk.Align(1))
  64. self.layout = Gtk.Grid()
  65. self.layout.set_row_spacing(10)
  66. self.layout.set_column_spacing(5)
  67. self.layout.set_column_homogeneous(False)
  68. self.layout.set_hexpand(True)
  69. self.add(self.layout)
  70. def add_line(
  71. self,
  72. identifier,
  73. name,
  74. value,
  75. unit=None,
  76. widget=None,
  77. widget_update_func=None
  78. ):
  79. if id in self.lines.keys():
  80. raise ValueError(
  81. "Identifiers must be uniqe, but '"
  82. +identifier
  83. +"' already exists!"
  84. )
  85. self.lines[identifier] = {
  86. "layout":None,
  87. "wname":None,
  88. "wvalue":None,
  89. "wunit":None,
  90. "wextra":None,
  91. "update_func":None
  92. }
  93. self.lines[identifier]["update_func"] = widget_update_func
  94. # if there is a widget and an update function was passed then update it
  95. if widget_update_func == True:
  96. self.lines[identifier]["update_func"] = widget.set_value
  97. if self.lines[identifier]["update_func"]:
  98. self.lines[identifier]["update_func"](value)
  99. layout = Gtk.Box()
  100. layout.set_spacing(5)
  101. layout.set_homogeneous(False)
  102. self.lines[identifier]["layout"] = layout
  103. # create the labels for the name and value field and also for the unit
  104. # field if an unit was specified
  105. label_name = LabelName(name)
  106. self.lines[identifier]["wname"] = label_name
  107. self.layout.attach(label_name,0,self.current_line_no,1,1)
  108. label_value = LabelValue(value)
  109. self.lines[identifier]["wvalue"] = label_value
  110. layout.add(label_value)
  111. if unit:
  112. label_unit = LabelValue(unit)
  113. self.lines[identifier]["wunit"] = label_unit
  114. layout.add(label_unit)
  115. if widget:
  116. self.lines[identifier]["wextra"] = widget
  117. layout.add(widget)
  118. self.layout.attach(layout,1,self.current_line_no,1,1)
  119. self.current_line_no += 1
  120. def update_name(self,identifier,name):
  121. self.lines[identifier]["wname"].set_label(name)
  122. def update_unit(self,identifier,unit):
  123. self.lines[identifier]["wunit"].set_label(unit)
  124. def update_value(self,identifier,value):
  125. self.lines[identifier]["wvalue"].set_label(str(value))
  126. if self.lines[identifier]["update_func"]:
  127. self.lines[identifier]["update_func"](value)
  128. print(1)
  129. # class ChildGrid(Gtk.Grid):
  130. # def __init__(self):
  131. # super(ChildGrid,self).__init__()
  132. # self.prepare()
  133. # def prepare(self):
  134. # pass
  135. #
  136. # class ChildScrollBase(Gtk.ScrolledWindow):
  137. # def __init__(self):
  138. # super(ChildScroll,self).__init__()
  139. # self.prepare()
  140. # def prepare(self):
  141. # pass
  142. class ChildConsole(Gtk.Grid):
  143. scroll = True
  144. history_list = []
  145. history_position = -1
  146. def __init__(self,get_client):
  147. super(ChildConsole,self).__init__()
  148. self.get_client = get_client
  149. self.set_css_name("tab_console")
  150. self.prepare()
  151. self.button_send.connect("clicked",self.on_entry_activated)
  152. self.entry_cmd.connect("activate",self.on_entry_activated)
  153. self.entry_cmd.connect("key-press-event",self.on_keypress)
  154. def prepare(self):
  155. self.scroll_mark = Gtk.TextMark(name="scroll_mark")
  156. self.text_buffer_log = Gtk.TextBuffer()
  157. self.text_view_log = Gtk.TextView(hexpand=True,vexpand=True)
  158. self.text_view_log.set_buffer(self.text_buffer_log)
  159. self.text_view_log.set_editable(False)
  160. self.text_view_log.set_cursor_visible(False)
  161. self.text_view_log.props.pixels_above_lines = 2
  162. self.text_view_log.props.pixels_below_lines = 2
  163. self.text_view_log.props.right_margin = 2
  164. self.text_view_log.props.left_margin = 6
  165. # self.text_view_log.set_hexpand(True)
  166. # self.text_view_log.set_vexpand(True)
  167. self.scrolled_window = Gtk.ScrolledWindow()
  168. self.entry_cmd = Gtk.Entry(hexpand=True)
  169. # self.entry_cmd.set_cursor_hadjustment(Gtk.Align(2))
  170. # self.entry_cmd.set_hexpand(True)
  171. self.button_send = Gtk.Button(label="send")
  172. # self.button_send.set_label("send")
  173. self.scrolled_window.add(self.text_view_log)
  174. self.attach(self.scrolled_window,0,1,2,1)
  175. self.attach(self.entry_cmd,0,2,1,1)
  176. self.attach(self.button_send,1,2,1,1)
  177. def add_msg(self,text,sender_name="Server"):
  178. for line in text.splitlines():
  179. if sender_name:
  180. line = sender_name+":"+line
  181. self.text_buffer_log.insert(
  182. self.text_buffer_log.get_end_iter(),
  183. "\n"+line.rstrip()
  184. )
  185. self.scroll_down(None)
  186. if self.scroll:
  187. self.scroll_down(None)
  188. def add_msg_threadsafe(self,*args,**kwargs):
  189. Gdk.threads_enter()
  190. self.add_msg(*args,**kwargs)
  191. Gdk.threads_leave()
  192. def send(self,text):
  193. client = self.get_client()
  194. if client:
  195. if client.is_connected:
  196. client.send(text)
  197. def scroll_down(self,*args):
  198. self.scroll = True
  199. self.text_buffer_log.add_mark(
  200. self.scroll_mark,
  201. self.text_buffer_log.get_end_iter()
  202. )
  203. self.text_view_log.scroll_to_mark(
  204. mark=self.scroll_mark,
  205. # No idea what these arguments do, but they work.
  206. within_margin=0.0,
  207. use_align=True,
  208. xalign=0.5,
  209. yalign=0.5
  210. )
  211. self.text_buffer_log.delete_mark(self.scroll_mark)
  212. def toggle_scroll(self,*args):
  213. self.scroll = not self.scroll
  214. def get_entry_text(self):
  215. text = self.entry_cmd.get_text()
  216. self.entry_cmd.set_text("")
  217. return text
  218. def on_entry_activated(self,widget):
  219. text = self.get_entry_text()
  220. if text.strip():
  221. self.history_position = -1
  222. if len(self.history_list) == 0:
  223. self.history_list.insert(0,text)
  224. else:
  225. if self.history_list[0] != text:
  226. self.history_list.insert(0,text)
  227. self.add_msg(text,"you")
  228. self.send(text)
  229. def on_keypress(self,widget,event):
  230. if not widget == self.entry_cmd:
  231. lgui.debug("exiting keypress event function because the widget was \
  232. not self.entry_cmd")
  233. return True
  234. if event.keyval == Gdk.KEY_Up: # Up
  235. if self.history_position < len(self.history_list)-1:
  236. self.history_position += 1
  237. text = self.history_list[self.history_position]
  238. self.entry_cmd.set_text(text)
  239. self.entry_cmd.set_position(len(text))
  240. return True
  241. elif event.keyval == Gdk.KEY_Down: # Down
  242. text = self.entry_cmd.get_text()
  243. if self.history_position == -1 and text != "":
  244. self.entry_cmd.set_text("")
  245. elif self.history_position == 0:
  246. self.history_position = -1
  247. self.entry_cmd.set_text("")
  248. elif self.history_position > 0:
  249. self.history_position -= 1
  250. text = self.history_list[self.history_position]
  251. self.entry_cmd.set_text(text)
  252. self.entry_cmd.set_position(len(text))
  253. return True
  254. class ChildOverview(Gtk.ScrolledWindow):
  255. def __init__(self):
  256. super(ChildOverview,self).__init__()
  257. self.set_css_name("tab_overview")
  258. self.layout = Gtk.Grid()
  259. self.layout.set_column_homogeneous(True)
  260. self.add(self.layout)
  261. class ChildControl(Gtk.Grid):
  262. def __init__(self):
  263. super(ChildControl,self).__init__()
  264. self.label = Gtk.Label()
  265. self.label.set_markup("<big>Another fancy self.label</big>")
  266. self.add(self.label)
  267. class ChildSettings(Gtk.Grid):
  268. def __init__(self):
  269. super(ChildSettings,self).__init__()
  270. self.label = Gtk.Label()
  271. self.label.set_markup("<big>Another fancy self.label</big>")
  272. self.add(self.label)
  273. class WindowBase(Gtk.Window):
  274. def __init__(self,title="Don't Panic!"):
  275. super(Gtk.Window,self).__init__(title=title)
  276. self.pressed_keys = []
  277. self.key_shortcuts = []
  278. self.connect("delete-event",self.on_delete_event)
  279. self.connect("key-press-event",self.on_key_press_event)
  280. self.connect("key-release-event",self.on_key_release_event)
  281. def keystring_to_gkd(self, keys):
  282. key_list = keys.split(" ")
  283. known_keys = []
  284. unknown_keys = []
  285. for k in key_list:
  286. if "KEY_"+k in dir(Gdk):
  287. known_keys.append(eval("Gdk.KEY_"+k))
  288. else:
  289. unknown_keys.append(k)
  290. if unknown_keys:
  291. raise ValueError("Unknown Keys: "+", ".join(unknown_keys))
  292. else:
  293. return known_keys
  294. def add_key_shortcut(self,keys,func=None,args=[],kwargs={}):
  295. key_list = self.keystring_to_gkd(keys)
  296. for ks in self.key_shortcuts:
  297. if key_list == ks[0]:
  298. self.key_shortcuts.remove(ks)
  299. break
  300. self.key_shortcuts.append([key_list,func,args,kwargs])
  301. def remove_key_shortcut(self,keys):
  302. key_list = self.keystring_to_gkd(keys)
  303. for ks in self.key_shortcuts:
  304. if key_list == ks[0]:
  305. self.key_shortcuts.remove(ks)
  306. break
  307. def on_delete_event(self,*args):
  308. print(args)
  309. Gtk.main_quit()
  310. def on_key_release_event(self,widget,event):
  311. if event.keyval in self.pressed_keys:
  312. self.pressed_keys.remove(event.keyval)
  313. def on_key_press_event(self,widget,event):
  314. self.pressed_keys.append(event.keyval)
  315. for keys,func,args,kwargs in self.key_shortcuts:
  316. if keys == self.pressed_keys:
  317. func(*args,**kwargs)
  318. break
  319. def hello_world(self,*args):
  320. print("hello world")
  321. #