Porting GUI to pyimgui

This commit is contained in:
Joseph Ferano 2023-02-21 13:50:36 +07:00
parent b1b72d0fcc
commit 8b6cd161c2
2 changed files with 212 additions and 131 deletions

View File

@ -5,6 +5,19 @@ import OpenGL.GL as gl
import imgui as im import imgui as im
from imgui.integrations.glfw import GlfwRenderer 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(): class ImguiWindow():
def impl_glfw_init(self, w, h): def impl_glfw_init(self, w, h):
window_name = "minimal Imgui/GLFW3 example" window_name = "minimal Imgui/GLFW3 example"
@ -33,18 +46,27 @@ class ImguiWindow():
return window 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() im.create_context()
self.window = self.impl_glfw_init(width, height) self.window = self.impl_glfw_init(width, height)
impl = GlfwRenderer(self.window) 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): while not glfw.window_should_close(self.window):
glfw.poll_events() glfw.poll_events()
impl.process_inputs() impl.process_inputs()
im.new_frame() im.new_frame()
draw_fn() with im.font(new_font):
draw_fn()
gl.glClearColor(1., 1., 1., 1) gl.glClearColor(1., 1., 1., 1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT) gl.glClear(gl.GL_COLOR_BUFFER_BIT)
@ -55,7 +77,3 @@ class ImguiWindow():
impl.shutdown() impl.shutdown()
glfw.terminate() glfw.terminate()

313
mm.py
View File

@ -1,38 +1,33 @@
from dateutil.parser import parse from dateutil.parser import parse
from dataclasses import dataclass
import sqlite3 as sql import sqlite3 as sql
import PySimpleGUI as sg import PySimpleGUI as sg
from ImguiWindow import ImguiWindow, load_texture
import glfw
import imgui as im
import random import random
import datetime 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) def get_store_items():
conn.execute('PRAGMA foreign_keys = ON') cursor = conn.cursor()
cursor.execute("""
SELECT store_item.id,store_item.name,resource.name,price,claim_amount FROM store_item
current_user = "Joe" INNER JOIN resource ON resource.id = currency
current_user_id = 1 """)
items = {item[0]:item[1:] for item in cursor.fetchall()}
cursor = conn.cursor() cursor.close()
return items
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_moons(): def get_moons():
staking_sources = {} staking_sources = {}
@ -63,7 +58,7 @@ def get_inventory():
LEFT JOIN upgrade_event ON inventory_item.id = upgrade_event.inventory_item_id LEFT JOIN upgrade_event ON inventory_item.id = upgrade_event.inventory_item_id
WHERE inventory_item.user_id = ? WHERE inventory_item.user_id = ?
GROUP BY inventory_item.id; GROUP BY inventory_item.id;
""", (current_user_id,)) """, (world.current_user_id,))
inventory = {item[0]:item[1:] for item in cursor.fetchall()} inventory = {item[0]:item[1:] for item in cursor.fetchall()}
@ -99,22 +94,23 @@ def mint():
try: try:
cursor.execute(""" cursor.execute("""
INSERT INTO staking_source (user_id, address) VALUES (?, ?) 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 source_id = cursor.lastrowid
for id,_ in resources: for id,_ in world.resources:
init_supply = random.randint(50, 200) init_supply = random.randint(50, 200)
cursor.execute(""" cursor.execute("""
INSERT INTO resource_well (source_id, resource_id, supply) VALUES (?, ?, ?) INSERT INTO resource_well (source_id, resource_id, supply) VALUES (?, ?, ?)
""", (source_id, id, init_supply)) """, (source_id, id, init_supply))
conn.commit() conn.commit()
except sqlite3.Error as error: except sql.Error as error:
print(error) print(error)
conn.rollback() conn.rollback()
finally: finally:
cursor.close() cursor.close()
world.staking_sources = get_moons()
return source_id return source_id
def buy_item(item_id): def buy_item(item_id):
@ -123,11 +119,12 @@ def buy_item(item_id):
cursor.execute(""" cursor.execute("""
INSERT INTO inventory_item (user_id, store_item_id) INSERT INTO inventory_item (user_id, store_item_id)
VALUES (?, ?) VALUES (?, ?)
""", (current_user_id, item_id)) """, (world.current_user_id, item_id))
item_id = cursor.lastrowid item_id = cursor.lastrowid
conn.commit() conn.commit()
cursor.close() cursor.close()
world.inventory = get_inventory()
return item_id return item_id
def mine(a,b,user_data): def mine(a,b,user_data):
@ -158,10 +155,11 @@ def sell(item_id):
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM inventory_item WHERE user_id = ? AND id = ?", cursor.execute("DELETE FROM inventory_item WHERE user_id = ? AND id = ?",
(current_user_id,item_id)) (world.current_user_id, item_id))
conn.commit() conn.commit()
cursor.close() cursor.close()
world.inventory = get_inventory()
def sell_all(): def sell_all():
cursor = conn.cursor() cursor = conn.cursor()
@ -170,105 +168,170 @@ def sell_all():
conn.commit() conn.commit()
cursor.close() cursor.close()
world.inventory = get_inventory()
bank_txts = [ f"{name.capitalize()}: {amount}" for name,amount in bank.items() ] def draw_dashboard():
banks = " | ".join(bank_txts) 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(): def draw_store():
inventory = get_inventory() for id,(name,resource,price,claim) in world.store.items():
store_ui = []
for id,(name,resource,price,claim) in store.items():
owned = False owned = False
for (store_item_id,_) in inventory.values(): for (store_item_id,_) in world.inventory.values():
if id == store_item_id: if id == store_item_id:
owned = True owned = True
store_ui.append([sg.Text(f"{name}: Mine {claim} {resource.capitalize()}"), im.text(f"{name}: Mine {claim} {resource.capitalize()}")
sg.Button(f"Buy {price} {resource[0:3]}",
key=("-BUY-",id),
disabled=owned)])
return store_ui
def inventory_row(item_id, si_id, tier): if owned:
name = store[si_id][0] im.text_disabled(f"Buy {price} {resource[0:3]}")
row = [sg.Text(f"{name} - Tier {tier+1}"), else:
sg.Button("Upgrade", key=("-UPGRADE-",item_id)), im.push_id(f"Buy{id}")
sg.Button("Sell", key=("-SELL-",item_id))] if im.button(f"Buy {price} {resource[0:3]}"):
return [sg.pin(sg.Column([row], key=("-IROW-",item_id)))] buy_item(id)
im.pop_id()
for _ in range(5):
im.spacing()
def moon_row(id,source): def draw_inventory():
wbtns = [] for id,(sid,tier) in world.inventory.items():
for name,(supply,ts) in source[1].items(): im.text(f"{id} - {world.store[sid][0]} - Tier {tier+1}")
col = sg.Col([[sg.Text(name)], [sg.Button("Mine", key=("-MINE-",id,name))]]) im.push_id(f"Upgrade{id}")
wbtns.append(col) if im.button("Upgrade"):
row = [sg.Image("moon.png"), sg.Column([wbtns])] print("Upgrade")
return [sg.pin(sg.Column([row, [sg.Button("Destroy", key=("-DESTROY-",id))]], key=("-MROW-",id)))] im.pop_id()
im.same_line()
def get_inventory_ui(): im.push_id(f"Sell{id}")
inventory_ui = [] if im.button("Sell"):
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()
sell(id) sell(id)
window[("-BUY-",inv[id][0])].update(disabled=False) im.pop_id()
window[("-IROW-",id)].update(visible=False) for _ in range(5):
elif event[0] == "-BUY-": im.spacing()
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()
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() conn.close()