#!/usr/bin/env python3.5
# Copyright 2017 Digital
#
# This file is part of DigiLib.
#
# DigiLib is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DigiLib is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with DigiLib. If not, see .
#
## Imports
# Python Libraries
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import logging
import logging.config
import os
import pprint
import random
import string
import sys
import time
import yaml
# My libraries
import digilib.misc
## Logging
log = logging.getLogger(__name__+".gui")
## Global Variables
## Classes
class LabelName(Gtk.Label):
def __init__(self, *args,**kwargs):
super(LabelName, self).__init__(*args,**kwargs)
self.set_css_name("namelabel")
self.set_halign(Gtk.Align(2))
class LabelValue(Gtk.Label):
"""docstring for LabelValue"""
def __init__(self, *args,**kwargs):
super(LabelValue, self).__init__(*args,**kwargs)
self.set_css_name("valuelabel")
self.set_halign(Gtk.Align(1))
class InfoFrame(Gtk.Frame):
"""docstring for InfoFrame."""
def __init__(self,**kwargs):
super(InfoFrame, self).__init__(**kwargs)
self.lines = {
# id:{
# "layout": layout,
# "widgets": [label_name,label_value,widget],
# "update_func":widget_update_func
# }
}
self.current_line_no = 0
# self.layout = Gtk.Grid(halign=Gtk.Align(1))
self.layout = Gtk.Grid()
self.layout.set_row_spacing(10)
self.layout.set_column_spacing(5)
self.layout.set_column_homogeneous(False)
self.layout.set_hexpand(True)
self.add(self.layout)
def add_line(
self,
identifier,
name,
value,
unit=None,
widget=None,
widget_update_func=None
):
if id in self.lines.keys():
raise ValueError(
"Identifiers must be uniqe, but '"
+identifier
+"' already exists!"
)
self.lines[identifier] = {
"layout":None,
"wname":None,
"wvalue":None,
"wunit":None,
"wextra":None,
"update_func":None
}
self.lines[identifier]["update_func"] = widget_update_func
# if there is a widget and an update function was passed then update it
if widget_update_func == True:
self.lines[identifier]["update_func"] = widget.set_value
if self.lines[identifier]["update_func"]:
self.lines[identifier]["update_func"](value)
layout = Gtk.Box()
layout.set_spacing(5)
layout.set_homogeneous(False)
self.lines[identifier]["layout"] = layout
# create the labels for the name and value field and also for the unit
# field if an unit was specified
label_name = LabelName(name)
self.lines[identifier]["wname"] = label_name
self.layout.attach(label_name,0,self.current_line_no,1,1)
label_value = LabelValue(value)
self.lines[identifier]["wvalue"] = label_value
layout.add(label_value)
if unit:
label_unit = LabelValue(unit)
self.lines[identifier]["wunit"] = label_unit
layout.add(label_unit)
if widget:
self.lines[identifier]["wextra"] = widget
layout.add(widget)
self.layout.attach(layout,1,self.current_line_no,1,1)
self.current_line_no += 1
def update_name(self,identifier,name):
self.lines[identifier]["wname"].set_label(name)
def update_unit(self,identifier,unit):
self.lines[identifier]["wunit"].set_label(unit)
def update_value(self,identifier,value):
self.lines[identifier]["wvalue"].set_label(str(value))
if self.lines[identifier]["update_func"]:
self.lines[identifier]["update_func"](value)
print(1)
# class ChildGrid(Gtk.Grid):
# def __init__(self):
# super(ChildGrid,self).__init__()
# self.prepare()
# def prepare(self):
# pass
#
# class ChildScrollBase(Gtk.ScrolledWindow):
# def __init__(self):
# super(ChildScroll,self).__init__()
# self.prepare()
# def prepare(self):
# pass
class ChildConsole(Gtk.Grid):
scroll = True
history_list = []
history_position = -1
def __init__(self,get_client):
super(ChildConsole,self).__init__()
self.get_client = get_client
self.set_css_name("tab_console")
self.prepare()
self.button_send.connect("clicked",self.on_entry_activated)
self.entry_cmd.connect("activate",self.on_entry_activated)
self.entry_cmd.connect("key-press-event",self.on_keypress)
def prepare(self):
self.scroll_mark = Gtk.TextMark(name="scroll_mark")
self.text_buffer_log = Gtk.TextBuffer()
self.text_view_log = Gtk.TextView(hexpand=True,vexpand=True)
self.text_view_log.set_buffer(self.text_buffer_log)
self.text_view_log.set_editable(False)
self.text_view_log.set_cursor_visible(False)
self.text_view_log.props.pixels_above_lines = 2
self.text_view_log.props.pixels_below_lines = 2
self.text_view_log.props.right_margin = 2
self.text_view_log.props.left_margin = 6
# self.text_view_log.set_hexpand(True)
# self.text_view_log.set_vexpand(True)
self.scrolled_window = Gtk.ScrolledWindow()
self.entry_cmd = Gtk.Entry(hexpand=True)
# self.entry_cmd.set_cursor_hadjustment(Gtk.Align(2))
# self.entry_cmd.set_hexpand(True)
self.button_send = Gtk.Button(label="send")
# self.button_send.set_label("send")
self.scrolled_window.add(self.text_view_log)
self.attach(self.scrolled_window,0,1,2,1)
self.attach(self.entry_cmd,0,2,1,1)
self.attach(self.button_send,1,2,1,1)
def add_msg(self,text,sender_name="Server"):
for line in text.splitlines():
if sender_name:
line = sender_name+":"+line
self.text_buffer_log.insert(
self.text_buffer_log.get_end_iter(),
"\n"+line.rstrip()
)
self.scroll_down(None)
if self.scroll:
self.scroll_down(None)
def add_msg_threadsafe(self,*args,**kwargs):
Gdk.threads_enter()
self.add_msg(*args,**kwargs)
Gdk.threads_leave()
def send(self,text):
client = self.get_client()
if client:
if client.is_connected:
client.send(text)
def scroll_down(self,*args):
self.scroll = True
self.text_buffer_log.add_mark(
self.scroll_mark,
self.text_buffer_log.get_end_iter()
)
self.text_view_log.scroll_to_mark(
mark=self.scroll_mark,
# No idea what these arguments do, but they work.
within_margin=0.0,
use_align=True,
xalign=0.5,
yalign=0.5
)
self.text_buffer_log.delete_mark(self.scroll_mark)
def toggle_scroll(self,*args):
self.scroll = not self.scroll
def get_entry_text(self):
text = self.entry_cmd.get_text()
self.entry_cmd.set_text("")
return text
def on_entry_activated(self,widget):
text = self.get_entry_text()
if text.strip():
self.history_position = -1
if len(self.history_list) == 0:
self.history_list.insert(0,text)
else:
if self.history_list[0] != text:
self.history_list.insert(0,text)
self.add_msg(text,"you")
self.send(text)
def on_keypress(self,widget,event):
if not widget == self.entry_cmd:
lgui.debug("exiting keypress event function because the widget was \
not self.entry_cmd")
return True
if event.keyval == Gdk.KEY_Up: # Up
if self.history_position < len(self.history_list)-1:
self.history_position += 1
text = self.history_list[self.history_position]
self.entry_cmd.set_text(text)
self.entry_cmd.set_position(len(text))
return True
elif event.keyval == Gdk.KEY_Down: # Down
text = self.entry_cmd.get_text()
if self.history_position == -1 and text != "":
self.entry_cmd.set_text("")
elif self.history_position == 0:
self.history_position = -1
self.entry_cmd.set_text("")
elif self.history_position > 0:
self.history_position -= 1
text = self.history_list[self.history_position]
self.entry_cmd.set_text(text)
self.entry_cmd.set_position(len(text))
return True
class ChildOverview(Gtk.ScrolledWindow):
def __init__(self):
super(ChildOverview,self).__init__()
self.set_css_name("tab_overview")
self.layout = Gtk.Grid()
self.layout.set_column_homogeneous(True)
self.add(self.layout)
class ChildControl(Gtk.Grid):
def __init__(self):
super(ChildControl,self).__init__()
self.label = Gtk.Label()
self.label.set_markup("Another fancy self.label")
self.add(self.label)
class ChildSettings(Gtk.Grid):
def __init__(self):
super(ChildSettings,self).__init__()
self.label = Gtk.Label()
self.label.set_markup("Another fancy self.label")
self.add(self.label)
class WindowBase(Gtk.Window):
def __init__(self,title="Don't Panic!"):
super(Gtk.Window,self).__init__(title=title)
self.pressed_keys = []
self.key_shortcuts = []
self.connect("delete-event",self.on_delete_event)
self.connect("key-press-event",self.on_key_press_event)
self.connect("key-release-event",self.on_key_release_event)
def keystring_to_gkd(self, keys):
key_list = keys.split(" ")
known_keys = []
unknown_keys = []
for k in key_list:
if "KEY_"+k in dir(Gdk):
known_keys.append(eval("Gdk.KEY_"+k))
else:
unknown_keys.append(k)
if unknown_keys:
raise ValueError("Unknown Keys: "+", ".join(unknown_keys))
else:
return known_keys
def add_key_shortcut(self,keys,func=None,args=[],kwargs={}):
key_list = self.keystring_to_gkd(keys)
for ks in self.key_shortcuts:
if key_list == ks[0]:
self.key_shortcuts.remove(ks)
break
self.key_shortcuts.append([key_list,func,args,kwargs])
def remove_key_shortcut(self,keys):
key_list = self.keystring_to_gkd(keys)
for ks in self.key_shortcuts:
if key_list == ks[0]:
self.key_shortcuts.remove(ks)
break
def on_delete_event(self,*args):
print(args)
Gtk.main_quit()
def on_key_release_event(self,widget,event):
if event.keyval in self.pressed_keys:
self.pressed_keys.remove(event.keyval)
def on_key_press_event(self,widget,event):
self.pressed_keys.append(event.keyval)
for keys,func,args,kwargs in self.key_shortcuts:
if keys == self.pressed_keys:
func(*args,**kwargs)
break
def hello_world(self,*args):
print("hello world")
#