From 8b6cd161c251df28ad956157991fa1066c5a4356 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 21 Feb 2023 13:50:36 +0700 Subject: [PATCH] Porting GUI to pyimgui --- ImguiWindow.py | 30 ++++- mm.py | 313 +++++++++++++++++++++++++++++-------------------- 2 files changed, 212 insertions(+), 131 deletions(-) diff --git a/ImguiWindow.py b/ImguiWindow.py index 6cb55b7..8ad44f9 100644 --- a/ImguiWindow.py +++ b/ImguiWindow.py @@ -5,6 +5,19 @@ import OpenGL.GL as gl import imgui as im from imgui.integrations.glfw import GlfwRenderer +from PIL import Image +import numpy as np + +def load_texture(filename): + image = Image.open(filename) + width, height = image.size + texture_id = gl.glGenTextures(1) + gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) + gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, np.array(image.convert("RGBA")).flatten()) + return texture_id + class ImguiWindow(): def impl_glfw_init(self, w, h): window_name = "minimal Imgui/GLFW3 example" @@ -33,18 +46,27 @@ class ImguiWindow(): return window - def __init__(self, draw_fn, window_name, width, height): + def __init__(self, init_fn, draw_fn, window_name, width, height): im.create_context() + self.window = self.impl_glfw_init(width, height) impl = GlfwRenderer(self.window) + # Load a new font + io = im.get_io() + new_font = io.fonts.add_font_from_file_ttf("/usr/share/fonts/TTF/RobotoMono-Regular.ttf", 24) + impl.refresh_font_texture() + + init_fn() + while not glfw.window_should_close(self.window): glfw.poll_events() impl.process_inputs() im.new_frame() - draw_fn() + with im.font(new_font): + draw_fn() gl.glClearColor(1., 1., 1., 1) gl.glClear(gl.GL_COLOR_BUFFER_BIT) @@ -55,7 +77,3 @@ class ImguiWindow(): impl.shutdown() glfw.terminate() - - - - diff --git a/mm.py b/mm.py index 3719853..e623251 100644 --- a/mm.py +++ b/mm.py @@ -1,38 +1,33 @@ from dateutil.parser import parse +from dataclasses import dataclass import sqlite3 as sql import PySimpleGUI as sg +from ImguiWindow import ImguiWindow, load_texture +import glfw +import imgui as im import random import datetime +def get_bank(): + cursor = conn.cursor() + cursor.execute(""" + SELECT resource.name,balance FROM bank_account + INNER JOIN resource ON resource.id = bank_account.resource_id + WHERE user_id = ? + """, (world.current_user_id,)) + bank = {name: balance for name,balance in cursor.fetchall()} + cursor.close() + return bank -conn = sql.connect("mm.db", check_same_thread=False) -conn.execute('PRAGMA foreign_keys = ON') - - -current_user = "Joe" -current_user_id = 1 - -cursor = conn.cursor() - -cursor.execute("SELECT id,name FROM resource") -resources = cursor.fetchall() -id_to_resource = {id: name for id, name in resources} -resource_to_id = {name: id for id, name in resources} - -cursor.execute(""" -SELECT resource.name,balance FROM bank_account -INNER JOIN resource ON resource.id = bank_account.resource_id -WHERE user_id = ? -""", (current_user_id,)) -bank = {name: balance for name,balance in cursor.fetchall()} - -cursor.execute(""" -SELECT store_item.id,store_item.name,resource.name,price,claim_amount FROM store_item -INNER JOIN resource ON resource.id = currency -""") -store = {item[0]:item[1:] for item in cursor.fetchall()} - -cursor.close() +def get_store_items(): + cursor = conn.cursor() + cursor.execute(""" + SELECT store_item.id,store_item.name,resource.name,price,claim_amount FROM store_item + INNER JOIN resource ON resource.id = currency + """) + items = {item[0]:item[1:] for item in cursor.fetchall()} + cursor.close() + return items def get_moons(): staking_sources = {} @@ -63,7 +58,7 @@ def get_inventory(): LEFT JOIN upgrade_event ON inventory_item.id = upgrade_event.inventory_item_id WHERE inventory_item.user_id = ? GROUP BY inventory_item.id; - """, (current_user_id,)) + """, (world.current_user_id,)) inventory = {item[0]:item[1:] for item in cursor.fetchall()} @@ -99,22 +94,23 @@ def mint(): try: cursor.execute(""" INSERT INTO staking_source (user_id, address) VALUES (?, ?) - """, (current_user_id, f"0x{rand_hash}")) + """, (world.current_user_id, f"0x{rand_hash}")) source_id = cursor.lastrowid - for id,_ in resources: + for id,_ in world.resources: init_supply = random.randint(50, 200) cursor.execute(""" INSERT INTO resource_well (source_id, resource_id, supply) VALUES (?, ?, ?) """, (source_id, id, init_supply)) conn.commit() - except sqlite3.Error as error: + except sql.Error as error: print(error) conn.rollback() finally: cursor.close() + world.staking_sources = get_moons() return source_id def buy_item(item_id): @@ -123,11 +119,12 @@ def buy_item(item_id): cursor.execute(""" INSERT INTO inventory_item (user_id, store_item_id) VALUES (?, ?) - """, (current_user_id, item_id)) + """, (world.current_user_id, item_id)) item_id = cursor.lastrowid conn.commit() cursor.close() + world.inventory = get_inventory() return item_id def mine(a,b,user_data): @@ -158,10 +155,11 @@ def sell(item_id): cursor = conn.cursor() cursor.execute("DELETE FROM inventory_item WHERE user_id = ? AND id = ?", - (current_user_id,item_id)) + (world.current_user_id, item_id)) conn.commit() cursor.close() + world.inventory = get_inventory() def sell_all(): cursor = conn.cursor() @@ -170,105 +168,170 @@ def sell_all(): conn.commit() cursor.close() + world.inventory = get_inventory() -bank_txts = [ f"{name.capitalize()}: {amount}" for name,amount in bank.items() ] -banks = " | ".join(bank_txts) +def draw_dashboard(): + im.text(f"Current User: {world.current_user}") + for _ in range(10): + im.spacing() + for name,balance in world.bank.items(): + im.text(f"{name.capitalize()}: {balance}") -def get_store_ui(): - inventory = get_inventory() - store_ui = [] - for id,(name,resource,price,claim) in store.items(): +def draw_store(): + for id,(name,resource,price,claim) in world.store.items(): owned = False - for (store_item_id,_) in inventory.values(): + for (store_item_id,_) in world.inventory.values(): if id == store_item_id: owned = True - store_ui.append([sg.Text(f"{name}: Mine {claim} {resource.capitalize()}"), - sg.Button(f"Buy {price} {resource[0:3]}", - key=("-BUY-",id), - disabled=owned)]) - return store_ui + im.text(f"{name}: Mine {claim} {resource.capitalize()}") -def inventory_row(item_id, si_id, tier): - name = store[si_id][0] - row = [sg.Text(f"{name} - Tier {tier+1}"), - sg.Button("Upgrade", key=("-UPGRADE-",item_id)), - sg.Button("Sell", key=("-SELL-",item_id))] - return [sg.pin(sg.Column([row], key=("-IROW-",item_id)))] + if owned: + im.text_disabled(f"Buy {price} {resource[0:3]}") + else: + im.push_id(f"Buy{id}") + if im.button(f"Buy {price} {resource[0:3]}"): + buy_item(id) + im.pop_id() + for _ in range(5): + im.spacing() -def moon_row(id,source): - wbtns = [] - for name,(supply,ts) in source[1].items(): - col = sg.Col([[sg.Text(name)], [sg.Button("Mine", key=("-MINE-",id,name))]]) - wbtns.append(col) - row = [sg.Image("moon.png"), sg.Column([wbtns])] - return [sg.pin(sg.Column([row, [sg.Button("Destroy", key=("-DESTROY-",id))]], key=("-MROW-",id)))] - -def get_inventory_ui(): - inventory_ui = [] - inventory = get_inventory() - for id,(si_id,tier) in inventory.items(): - inventory_ui.append(inventory_row(id,si_id,tier)) - return inventory_ui - -def get_sources_ui(): - staking_sources = get_moons() - sources_ui = [] - for id,source in staking_sources.items(): - sources_ui.append(moon_row(id,source)) - return sources_ui - -layout = [ - [sg.Text(f"User: {current_user}")], - [sg.Text(banks, key='-BANKS-')], - [sg.HorizontalSeparator()], - [sg.Button("Sell All", key="-SELLALL-")], - [[sg.Column(get_store_ui(), size=(400, 280),), - sg.Column(get_inventory_ui(), key="-ICOL-", vertical_alignment='t')]], - [sg.HorizontalSeparator()], - [sg.Button("Mint Moon", key="-MINT-")], - [sg.Column(layout=get_sources_ui(), key="-MCOL-", size=(1200, 500), - scrollable=True, vertical_scroll_only=True)] -] - -window = sg.Window("Moon Miner", layout, font='25') - -while True: - event, values = window.read() - if event == sg.WINDOW_CLOSED: - break - elif type(event) is tuple: - if event[0] == "-UPGRADE-": - sg.Window.Layout([[sg.Text("IT WORKED")]]) - elif event[0] == "-SELL-": - id = event[1] - inv = get_inventory() +def draw_inventory(): + for id,(sid,tier) in world.inventory.items(): + im.text(f"{id} - {world.store[sid][0]} - Tier {tier+1}") + im.push_id(f"Upgrade{id}") + if im.button("Upgrade"): + print("Upgrade") + im.pop_id() + im.same_line() + im.push_id(f"Sell{id}") + if im.button("Sell"): sell(id) - window[("-BUY-",inv[id][0])].update(disabled=False) - window[("-IROW-",id)].update(visible=False) - elif event[0] == "-BUY-": - id = event[1] - item_id = buy_item(id) - window[("-BUY-",id)].update(disabled=True) - window.extend_layout(window["-ICOL-"], [inventory_row(item_id,id,0)]) - elif event[0] == "-DESTROY-": - id = event[1] - destroy(id) - window[("-MROW-",id)].update(visible=False) - else: - if event == "-MINT-": - id = mint() - moons = get_moons() - window.extend_layout(window["-MCOL-"], [moon_row(id,moons[id])]) - elif event.startswith("-MINE-"): - print("Mine") - elif event == "-SELLALL-": - inv = get_inventory() - for item in inv: - window[("-IROW-",item)].update(visible=False) - for item in store: - window[("-BUY-",item)].update(disabled=False) - sell_all() + im.pop_id() + for _ in range(5): + im.spacing() +def draw_moons(): + if im.button("Mint"): + mint() + + im.begin_child("Moons") + im.columns(3, 'fileLlist') + im.set_column_width(0, 250) + im.set_column_width(1, 650) + im.separator() + im.text("Moon") + im.next_column() + im.text("Resources") + im.next_column() + im.text("Created") + im.next_column() + im.separator() + + for id,(ts,wells) in world.staking_sources.items(): + im.image(world.moon_img_tex_id, 240, 200) + im.next_column() + for well in wells: + im.button("Mine") + im.same_line() + im.text(well) + im.next_column() + im.text(str(ts)) + im.next_column() + im.separator() + + im.columns(1) + im.end_child() + +def draw_panels(): + screen_width, screen_height = glfw.get_video_mode(glfw.get_primary_monitor())[0] + + # Main + # TODO: This is probably not the right way to do this + im.set_next_window_size(screen_width, screen_height) + + # Set the next window position to (0, 0) to make the window cover the entire screen + im.set_next_window_position(0, 0) + + f = im.WINDOW_NO_TITLE_BAR | im.WINDOW_NO_RESIZE | im.WINDOW_NO_MOVE | im.WINDOW_NO_COLLAPSE + im.begin("Main", flags=f) + im.end() + + # Dashboard + im.set_next_window_position(0, 0) + im.set_next_window_size(400, 450) + f = im.WINDOW_NO_RESIZE | im.WINDOW_NO_MOVE + im.begin("Dashboard", flags=f) + + draw_dashboard() + + im.end() + + # Store + im.set_next_window_position(402, 0) + im.set_next_window_size(400, 450) + f = im.WINDOW_NO_RESIZE | im.WINDOW_NO_MOVE + im.begin("Store", flags=f) + + draw_store() + + im.end() + + # Inventory + im.set_next_window_position(802, 0) + im.set_next_window_size(400, 450) + f = im.WINDOW_NO_RESIZE | im.WINDOW_NO_MOVE + im.begin("Inventory", flags=f) + + draw_inventory() + + im.end() + + # Moons + im.set_next_window_position(0, 452) + im.set_next_window_size(1200, 540) + f = im.WINDOW_NO_RESIZE | im.WINDOW_NO_MOVE | im.WINDOW_ALWAYS_VERTICAL_SCROLLBAR + im.begin("Moons", flags=f) + + draw_moons() + + im.end() + +@dataclass +class World: + current_user = "Joe" + current_user_id = 1 + bank = dict() + resources = [] + id_to_resource = dict() + resource_to_id = dict() + store = dict() + inventory = dict() + staking_sources = dict() + moon_img_tex_id = -1 + +world = World() + +conn = sql.connect("mm.db", check_same_thread=False) +conn.execute('PRAGMA foreign_keys = ON') + +world.current_user = "Joe" +world.current_user_id = 1 + +cursor = conn.cursor() + +cursor.execute("SELECT id,name FROM resource") +world.resources = cursor.fetchall() +cursor.close() + +world.id_to_resource = {id: name for id, name in world.resources} +world.bank = get_bank() +world.store = get_store_items() +world.inventory = get_inventory() +world.staking_sources = get_moons() + +def imgui_init(): + world.moon_img_tex_id = texture_id = load_texture("moon.png") + +imguiWindow = ImguiWindow(imgui_init, draw_panels, "Moon Miner Test", 1200, 1000) -window.close() conn.close()