snakeware

Python-based Linux distro for x86-64 and RPi
git clone git://squid-tech.com/snakeware.git
Log | Files | Refs | README

commit 5cb2758766057c231026c6e37770d30ea5e9a02e
parent c13b7ec362cc3180a6752dcc0297f275b001d109
Author: Josh Moore <jxm5210@g.rit.edu>
Date:   Tue,  2 Jun 2020 02:14:26 -0400

Merge pull request #37 from cclauss/patch-4

Create autoblack.yml
Diffstat:
A.github/workflows/autoblack.yml | 24++++++++++++++++++++++++
Msnake_games/__init__.py | 1-
Msnake_games/circlez/__init__.py | 1+
Msnake_games/circlez/circ.py | 26+++++++++-----------------
Msnake_games/gamemenu.py | 43+++++++++++++++++++++----------------------
Msnake_games/snake/__init__.py | 1+
Msnake_games/snake/sgame.py | 184+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msnakewm/appmenu/appmenupanel.py | 42+++++++++++++++++-------------------------
Msnakewm/apps/fun/speaknspell/__init__.py | 1+
Msnakewm/apps/fun/speaknspell/speak.py | 23+++++++++++------------
Msnakewm/apps/games/pong/__init__.py | 1+
Msnakewm/apps/games/pong/ball.py | 16+++++++++++-----
Msnakewm/apps/games/pong/bat.py | 4++--
Msnakewm/apps/games/pong/pong.py | 14+++++++++-----
Msnakewm/apps/games/pong/pongwindow.py | 43+++++++++++++++++++++++++------------------
Msnakewm/apps/games/pong/score.py | 10+++++++---
Msnakewm/apps/games/pong/wall.py | 4+++-
Msnakewm/apps/system/exit snakewm/__init__.py | 1+
Msnakewm/apps/system/reboot/confirm.py | 2+-
Msnakewm/apps/system/shutdown/confirm.py | 2+-
Msnakewm/apps/test/HelloWorld/__init__.py | 3++-
Msnakewm/apps/tools/Background Color/__init__.py | 5+++--
Msnakewm/apps/tools/Background Image/__init__.py | 5+++--
Msnakewm/apps/tools/clock/__init__.py | 1+
Msnakewm/apps/tools/clock/clock.py | 29+++++++++++++----------------
Msnakewm/apps/tools/snakecalc/__init__.py | 1+
Msnakewm/apps/tools/snakecalc/calc.py | 47+++++++++++++++++++++++------------------------
Msnakewm/apps/tools/snaketerm/__init__.py | 1+
Msnakewm/apps/tools/snaketerm/term.py | 84++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msnakewm/wm.py | 73++++++++++++++++++++++++++++++++++---------------------------------------
30 files changed, 371 insertions(+), 321 deletions(-)

diff --git a/.github/workflows/autoblack.yml b/.github/workflows/autoblack.yml @@ -0,0 +1,24 @@ +# GitHub Action that uses Black to reformat Python code (if needed) when doing a git push. +# If all Python code in the repo is compliant with Black then this Action does nothing. +# Otherwise, Black is run and its changes are committed to the repo. +# https://github.com/cclauss/autoblack + +name: autoblack_push +on: [push] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 # Use v1, NOT v2 + - uses: actions/setup-python@v2 + - run: pip install black + - run: black --check . + - name: If needed, commit black changes to a new pull request + if: failure() + run: | + black . + git config --global user.name github-actions + git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com' + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git commit -am "fixup! Format Python code with psf/black push" + git push --force origin HEAD:$GITHUB_REF diff --git a/snake_games/__init__.py b/snake_games/__init__.py @@ -1,4 +1,3 @@ - def menu(): from .gamemenu import SnakeGameMenu diff --git a/snake_games/circlez/__init__.py b/snake_games/circlez/__init__.py @@ -1,4 +1,5 @@ from .circ import CirclezApp + def load(): CirclezApp().run() diff --git a/snake_games/circlez/circ.py b/snake_games/circlez/circ.py @@ -9,29 +9,24 @@ import pygame import random import os + class CirclezApp: def __init__(self): pygame.init() # set pygame to fbdev mode - os.putenv('SDL_FBDEV', '/dev/fb0') + os.putenv("SDL_FBDEV", "/dev/fb0") pygame.display.init() # get screen dimensions - self.DIMS = ( - pygame.display.Info().current_w, - pygame.display.Info().current_h - ) + self.DIMS = (pygame.display.Info().current_w, pygame.display.Info().current_h) # init screen - self.SCREEN = pygame.display.set_mode( - self.DIMS, - pygame.FULLSCREEN - ) + self.SCREEN = pygame.display.set_mode(self.DIMS, pygame.FULLSCREEN) # init background self.BG = pygame.Surface((self.DIMS)) - self.BG.fill((0,0,0)) + self.BG.fill((0, 0, 0)) pygame.mouse.set_visible(False) pygame.display.update() @@ -49,14 +44,11 @@ class CirclezApp: ( random.randint(0, 255), random.randint(0, 255), - random.randint(0, 255) - ), - ( - random.randint(0, self.DIMS[0]), - random.randint(0, self.DIMS[1]) + random.randint(0, 255), ), - random.randint(10, 100) + (random.randint(0, self.DIMS[0]), random.randint(0, self.DIMS[1])), + random.randint(10, 100), ) - self.SCREEN.blit(self.BG, (0,0)) + self.SCREEN.blit(self.BG, (0, 0)) pygame.display.flip() clock.tick(30) diff --git a/snake_games/gamemenu.py b/snake_games/gamemenu.py @@ -1,8 +1,9 @@ import os import importlib -class SnakeGameMenu(): - GAMENUMS = '0123456789' + +class SnakeGameMenu: + GAMENUMS = "0123456789" def __init__(self): self.GAMEPATH = os.path.dirname(os.path.abspath(__file__)) @@ -10,8 +11,9 @@ class SnakeGameMenu(): self.cur_page = 0 for file in os.listdir(self.GAMEPATH): - if os.path.isdir(self.GAMEPATH + '/' + file) and\ - os.path.isfile(self.GAMEPATH + '/' + file + '/__init__.py'): + if os.path.isdir(self.GAMEPATH + "/" + file) and os.path.isfile( + self.GAMEPATH + "/" + file + "/__init__.py" + ): self.LIST.append(file) def list_page(self): @@ -23,39 +25,36 @@ class SnakeGameMenu(): for i in range(10): if i + page_idx >= len(self.LIST): break - print(' ' + str(i) + '. ' + self.LIST[i + page_idx]) - print('') + print(" " + str(i) + ". " + self.LIST[i + page_idx]) + print("") def list_games(self): """ Render the full current page for the games list, including the header and prompt for user input. """ - os.system('clear') + os.system("clear") - print('\n\n~~~~~ SNAKE GAMES ~~~~~\n') - print(' Page {0}/{1}:'.format( - self.cur_page + 1, - int(len(self.LIST) / 10 + 1) - )) + print("\n\n~~~~~ SNAKE GAMES ~~~~~\n") + print(" Page {0}/{1}:".format(self.cur_page + 1, int(len(self.LIST) / 10 + 1))) self.list_page() - print(' 0-9: Select Game') - print(' + : Next Page') - print(' - : Prev Page') - print(' q : Quit\n') + print(" 0-9: Select Game") + print(" + : Next Page") + print(" - : Prev Page") + print(" q : Quit\n") - resp = input(' >') + resp = input(" >") - if resp == 'q': + if resp == "q": # quit exit() - elif resp == '+': + elif resp == "+": # next page if self.cur_page < int(len(self.LIST) / 10): self.cur_page = self.cur_page + 1 - elif resp == '-': + elif resp == "-": # prev page if self.cur_page > 0: self.cur_page = self.cur_page - 1 @@ -66,9 +65,9 @@ class SnakeGameMenu(): if sidx >= len(self.LIST): return - print('Loading ' + self.LIST[sidx] + '...') + print("Loading " + self.LIST[sidx] + "...") - game = 'snake_games.' + self.LIST[sidx] + game = "snake_games." + self.LIST[sidx] _game = importlib.import_module(game) _game.load() diff --git a/snake_games/snake/__init__.py b/snake_games/snake/__init__.py @@ -1,5 +1,6 @@ from .sgame import SnakeApp + def load(): app = SnakeApp() app.on_execute() diff --git a/snake_games/snake/sgame.py b/snake_games/snake/sgame.py @@ -3,49 +3,51 @@ from random import randint import pygame import time import os - + + class Apple: x = 0 y = 0 step = 44 - - def __init__(self,x,y): + + def __init__(self, x, y): self.x = x * self.step self.y = y * self.step - + def draw(self, surface): - pygame.draw.rect(surface, (0,255,0), (self.x,self.y, 44, 44), 0) - + pygame.draw.rect(surface, (0, 255, 0), (self.x, self.y, 44, 44), 0) + + class Player: x = [0] y = [0] step = 44 direction = 0 length = 3 - + updateCountMax = 2 updateCount = 0 - + def __init__(self, length): - self.length = length - for i in range(0,2000): - self.x.append(-100) - self.y.append(-100) - - # initial positions, no collision. - self.x[1] = 1*44 - self.x[2] = 2*44 - + self.length = length + for i in range(0, 2000): + self.x.append(-100) + self.y.append(-100) + + # initial positions, no collision. + self.x[1] = 1 * 44 + self.x[2] = 2 * 44 + def update(self): - + self.updateCount = self.updateCount + 1 if self.updateCount > self.updateCountMax: - + # update previous positions - for i in range(self.length-1,0,-1): - self.x[i] = self.x[i-1] - self.y[i] = self.y[i-1] - + for i in range(self.length - 1, 0, -1): + self.x[i] = self.x[i - 1] + self.y[i] = self.y[i - 1] + # update position of head of snake if self.direction == 0: self.x[0] = self.x[0] + self.step @@ -55,132 +57,148 @@ class Player: self.y[0] = self.y[0] - self.step if self.direction == 3: self.y[0] = self.y[0] + self.step - + self.updateCount = 0 - - + def moveRight(self): self.direction = 0 - + def moveLeft(self): self.direction = 1 - + def moveUp(self): self.direction = 2 - + def moveDown(self): - self.direction = 3 - + self.direction = 3 + def draw(self, surface): - for i in range(0,self.length): - pygame.draw.rect(surface, (255,0,0), (self.x[i],self.y[i], 44,44), 0) - + for i in range(0, self.length): + pygame.draw.rect(surface, (255, 0, 0), (self.x[i], self.y[i], 44, 44), 0) + + class Game: - def isCollision(self,x1,y1,x2,y2,bsize): + def isCollision(self, x1, y1, x2, y2, bsize): if x1 >= x2 and x1 <= x2 + bsize: if y1 >= y2 and y1 <= y2 + bsize: return True return False - + + class SnakeApp: player = 0 apple = 0 - + def __init__(self): self._running = True self._display_surf = None self._image_surf = None self._apple_surf = None self.game = Game() - self.player = Player(3) - self.apple = Apple(5,5) - + self.player = Player(3) + self.apple = Apple(5, 5) + def on_init(self): pygame.init() # initialize pygame to the framebuffer - os.putenv('SDL_FBDEV', '/dev/fb0') + os.putenv("SDL_FBDEV", "/dev/fb0") pygame.display.init() pygame.mouse.set_visible(False) - self.DIMS = ( - pygame.display.Info().current_w, - pygame.display.Info().current_h - ) + self.DIMS = (pygame.display.Info().current_w, pygame.display.Info().current_h) - self._display_surf = pygame.display.set_mode( - self.DIMS, - pygame.FULLSCREEN - ) + self._display_surf = pygame.display.set_mode(self.DIMS, pygame.FULLSCREEN) self._running = True - + def on_event(self, event): if event.type == QUIT: self._running = False - + def on_loop(self): self.player.update() - + # does snake eat apple? - for i in range(0,self.player.length): - if self.game.isCollision(self.apple.x,self.apple.y,self.player.x[i], self.player.y[i],44): + for i in range(0, self.player.length): + if self.game.isCollision( + self.apple.x, self.apple.y, self.player.x[i], self.player.y[i], 44 + ): self.apple.x = randint(2, int(self.DIMS[0] / 44) - 2) * 44 self.apple.y = randint(2, int(self.DIMS[1] / 44) - 2) * 44 self.player.length = self.player.length + 1 - - + # does snake collide with itself? - for i in range(2,self.player.length): - if self.game.isCollision(self.player.x[0],self.player.y[0],self.player.x[i], self.player.y[i],40): + for i in range(2, self.player.length): + if self.game.isCollision( + self.player.x[0], + self.player.y[0], + self.player.x[i], + self.player.y[i], + 40, + ): print("You lose! Collision: ") - print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")") - print("x[" + str(i) + "] (" + str(self.player.x[i]) + "," + str(self.player.y[i]) + ")") + print( + "x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")" + ) + print( + "x[" + + str(i) + + "] (" + + str(self.player.x[i]) + + "," + + str(self.player.y[i]) + + ")" + ) self._running = False # is the snake out of bounds? - if self.player.x[0] < 0 or self.player.y[0] < 0 or\ - self.player.x[0] >= self.DIMS[0] or self.player.y[0] >= self.DIMS[1]: + if ( + self.player.x[0] < 0 + or self.player.y[0] < 0 + or self.player.x[0] >= self.DIMS[0] + or self.player.y[0] >= self.DIMS[1] + ): print("You lose!") self._running = False - + pass - + def on_render(self): - self._display_surf.fill((0,0,0)) + self._display_surf.fill((0, 0, 0)) self.player.draw(self._display_surf) self.apple.draw(self._display_surf) pygame.display.flip() - + def on_cleanup(self): pygame.quit() exit(0) - + def on_execute(self): if self.on_init() == False: self._running = False - - while( self._running ): + + while self._running: pygame.event.pump() - keys = pygame.key.get_pressed() - - if (keys[K_RIGHT]): + keys = pygame.key.get_pressed() + + if keys[K_RIGHT]: self.player.moveRight() - - if (keys[K_LEFT]): + + if keys[K_LEFT]: self.player.moveLeft() - - if (keys[K_UP]): + + if keys[K_UP]: self.player.moveUp() - - if (keys[K_DOWN]): + + if keys[K_DOWN]: self.player.moveDown() - - if (keys[K_ESCAPE]): + + if keys[K_ESCAPE]: self._running = False - + self.on_loop() self.on_render() - - time.sleep (50.0 / 1000.0); + + time.sleep(50.0 / 1000.0) self.on_cleanup() diff --git a/snakewm/appmenu/appmenupanel.py b/snakewm/appmenu/appmenupanel.py @@ -15,6 +15,7 @@ PANEL_LAYER = 10 # button dimensions BUTTON_DIMS = (200, 25) + class AppMenuPanel(UIPanel): manager = None pos = None @@ -37,17 +38,11 @@ class AppMenuPanel(UIPanel): """ super().__init__( pygame.Rect( - ( - pos[0] * BUTTON_DIMS[0], - pos[1] * BUTTON_DIMS[1] - ), - ( - BUTTON_DIMS[0] + 5, - BUTTON_DIMS[1] * len(elements.keys()) + 5 - ) + (pos[0] * BUTTON_DIMS[0], pos[1] * BUTTON_DIMS[1]), + (BUTTON_DIMS[0] + 5, BUTTON_DIMS[1] * len(elements.keys()) + 5), ), starting_layer_height=PANEL_LAYER, - manager=manager + manager=manager, ) self.pos = pos self.path = path @@ -58,30 +53,30 @@ class AppMenuPanel(UIPanel): ekeys = list(elements.keys()) for i in range(len(ekeys)): UIButton( - pygame.Rect( - (0, i * BUTTON_DIMS[1]), - BUTTON_DIMS - ), + pygame.Rect((0, i * BUTTON_DIMS[1]), BUTTON_DIMS), text=ekeys[i], manager=manager, container=self, - object_id = 'menu-' + self.path.replace('.', '-') + object_id="menu-" + self.path.replace(".", "-"), ) def process_event(self, event): if event.type != pygame.USEREVENT: return - if event.user_type == pygame_gui.UI_BUTTON_PRESSED and\ - event.ui_object_id == ('panel.menu-' + self.path.replace('.', '-')): + if event.user_type == pygame_gui.UI_BUTTON_PRESSED and event.ui_object_id == ( + "panel.menu-" + self.path.replace(".", "-") + ): # open clicked app uitext = event.ui_element.text if self.elements[uitext] == None: - self.loadfunc(self.path + '.' + uitext) + self.loadfunc(self.path + "." + uitext) - if event.user_type == pygame_gui.UI_BUTTON_ON_HOVERED and\ - event.ui_object_id == ('panel.menu-' + self.path.replace('.', '-')): + if ( + event.user_type == pygame_gui.UI_BUTTON_ON_HOVERED + and event.ui_object_id == ("panel.menu-" + self.path.replace(".", "-")) + ): uitext = event.ui_element.text if self.elements[uitext] != None: @@ -92,13 +87,10 @@ class AppMenuPanel(UIPanel): # next open a new child panel self.child = AppMenuPanel( self.ui_manager, - ( - self.pos[0] + 1, - list(self.elements.keys()).index(uitext) - ), - self.path + '.' + uitext, + (self.pos[0] + 1, list(self.elements.keys()).index(uitext)), + self.path + "." + uitext, self.elements[uitext], - self.loadfunc + self.loadfunc, ) def destroy(self): diff --git a/snakewm/apps/fun/speaknspell/__init__.py b/snakewm/apps/fun/speaknspell/__init__.py @@ -1,5 +1,6 @@ from .speak import SpeakSpell + def load(manager, params): """ Create and launch a new instance of SpeakSpell. diff --git a/snakewm/apps/fun/speaknspell/speak.py b/snakewm/apps/fun/speaknspell/speak.py @@ -8,48 +8,47 @@ from pygame_gui.elements import UITextEntryLine import pyttsx3 + class SpeakSpell(pygame_gui.elements.UIWindow): speakthrd = None def __init__(self, pos, manager): super().__init__( - pygame.Rect(pos, (400,128)), + pygame.Rect(pos, (400, 128)), manager=manager, - window_display_title='speaknspell', - object_id='#speaknspell' + window_display_title="speaknspell", + object_id="#speaknspell", ) self.label = UILabel( relative_rect=pygame.Rect(-20, 10, 400, 20), - text='', + text="", manager=manager, - container=self + container=self, ) self.input = UITextEntryLine( - relative_rect=pygame.Rect(0, 40, 368, 30), - manager=manager, - container=self + relative_rect=pygame.Rect(0, 40, 368, 30), manager=manager, container=self ) self.engine = pyttsx3.init() - self.engine.setProperty('rate', 150) + self.engine.setProperty("rate", 150) self.speakthrd = None - self.speak('Hello, thank you for using snakeware!') + self.speak("Hello, thank you for using snakeware!") def speak(self, text): if self.speakthrd is not None and self.speakthrd.is_alive(): return - if text == '': + if text == "": return self.engine.say(text) self.speakthrd = threading.Thread(target=self.engine.runAndWait, args=()) self.speakthrd.start() self.label.set_text(text) - self.input.set_text('') + self.input.set_text("") def process_event(self, event): super().process_event(event) diff --git a/snakewm/apps/games/pong/__init__.py b/snakewm/apps/games/pong/__init__.py @@ -1,5 +1,6 @@ from .pongwindow import PongWindow + def load(manager, params): """ Create Pong game and add it to the UI manager. diff --git a/snakewm/apps/games/pong/ball.py b/snakewm/apps/games/pong/ball.py @@ -10,7 +10,7 @@ class Ball: self.position = [float(start_position[0]), float(start_position[1])] self.start_position = [self.position[0], self.position[1]] self.ball_speed = 120.0 - self.max_bat_bounce_angle = 5.0 * math.pi/12.0 + self.max_bat_bounce_angle = 5.0 * math.pi / 12.0 self.collided = False self.velocity = [0.0, 0.0] @@ -49,11 +49,17 @@ class Ball: collided_this_frame = True if not self.collided: self.collided = True - bat_y_centre = bat.position[1] + (bat.length/2) + bat_y_centre = bat.position[1] + (bat.length / 2) ball_y_centre = self.position[1] + 5 - relative_intersect_y = bat_y_centre - ball_y_centre # should be in 'bat space' between -50 and +50 - normalized_relative_intersect_y = relative_intersect_y/(bat.length/2) - bounce_angle = normalized_relative_intersect_y * self.max_bat_bounce_angle + relative_intersect_y = ( + bat_y_centre - ball_y_centre + ) # should be in 'bat space' between -50 and +50 + normalized_relative_intersect_y = relative_intersect_y / ( + bat.length / 2 + ) + bounce_angle = ( + normalized_relative_intersect_y * self.max_bat_bounce_angle + ) self.velocity[0] = self.velocity[0] * -1 self.velocity[1] = self.ball_speed * -math.sin(bounce_angle) diff --git a/snakewm/apps/games/pong/bat.py b/snakewm/apps/games/pong/bat.py @@ -21,7 +21,7 @@ class Bat: self.width = 5.0 self.position = [float(start_pos[0]), float(start_pos[1])] - + self.rect = pygame.Rect((start_pos[0], start_pos[1]), (self.width, self.length)) self.colour = pygame.Color("#FFFFFF") @@ -46,7 +46,7 @@ class Bat: self.position[1] = 10.0 self.rect.y = self.position[1] - + if self.move_down: self.position[1] += dt * self.move_speed diff --git a/snakewm/apps/games/pong/pong.py b/snakewm/apps/games/pong/pong.py @@ -18,8 +18,10 @@ class PongGame: self.score = Score(font) - self.walls = [Wall((5, 5), (size[0] - 10, 10)), - Wall((5, size[1] - 10), (size[0] - 10, size[1] - 5))] + self.walls = [ + Wall((5, 5), (size[0] - 10, 10)), + Wall((5, size[1] - 10), (size[0] - 10, size[1] - 5)), + ] self.bats = [] @@ -31,10 +33,12 @@ class PongGame: control_scheme_2.up = K_UP control_scheme_2.down = K_DOWN - self.bats.append(Bat((5, int(size[1]/2)), control_scheme_1, self.size)) - self.bats.append(Bat((size[0] - 10, int(size[1]/2)), control_scheme_2, self.size)) + self.bats.append(Bat((5, int(size[1] / 2)), control_scheme_1, self.size)) + self.bats.append( + Bat((size[0] - 10, int(size[1] / 2)), control_scheme_2, self.size) + ) - self.ball = Ball((int(size[0]/2), int(size[1]/2))) + self.ball = Ball((int(size[0] / 2), int(size[1] / 2))) def process_event(self, event): for bat in self.bats: diff --git a/snakewm/apps/games/pong/pongwindow.py b/snakewm/apps/games/pong/pongwindow.py @@ -10,17 +10,21 @@ from .pong import PongGame class PongWindow(UIWindow): def __init__(self, position, ui_manager): - super().__init__(pygame.Rect(position, (320, 240)), ui_manager, - window_display_title='pong', - object_id='#pong_window') + super().__init__( + pygame.Rect(position, (320, 240)), + ui_manager, + window_display_title="pong", + object_id="#pong_window", + ) game_surface_size = self.get_container().get_size() - self.game_surface_element = UIImage(pygame.Rect((0, 0), - game_surface_size), - pygame.Surface(game_surface_size).convert(), - manager=ui_manager, - container=self, - parent_element=self) + self.game_surface_element = UIImage( + pygame.Rect((0, 0), game_surface_size), + pygame.Surface(game_surface_size).convert(), + manager=ui_manager, + container=self, + parent_element=self, + ) self.pong_game = PongGame(game_surface_size) @@ -34,16 +38,19 @@ class PongWindow(UIWindow): def process_event(self, event): handled = super().process_event(event) - if (event.type == pygame.USEREVENT and - event.user_type == pygame_gui.UI_BUTTON_PRESSED and - event.ui_object_id == "#pong_window.#title_bar" and - event.ui_element == self.title_bar): + if ( + event.type == pygame.USEREVENT + and event.user_type == pygame_gui.UI_BUTTON_PRESSED + and event.ui_object_id == "#pong_window.#title_bar" + and event.ui_element == self.title_bar + ): handled = True - event_data = {'user_type': 'window_selected', - 'ui_element': self, - 'ui_object_id': self.most_specific_combined_id} - window_selected_event = pygame.event.Event(pygame.USEREVENT, - event_data) + event_data = { + "user_type": "window_selected", + "ui_element": self, + "ui_object_id": self.most_specific_combined_id, + } + window_selected_event = pygame.event.Event(pygame.USEREVENT, event_data) pygame.event.post(window_selected_event) if self.is_active: handled = self.pong_game.process_event(event) diff --git a/snakewm/apps/games/pong/score.py b/snakewm/apps/games/pong/score.py @@ -14,11 +14,15 @@ class Score: def update_score_text(self): self.score_string = str(self.player_1_score) + " - " + str(self.player_2_score) - self.score_text_render = self.font.render(self.score_string, True, pygame.Color(200, 200, 200)) + self.score_text_render = self.font.render( + self.score_string, True, pygame.Color(200, 200, 200) + ) def render(self, screen, size): - screen.blit(self.score_text_render, self.score_text_render.get_rect(centerx=size[0]/2, - centery=size[1]/10)) + screen.blit( + self.score_text_render, + self.score_text_render.get_rect(centerx=size[0] / 2, centery=size[1] / 10), + ) def increase_player_1_score(self): self.player_1_score += 1 diff --git a/snakewm/apps/games/pong/wall.py b/snakewm/apps/games/pong/wall.py @@ -3,7 +3,9 @@ import pygame class Wall: def __init__(self, top_left, bottom_right): - self.rect = pygame.Rect(top_left, (bottom_right[0] - top_left[0], bottom_right[1] - top_left[1])) + self.rect = pygame.Rect( + top_left, (bottom_right[0] - top_left[0], bottom_right[1] - top_left[1]) + ) self.colour = pygame.Color("#C8C8C8") def render(self, screen): diff --git a/snakewm/apps/system/exit snakewm/__init__.py b/snakewm/apps/system/exit snakewm/__init__.py @@ -1,5 +1,6 @@ import pygame + def load(manager, params): pygame.quit() exit() diff --git a/snakewm/apps/system/reboot/confirm.py b/snakewm/apps/system/reboot/confirm.py @@ -12,7 +12,7 @@ class RebootConfirmationDialog(pygame_gui.windows.UIConfirmationDialog): action_long_desc="Are you sure you want to reboot the system?", action_short_name="Reboot", blocking=False, - object_id="#reboot" + object_id="#reboot", ) def process_event(self, event): diff --git a/snakewm/apps/system/shutdown/confirm.py b/snakewm/apps/system/shutdown/confirm.py @@ -12,7 +12,7 @@ class ShutdownConfirmationDialog(pygame_gui.windows.UIConfirmationDialog): action_long_desc="Are you sure you want to shut down the system?", action_short_name="Shut down", blocking=False, - object_id="#shutdown" + object_id="#shutdown", ) def process_event(self, event): diff --git a/snakewm/apps/test/HelloWorld/__init__.py b/snakewm/apps/test/HelloWorld/__init__.py @@ -1,6 +1,7 @@ import pygame import pygame_gui + def load(manager, params): """ An example implementation of the load() function called by the snakewm @@ -17,5 +18,5 @@ def load(manager, params): rect=pygame.Rect(pos, (300, 160)), window_title="snakeware", html_message="Hello World!", - manager=manager + manager=manager, ) diff --git a/snakewm/apps/tools/Background Color/__init__.py b/snakewm/apps/tools/Background Color/__init__.py @@ -1,6 +1,7 @@ import pygame import pygame_gui + def load(manager, params): """ Launch a Colour Picker dialog to change the desktop background color. @@ -15,6 +16,6 @@ def load(manager, params): pygame_gui.windows.UIColourPickerDialog( rect=pygame.Rect(pos, (600, 400)), manager=manager, - window_title='Set Background Color', - object_id='#desktop_colour_picker' + window_title="Set Background Color", + object_id="#desktop_colour_picker", ) diff --git a/snakewm/apps/tools/Background Image/__init__.py b/snakewm/apps/tools/Background Image/__init__.py @@ -2,6 +2,7 @@ import pygame import pygame_gui import os + def load(manager, params): """ Launch a file dialog to change the desktop background. @@ -16,7 +17,7 @@ def load(manager, params): pygame_gui.windows.UIFileDialog( rect=pygame.Rect(pos, (600, 400)), manager=manager, - window_title='Set Background Image', + window_title="Set Background Image", initial_file_path=os.path.dirname(os.path.realpath(__file__)), - object_id='#background_picker' + object_id="#background_picker", ) diff --git a/snakewm/apps/tools/clock/__init__.py b/snakewm/apps/tools/clock/__init__.py @@ -1,5 +1,6 @@ from .clock import SnakeClock + def load(manager, params): """ Create and launch a new instance of SnakeClock. diff --git a/snakewm/apps/tools/clock/clock.py b/snakewm/apps/tools/clock/clock.py @@ -3,44 +3,42 @@ import pygame_gui import datetime -class SnakeClock(pygame_gui.elements.UIWindow): +class SnakeClock(pygame_gui.elements.UIWindow): def __init__(self, pos, manager): super().__init__( pygame.Rect(pos, (195, 100)), manager=manager, - window_display_title='clock', - object_id='#clockterm', - resizable=True + window_display_title="clock", + object_id="#clockterm", + resizable=True, ) self.textbox = pygame_gui.elements.UITextBox( - '', + "", relative_rect=pygame.Rect(0, 1, 163, 40), manager=manager, container=self, anchors={ - 'left': 'left', - 'right': 'right', - 'top': 'top', - 'bottom': 'bottom' - } + "left": "left", + "right": "right", + "top": "top", + "bottom": "bottom", + }, ) - - def process_event(self, event): super().process_event(event) def update(self, time_delta): super().update(time_delta) - + dt = datetime.datetime.now() # %X formatted clock, %x formatted date current_time = dt.strftime("%X %x") - + self.set_text(current_time) def set_text(self, text): self.textbox.html_text = text - self.textbox.rebuild()- \ No newline at end of file + self.textbox.rebuild() diff --git a/snakewm/apps/tools/snakecalc/__init__.py b/snakewm/apps/tools/snakecalc/__init__.py @@ -1,5 +1,6 @@ from .calc import SnakeCalc + def load(manager, params): """ Create and launch a new instance of SnakeCalc. diff --git a/snakewm/apps/tools/snakecalc/calc.py b/snakewm/apps/tools/snakecalc/calc.py @@ -1,55 +1,54 @@ import pygame import pygame_gui + class SnakeCalc(pygame_gui.elements.UIWindow): # operations to be converted to buttons - OPS = '+-/*1234567890pxC=' + OPS = "+-/*1234567890pxC=" # button dimensions BSIZE = (67, 75) # user input - USERCALC = '' + USERCALC = "" def __init__(self, pos, manager): super().__init__( pygame.Rect(pos, (300, 475)), manager=manager, - window_display_title='snakecalc', - object_id='#snaketerm', - resizable=True + window_display_title="snakecalc", + object_id="#snaketerm", + resizable=True, ) self.textbox = pygame_gui.elements.UITextBox( - '', + "", relative_rect=pygame.Rect(0, 1, 268, 40), manager=manager, container=self, anchors={ - 'left': 'left', - 'right': 'right', - 'top': 'top', - 'bottom': 'bottom' - } + "left": "left", + "right": "right", + "top": "top", + "bottom": "bottom", + }, ) # generate calculator buttons for i in range(len(self.OPS)): op = self.OPS[i] - if op == 'x': + if op == "x": # skip placeholder ops continue pygame_gui.elements.UIButton( relative_rect=pygame.Rect( - (i % 4 * self.BSIZE[0], - 40 + int(i / 4) * self.BSIZE[1]), - self.BSIZE + (i % 4 * self.BSIZE[0], 40 + int(i / 4) * self.BSIZE[1]), self.BSIZE ), - text='.' if op == 'p' else op, + text="." if op == "p" else op, manager=manager, container=self, - object_id='#op-' + op + object_id="#op-" + op, ) def process_event(self, event): @@ -72,12 +71,12 @@ class SnakeCalc(pygame_gui.elements.UIWindow): """ Perform the actual calculation based on user input. """ - result = '' + result = "" try: result = str(eval(expression)) except Exception: - result = 'Error' + result = "Error" self.set_text(result) @@ -86,12 +85,12 @@ class SnakeCalc(pygame_gui.elements.UIWindow): Called to append user input ops to the existing input. """ if op in self.OPS: - if op == '=': + if op == "=": # perform the calculation self.calculate(self.textbox.html_text) - elif op == 'C': - self.set_text('') - elif op == 'p': - self.append_text('.') + elif op == "C": + self.set_text("") + elif op == "p": + self.append_text(".") else: self.append_text(op) diff --git a/snakewm/apps/tools/snaketerm/__init__.py b/snakewm/apps/tools/snaketerm/__init__.py @@ -1,5 +1,6 @@ from .term import SnakeTerm + def load(manager, params): """ Create an launch a new instance of SnakeTerm. diff --git a/snakewm/apps/tools/snaketerm/term.py b/snakewm/apps/tools/snaketerm/term.py @@ -8,14 +8,15 @@ import pygame_gui from pygame_gui.elements import UITextBox + class SnakeTerm(pygame_gui.elements.UIWindow): def __init__(self, pos, manager): super().__init__( - pygame.Rect(pos, (400,300)), + pygame.Rect(pos, (400, 300)), manager, - window_display_title='snaketerm', - object_id='#snaketerm', - resizable=True + window_display_title="snaketerm", + object_id="#snaketerm", + resizable=True, ) self.textbox = pygame_gui.elements.UITextBox( @@ -24,11 +25,11 @@ class SnakeTerm(pygame_gui.elements.UIWindow): manager=manager, container=self, anchors={ - 'left': 'left', - 'right': 'right', - 'top': 'top', - 'bottom': 'bottom' - } + "left": "left", + "right": "right", + "top": "top", + "bottom": "bottom", + }, ) self.input = pygame_gui.elements.UITextEntryLine( @@ -36,11 +37,11 @@ class SnakeTerm(pygame_gui.elements.UIWindow): manager=manager, container=self, anchors={ - 'left': 'left', - 'right': 'right', - 'top': 'bottom', - 'bottom': 'bottom' - } + "left": "left", + "right": "right", + "top": "bottom", + "bottom": "bottom", + }, ) self.input.focus() @@ -52,29 +53,29 @@ class SnakeTerm(pygame_gui.elements.UIWindow): self.cached_command = str() # jump attributes - self.jump_chars = (' ', '-', '_', '/') + self.jump_chars = (" ", "-", "_", "/") # TODO: load this from a file so users can configure self.hotkeys = { - 'ctrl': { - 'l': self.clear_text, - 'left': self.jump_left, - 'right': self.jump_right, - 'backspace': self.jump_backspace + "ctrl": { + "l": self.clear_text, + "left": self.jump_left, + "right": self.jump_right, + "backspace": self.jump_backspace, } } def set_text(self, text): - self.textbox.html_text = text.replace('\n', '<br>') + self.textbox.html_text = text.replace("\n", "<br>") self.textbox.rebuild() - + def clear_text(self): self.set_text(str()) - + def jump_left(self): command = self.input.get_text() ep = self.input.edit_position - while ep > 0 and command[ep-1] not in self.jump_chars: + while ep > 0 and command[ep - 1] not in self.jump_chars: ep -= 1 self.input.edit_position = ep @@ -84,34 +85,36 @@ class SnakeTerm(pygame_gui.elements.UIWindow): while ep < len(command) and command[ep] not in self.jump_chars: ep += 1 self.input.edit_position = ep - + def jump_backspace(self): command = self.input.get_text() ep = to_pos = self.input.edit_position - while ep > 0 and command[ep-1] not in self.jump_chars: + while ep > 0 and command[ep - 1] not in self.jump_chars: ep -= 1 self.input.set_text(command[:ep] + command[to_pos:]) self.input.edit_position = ep def append_text(self, text): - self.textbox.html_text = self.textbox.html_text + text.replace('\n', '<br>') + self.textbox.html_text = self.textbox.html_text + text.replace("\n", "<br>") self.textbox.rebuild() if self.textbox.scroll_bar is not None: - self.textbox.scroll_bar.scroll_position = len(self.textbox.html_text.split('<br>')) * 5 + self.textbox.scroll_bar.scroll_position = ( + len(self.textbox.html_text.split("<br>")) * 5 + ) self.textbox.scroll_bar.scroll_wheel_down = True - + def add_to_history(self, command): self.history = [command] + self.history if len(self.history) > self.histsize: del self.history[-1] def set_from_history(self): - if self.histindex > -1: + if self.histindex > -1: self.input.set_text(self.history[self.histindex]) else: self.input.set_text(self.cached_command) self.input.edit_position = len(self.input.get_text()) - + def set_histindex(self, increment): try: self.history[self.histindex + increment] @@ -119,10 +122,10 @@ class SnakeTerm(pygame_gui.elements.UIWindow): except IndexError: return self.histindex return self.histindex - + def cache_command(self): self.cached_command = self.input.get_text() - + def flush_command_cache(self): self.cached_command = str() @@ -134,11 +137,11 @@ class SnakeTerm(pygame_gui.elements.UIWindow): sys.stdout = tout = StringIO() try: - code = compile(self.input.get_text(), 'snaketerm_code', 'exec') + code = compile(self.input.get_text(), "snaketerm_code", "exec") exec(code, globals()) except Exception: - e_type,e_val,e_traceback = sys.exc_info() - print('Traceback (most recent call last):') + e_type, e_val, e_traceback = sys.exc_info() + print("Traceback (most recent call last):") traceback.print_tb(e_traceback, None, tout) print(e_type, e_val) @@ -149,15 +152,15 @@ class SnakeTerm(pygame_gui.elements.UIWindow): self.histindex = -1 self.flush_command_cache() self.input.set_text(str()) - + # ctrl hotkeys elif pygame.key.get_mods() & pygame.KMOD_CTRL: if event.type == pygame.KEYUP: name = pygame.key.name(event.key) - callback = self.hotkeys['ctrl'].get(name) + callback = self.hotkeys["ctrl"].get(name) if callback and callable(callback): - self.hotkeys['ctrl'][name]() - + self.hotkeys["ctrl"][name]() + # other special keys (history, etc) elif event.type == pygame.KEYUP: if event.key in (pygame.K_UP, pygame.K_DOWN): @@ -166,4 +169,3 @@ class SnakeTerm(pygame_gui.elements.UIWindow): self.cache_command() self.set_histindex(increment) self.set_from_history() - diff --git a/snakewm/wm.py b/snakewm/wm.py @@ -2,7 +2,7 @@ Snake Window Manager """ -TESTMODE = __name__ == '__main__' +TESTMODE = __name__ == "__main__" import os import sys @@ -15,6 +15,7 @@ if TESTMODE: else: from snakewm.appmenu.appmenupanel import AppMenuPanel + class SnakeWM: SCREEN = None DIMS = None @@ -33,26 +34,20 @@ class SnakeWM: def __init__(self): # populate the apps tree - apps_path = os.path.dirname(os.path.abspath(__file__)) + '/apps' + apps_path = os.path.dirname(os.path.abspath(__file__)) + "/apps" SnakeWM.iter_dir(self.APPS, apps_path) pygame.init() # initialize pygame to framebuffer - os.putenv('SDL_FBDEV', '/dev/fb0') + os.putenv("SDL_FBDEV", "/dev/fb0") pygame.display.init() # get screen dimensions - self.DIMS = ( - pygame.display.Info().current_w, - pygame.display.Info().current_h - ) + self.DIMS = (pygame.display.Info().current_w, pygame.display.Info().current_h) # init screen - self.SCREEN = pygame.display.set_mode( - self.DIMS, - pygame.FULLSCREEN - ) + self.SCREEN = pygame.display.set_mode(self.DIMS, pygame.FULLSCREEN) # init background self.BG = pygame.Surface((self.DIMS)) @@ -64,18 +59,17 @@ class SnakeWM: pygame.mouse.set_visible(True) pygame.display.update() - def iter_dir(tree, path): """ Static function that recursively populates dict 'tree' with the app directory structure starting at 'path'. """ for f in os.listdir(path): - if os.path.isfile(path + '/' + f + '/__init__.py'): + if os.path.isfile(path + "/" + f + "/__init__.py"): tree[f] = None - elif os.path.isdir(path + '/' + f): + elif os.path.isdir(path + "/" + f): tree[f] = {} - SnakeWM.iter_dir(tree[f], path + '/' + f) + SnakeWM.iter_dir(tree[f], path + "/" + f) def loadapp(self, app, params=None): """ @@ -89,7 +83,7 @@ class SnakeWM: examples. """ if not TESTMODE: - app = 'snakewm.' + app + app = "snakewm." + app _app = importlib.import_module(app) _app.load(self.MANAGER, params) @@ -133,40 +127,40 @@ class SnakeWM: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: - if event.key == pygame.K_LSUPER: - if self.APPMENU is None: - # open app menu - self.APPMENU = AppMenuPanel( - self.MANAGER, - (0, 0), - 'apps', - self.APPS, - self.appmenu_load - ) - else: - # close app menu - self.APPMENU.destroy() - self.APPMENU = None - - if pressed[pygame.K_LALT]: - if event.key == pygame.K_ESCAPE: - running = False - pygame.quit() - exit() + if event.key == pygame.K_LSUPER: + if self.APPMENU is None: + # open app menu + self.APPMENU = AppMenuPanel( + self.MANAGER, + (0, 0), + "apps", + self.APPS, + self.appmenu_load, + ) + else: + # close app menu + self.APPMENU.destroy() + self.APPMENU = None + + if pressed[pygame.K_LALT]: + if event.key == pygame.K_ESCAPE: + running = False + pygame.quit() + exit() elif event.type == pygame.USEREVENT: - if event.user_type == 'window_selected': + if event.user_type == "window_selected": # focus selected window if self.FOCUS is not None: self.FOCUS.unfocus() self.FOCUS = event.ui_element self.FOCUS.focus() elif event.user_type == pygame_gui.UI_COLOUR_PICKER_COLOUR_PICKED: - if event.ui_object_id == '#desktop_colour_picker': + if event.ui_object_id == "#desktop_colour_picker": # set desktop background color - no alpha channel self.set_bg_color(event.colour[:-1]) elif event.user_type == pygame_gui.UI_FILE_DIALOG_PATH_PICKED: - if event.ui_object_id == '#background_picker': + if event.ui_object_id == "#background_picker": self.set_bg_image(event.text) self.MANAGER.process_events(event) @@ -177,6 +171,7 @@ class SnakeWM: self.MANAGER.draw_ui(self.SCREEN) pygame.display.update() + if TESTMODE: wm = SnakeWM() wm.run()