📚 The CoCalc Library - books, templates and other resources
License: OTHER
#!/usr/bin/env python1#2# Copyright 2019 the original author or authors.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15#16import pygame17import numpy as np18from cmath import isclose19from .number_picker import NumberPicker20from .matrix_label import MatrixLabel21from vqe_playground.utils.labels import comp_graph_node_labels22from vqe_playground.utils.fonts import ARIAL_36232425class AdjacencyMatrix(pygame.sprite.RenderPlain):26ELEMENT_WIDTH_HEIGHT = 4827MAX_EDGE_VALUE = 42829"""UI control for maintaining adjacency matrix"""30def __init__(self, xpos, ypos, adj_matrix_numeric):31self.adj_matrix_numeric = adj_matrix_numeric32self.xpos = xpos33self.ypos = ypos3435self.adj_matrix_graph_dirty = False36self.num_nodes = adj_matrix_numeric.shape[0]37self.row_col_labels_dict = comp_graph_node_labels(self.num_nodes)38self.row_labels_list = self.create_row_labels_list()39self.col_labels_list = self.create_col_labels_list()40self.number_pickers_list = self.create_number_pickers_list()41pygame.sprite.RenderPlain.__init__(self,42self.row_labels_list,43self.col_labels_list,44self.number_pickers_list)45self.arrange()4647def create_number_pickers_list(self):48pickers = []49for row in range(self.num_nodes):50for col in range(self.num_nodes):51pickers.append(NumberPicker(self.adj_matrix_numeric[row, col],52self.ELEMENT_WIDTH_HEIGHT,53self.ELEMENT_WIDTH_HEIGHT,54row != col))55return pickers5657def create_row_labels_list(self):58row_labels = []59for row in range(self.num_nodes):60row_labels.append(MatrixLabel(self.row_col_labels_dict[row],61self.ELEMENT_WIDTH_HEIGHT,62self.ELEMENT_WIDTH_HEIGHT))63return row_labels6465def create_col_labels_list(self):66col_labels = []67for col in range(self.num_nodes):68col_labels.append(MatrixLabel(self.row_col_labels_dict[col],69self.ELEMENT_WIDTH_HEIGHT,70self.ELEMENT_WIDTH_HEIGHT))71return col_labels7273def arrange(self):74for col in range(self.num_nodes):75col_label = self.col_labels_list[col]76col_label.rect.left = self.xpos + (col + 1) * col_label.rect.width77col_label.rect.top = self.ypos7879for row in range(self.num_nodes):80row_label = self.row_labels_list[row]81row_label.rect.left = self.xpos82row_label.rect.top = self.ypos + (row + 1) * row_label.rect.height8384next_ypos = self.ypos + self.ELEMENT_WIDTH_HEIGHT85for row in range(self.num_nodes):86next_xpos = self.xpos + self.ELEMENT_WIDTH_HEIGHT87for col in range(self.num_nodes):88picker = self.number_pickers_list[row * self.num_nodes + col]89picker.rect.left = next_xpos90picker.rect.top = next_ypos91next_xpos += picker.rect.width92next_ypos += picker.rect.height9394def handle_element_clicked(self, picker):95for idx, picker_in_list in enumerate(self.number_pickers_list):96if picker == picker_in_list:97row = idx // self.num_nodes98col = idx % self.num_nodes99if row != col:100if isclose(picker_in_list.number, 0):101picker_in_list.number = 1102self.adj_matrix_graph_dirty = True103elif picker_in_list.number < self.MAX_EDGE_VALUE:104picker_in_list.number += 1105else:106picker_in_list.number = 0107self.adj_matrix_graph_dirty = True108109picker_in_list.draw_number_picker()110self.adj_matrix_numeric[row, col] = picker_in_list.number111112# Also update the other side113other_idx = col * self.num_nodes + row114other_picker = self.number_pickers_list[other_idx]115other_picker.number = picker_in_list.number116other_picker.draw_number_picker()117self.adj_matrix_numeric[col, row] = picker_in_list.number118119120