Show some dialogs in Mines and ToaruPaint
This commit is contained in:
parent
2c05f6d065
commit
32e68de909
@ -15,10 +15,13 @@ import toaru_fonts
|
||||
from button import Button, rounded_rectangle
|
||||
from menu_bar import MenuBarWidget, MenuEntryAction, MenuEntrySubmenu, MenuEntryDivider, MenuWindow
|
||||
|
||||
from dialog import DialogWindow
|
||||
|
||||
import yutani_mainloop
|
||||
|
||||
version = "0.1.0"
|
||||
_description = f"<b>Mines {version}</b>\n© 2017 Kevin Lange\n\nClassic logic game.\n\n<color 0x0000FF>http://github.com/klange/toaruos</color>"
|
||||
app_name = "Mines"
|
||||
_description = f"<b>{app_name} {version}</b>\n© 2017 Kevin Lange\n\nClassic logic game.\n\n<color 0x0000FF>http://github.com/klange/toaruos</color>"
|
||||
|
||||
class MineButton(Button):
|
||||
|
||||
@ -77,75 +80,10 @@ class MinesWindow(yutani.Window):
|
||||
base_height = 440
|
||||
|
||||
def __init__(self, decorator):
|
||||
super(MinesWindow, self).__init__(self.base_width + decorator.width(), self.base_height + decorator.height(), title="Mines", icon="mines", doublebuffer=True)
|
||||
super(MinesWindow, self).__init__(self.base_width + decorator.width(), self.base_height + decorator.height(), title=app_name, icon="mines", doublebuffer=True)
|
||||
self.move(100,100)
|
||||
self.decorator = decorator
|
||||
|
||||
def new_game(action):
|
||||
def mine_func(b):
|
||||
button = b
|
||||
if self.first_click:
|
||||
while button.is_mine or button.mines:
|
||||
new_game(action)
|
||||
button = self.buttons[button.row][button.col]
|
||||
self.first_click = False
|
||||
if button.flagged:
|
||||
return
|
||||
if button.is_mine:
|
||||
self.tr.set_text("You lose.")
|
||||
for row in self.buttons:
|
||||
for b in row:
|
||||
b.reveal()
|
||||
self.draw()
|
||||
return
|
||||
else:
|
||||
if not button.revealed:
|
||||
button.reveal()
|
||||
if button.mines == 0:
|
||||
n = [x for x in check_neighbor_buttons(button.row,button.col) if not x.revealed]
|
||||
while n:
|
||||
b = n.pop()
|
||||
b.reveal()
|
||||
if b.mines == 0:
|
||||
n.extend([x for x in check_neighbor_buttons(b.row,b.col) if not x.revealed and not x in n])
|
||||
self.check_win()
|
||||
|
||||
self.field_size, self.mine_count = action
|
||||
self.first_click = True
|
||||
self.tr.set_text(f"There are {self.mine_count} mines.")
|
||||
|
||||
self.mines = []
|
||||
while len(self.mines) < self.mine_count:
|
||||
x,y = random.randrange(self.field_size),random.randrange(self.field_size)
|
||||
if not (x,y) in self.mines:
|
||||
self.mines.append((x,y))
|
||||
|
||||
def check_neighbors(r,c):
|
||||
n = []
|
||||
if r > 0:
|
||||
if c > 0: n.append((r-1,c-1))
|
||||
n.append((r-1,c))
|
||||
if c < self.field_size-1: n.append((r-1,c+1))
|
||||
if r < self.field_size-1:
|
||||
if c > 0: n.append((r+1,c-1))
|
||||
n.append((r+1,c))
|
||||
if c < self.field_size-1: n.append((r+1,c+1))
|
||||
if c > 0: n.append((r,c-1))
|
||||
if c < self.field_size-1: n.append((r,c+1))
|
||||
return n
|
||||
|
||||
def check_neighbor_buttons(r,c):
|
||||
return [self.buttons[x][y] for x,y in check_neighbors(r,c)]
|
||||
|
||||
self.buttons = []
|
||||
for row in range(self.field_size):
|
||||
r = []
|
||||
for col in range(self.field_size):
|
||||
is_mine = (row,col) in self.mines
|
||||
neighbor_mines = len([x for x in check_neighbors(row,col) if x in self.mines])
|
||||
r.append(MineButton(mine_func,row,col,is_mine,neighbor_mines))
|
||||
self.buttons.append(r)
|
||||
|
||||
def exit_app(action):
|
||||
menus = [x for x in self.menus.values()]
|
||||
for x in menus:
|
||||
@ -153,15 +91,15 @@ class MinesWindow(yutani.Window):
|
||||
self.close()
|
||||
sys.exit(0)
|
||||
def about_window(action):
|
||||
subprocess.Popen(["about-applet.py","About Mines","mines","/usr/share/icons/48/mines.png",_description])
|
||||
subprocess.Popen(["about-applet.py",f"About {app_name}","mines","/usr/share/icons/48/mines.png",_description])
|
||||
def help_browser(action):
|
||||
subprocess.Popen(["help-browser.py","mines.trt"])
|
||||
menus = [
|
||||
("File", [
|
||||
MenuEntrySubmenu("New Game...",[
|
||||
MenuEntryAction("9×9, 10 mines",None,new_game,(9,10)),
|
||||
MenuEntryAction("16×16, 40 mines",None,new_game,(16,40)),
|
||||
MenuEntryAction("20×20, 90 mines",None,new_game,(20,90)),
|
||||
MenuEntryAction("9×9, 10 mines",None,self.new_game,(9,10)),
|
||||
MenuEntryAction("16×16, 40 mines",None,self.new_game,(16,40)),
|
||||
MenuEntryAction("20×20, 90 mines",None,self.new_game,(20,90)),
|
||||
],icon="new"),
|
||||
MenuEntryDivider(),
|
||||
MenuEntryAction("Exit","exit",exit_app,None),
|
||||
@ -169,7 +107,7 @@ class MinesWindow(yutani.Window):
|
||||
("Help", [
|
||||
MenuEntryAction("Contents","help",help_browser,None),
|
||||
MenuEntryDivider(),
|
||||
MenuEntryAction("About Mines","star",about_window,None),
|
||||
MenuEntryAction(f"About {app_name}","star",about_window,None),
|
||||
]),
|
||||
]
|
||||
|
||||
@ -192,7 +130,76 @@ class MinesWindow(yutani.Window):
|
||||
self.hovered_menu = None
|
||||
self.modifiers = 0
|
||||
|
||||
new_game((9,10))
|
||||
self.new_game((9,10))
|
||||
|
||||
def new_game(self,action):
|
||||
def mine_func(b):
|
||||
button = b
|
||||
if self.first_click:
|
||||
while button.is_mine or button.mines:
|
||||
self.new_game(action)
|
||||
button = self.buttons[button.row][button.col]
|
||||
self.first_click = False
|
||||
if button.flagged:
|
||||
return
|
||||
if button.is_mine:
|
||||
self.tr.set_text("You lose.")
|
||||
for row in self.buttons:
|
||||
for b in row:
|
||||
b.reveal()
|
||||
self.draw()
|
||||
def new():
|
||||
self.new_game(action)
|
||||
DialogWindow(self.decorator,app_name,"Oops, you clicked a mine! Play another game?",callback=new,window=self,icon='mines')
|
||||
return
|
||||
else:
|
||||
if not button.revealed:
|
||||
button.reveal()
|
||||
if button.mines == 0:
|
||||
n = [x for x in check_neighbor_buttons(button.row,button.col) if not x.revealed]
|
||||
while n:
|
||||
b = n.pop()
|
||||
b.reveal()
|
||||
if b.mines == 0:
|
||||
n.extend([x for x in check_neighbor_buttons(b.row,b.col) if not x.revealed and not x in n])
|
||||
self.check_win()
|
||||
|
||||
self.field_size, self.mine_count = action
|
||||
self.first_click = True
|
||||
self.tr.set_text(f"There are {self.mine_count} mines.")
|
||||
|
||||
self.mines = []
|
||||
while len(self.mines) < self.mine_count:
|
||||
x,y = random.randrange(self.field_size),random.randrange(self.field_size)
|
||||
if not (x,y) in self.mines:
|
||||
self.mines.append((x,y))
|
||||
|
||||
def check_neighbors(r,c):
|
||||
n = []
|
||||
if r > 0:
|
||||
if c > 0: n.append((r-1,c-1))
|
||||
n.append((r-1,c))
|
||||
if c < self.field_size-1: n.append((r-1,c+1))
|
||||
if r < self.field_size-1:
|
||||
if c > 0: n.append((r+1,c-1))
|
||||
n.append((r+1,c))
|
||||
if c < self.field_size-1: n.append((r+1,c+1))
|
||||
if c > 0: n.append((r,c-1))
|
||||
if c < self.field_size-1: n.append((r,c+1))
|
||||
return n
|
||||
|
||||
def check_neighbor_buttons(r,c):
|
||||
return [self.buttons[x][y] for x,y in check_neighbors(r,c)]
|
||||
|
||||
self.buttons = []
|
||||
for row in range(self.field_size):
|
||||
r = []
|
||||
for col in range(self.field_size):
|
||||
is_mine = (row,col) in self.mines
|
||||
neighbor_mines = len([x for x in check_neighbors(row,col) if x in self.mines])
|
||||
r.append(MineButton(mine_func,row,col,is_mine,neighbor_mines))
|
||||
self.buttons.append(r)
|
||||
|
||||
|
||||
def check_win(self):
|
||||
buttons = []
|
||||
@ -204,6 +211,9 @@ class MinesWindow(yutani.Window):
|
||||
self.tr.set_text("You win!")
|
||||
for b in buttons:
|
||||
b.reveal()
|
||||
def new():
|
||||
self.new_game((self.field_size,self.mine_count))
|
||||
DialogWindow(self.decorator,app_name,"You won! Play another game?",callback=new,window=self,icon='mines')
|
||||
|
||||
def flag(self,button):
|
||||
button.set_flagged()
|
||||
|
@ -20,6 +20,8 @@ from color_picker import ColorPickerWindow
|
||||
from menu_bar import MenuBarWidget, MenuEntryAction, MenuEntrySubmenu, MenuEntryDivider, MenuWindow
|
||||
from icon_cache import get_icon
|
||||
|
||||
from dialog import DialogWindow
|
||||
|
||||
import yutani_mainloop
|
||||
|
||||
app_name = "ToaruPaint"
|
||||
@ -41,13 +43,6 @@ class PaintingWindow(yutani.Window):
|
||||
self.last_color = (0,0,0)
|
||||
self.modifiers = None
|
||||
|
||||
def exit_app(action):
|
||||
menus = [x for x in self.menus.values()]
|
||||
for x in menus:
|
||||
x.definitely_close()
|
||||
self.close()
|
||||
sys.exit(0)
|
||||
|
||||
def about_window(action):
|
||||
subprocess.Popen(["about-applet.py",f"About {app_name}","applications-painting","/usr/share/icons/48/applications-painting.png",_description])
|
||||
|
||||
@ -95,7 +90,7 @@ class PaintingWindow(yutani.Window):
|
||||
#MenuEntryAction("Open","new",open_file,None),
|
||||
MenuEntryAction("Save","save",save_file,None),
|
||||
MenuEntryDivider(),
|
||||
MenuEntryAction("Exit","exit",exit_app,None),
|
||||
MenuEntryAction("Exit","exit",self.exit_app,None),
|
||||
]),
|
||||
("Tools", [
|
||||
MenuEntryAction("Color",None,select_color,None),
|
||||
@ -127,6 +122,20 @@ class PaintingWindow(yutani.Window):
|
||||
self.scale = 1.0
|
||||
self.modified = False
|
||||
|
||||
def actually_exit(self):
|
||||
menus = [x for x in self.menus.values()]
|
||||
for x in menus:
|
||||
x.definitely_close()
|
||||
self.close()
|
||||
sys.exit(0)
|
||||
|
||||
def exit_app(self, action=None):
|
||||
if self.modified:
|
||||
DialogWindow(self.decorator,app_name,"You have unsaved changes.\nAre you sure you want to quit?",callback=self.actually_exit,window=self)
|
||||
else:
|
||||
self.actually_exit()
|
||||
|
||||
|
||||
def load_buffer(self,path):
|
||||
self.set_title(f'{os.path.basename(path)} - {app_name}',self.icon)
|
||||
s = cairo.ImageSurface.create_from_png(path)
|
||||
@ -239,8 +248,7 @@ class PaintingWindow(yutani.Window):
|
||||
|
||||
def mouse_event(self, msg):
|
||||
if d.handle_event(msg) == yutani.Decor.EVENT_CLOSE:
|
||||
window.close()
|
||||
sys.exit(0)
|
||||
self.exit_app()
|
||||
x,y = msg.new_x - self.decorator.left_width(), msg.new_y - self.decorator.top_height()
|
||||
w,h = self.width - self.decorator.width(), self.height - self.decorator.height()
|
||||
|
||||
@ -331,8 +339,7 @@ class PaintingWindow(yutani.Window):
|
||||
if msg.event.action != yutani.KeyAction.ACTION_DOWN:
|
||||
return # Ignore anything that isn't a key down.
|
||||
if msg.event.key == b"q":
|
||||
self.close()
|
||||
sys.exit(0)
|
||||
self.exit_app()
|
||||
|
||||
if __name__ == '__main__':
|
||||
yutani.Yutani()
|
||||
|
Loading…
x
Reference in New Issue
Block a user