import math import gi from gi.repository import Gdk gi.require_version('Gtk', '3.0') from gi.repository import Gtk def rad(n): return n/360*(2*3.1415) class ButtonWrapper(Gtk.Button): def __init__(self, *args, **kwds): super().__init__(*args, **kwds) self.connect("clicked", self.on_click) self.select() self.sel=None self.definition=None self.color=0 self.index=0 self.colors=[(0x20/0xff,0x20/0xff,0x20/0xff), (0x20/0xff,0xE0/0xff,0xE0/0xff)] self.is_selected=False self._btn_selected=None self._btn_unselected=None self.show=True self.show_all() def on_click(self, x): if self.is_selected: if self._btn_unselected: self._btn_unselected(self.index, self) else: if self._btn_selected: self._btn_selected(self.index, self) def do_draw(self, cr): if not self.show: return allocation = self.get_allocation() fg_color = self.get_style_context().get_color(Gtk.StateFlags.NORMAL) cr.set_source_rgba(*self.colors[0]); cr.rectangle(4,4,allocation.width-8, allocation.height-8) cr.stroke() cr.set_source_rgba(*self.colors[self.color]); cr.rectangle(6,6,allocation.width-12, allocation.height-12) cr.fill() def select(self): self.is_selected=True self.color=1 def unselect(self): self.is_selected=False self.color=0 @staticmethod def new(sel, mat, index): btn = ButtonWrapper() btn.sel=sel btn.definition=mat btn.index=index return btn class GtkButtonGrid(Gtk.Grid): def __init__(self, *args, **kwds): super().__init__(*args, **kwds) self.width=0 self.height=0 self.map=[] self.x=0 self.y=0 self.sel=None self.type=None self._btn_selected=None self._btn_unselected=None self.set_hexpand(True) self.set_vexpand(True) self.set_row_homogeneous(True) self.set_column_homogeneous(True) def set_on_select(self, b): self._btn_selected=b def set_on_unselect(self, b): self._btn_unselected=b def unselect_all(self): for k in self.map: k.unselect() def new(self, x, y, sel, t): btn = GtkButtonGrid() btn.x=x btn.y=y btn.sel=sel btn.type=type return btn def update(self): self.queue_draw() def select(self, i, j=-1): if j>=0: i+=j*self.width if self.map[i]: self.map[i].select() def unselect(self, i, j=-1): if j>=0: i+=j*self.width if self.map[i]: self.map[i].unselect() def set_grid_size(self, x, y): for i in range(self.width): self.remove_column(0) for i in range(self.height): self.remove_row(0) self.width=x self.height=y self.map=[] for i in range(x*y): self.map.append(None) for i in range(self.width): self.insert_column(0) for i in range(self.height): self.insert_row(0) self.show_all() def __getitem__(self, item): if isinstance(item, (tuple, list)): item=item[0]+item[1]*self.width return self.map[item] def __setitem__(self, key, value): if isinstance(key, (tuple, list)): key=key[0]+key[1]*self.width x=key%self.width y=math.floor(key/self.width) if(value[1]): self.map[key]=ButtonWrapper.new(value[0], value[1], value[2]) self.map[key]._btn_selected=self._btn_selected self.map[key]._btn_unselected=self._btn_unselected self.attach(self.map[key], x,y,1,1) else: self.map[key]=ButtonWrapper.new(value[0], value[1], value[2]) self.map[key].show=False self.attach(self.map[key], x,y,1,1) return self.map[key]