From: <Blu...@us...> - 2010-04-24 21:22:42
|
Revision: 337 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=337&view=rev Author: BlueWolf_ Date: 2010-04-24 21:22:36 +0000 (Sat, 24 Apr 2010) Log Message: ----------- I'm starting with the client-app! It actually draws an awesome RECTANGLE right now! Wheee! Added Paths: ----------- trunk/client/VP.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added: trunk/client/VP.py =================================================================== --- trunk/client/VP.py (rev 0) +++ trunk/client/VP.py 2010-04-24 21:22:36 UTC (rev 337) @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +from functions import * + +from playground import Playground +from layout import Layout +from windows import Windows + + +class Main(): + def __init__(self): + # This will be available ([sh]ared) to all functions + self.sh = {} + + self.blit_lock = threading.Lock() + + # Fire up pygame + os.environ['SDL_VIDEO_CENTERED']='1' + pygame.init() + pygame.display.set_caption('Virtual Playground') + self.sh['screen'] = pygame.display.set_mode((1000, 700)) + #icon = load_image('img','icon.png') + #pygame.display.set_icon(icon) + pygame.key.set_repeat(250, 40) + pygame.scrap.init() + + # Give the program a way to close itself. Just call .set() and + # all your problems will be gone + self.sh['close'] = threading.Event() + + + # Give the surfaces a way to blit themselves + self.sh['update'] = self.update + + # Create all our surfaces + self.sh['playground'] = Playground(self.sh) + self.sh['layout'] = Layout(self.sh) + self.sh['windows'] = Windows(self.sh) + + self.update() + + + + # Wait until someone decides to close VP (Why??) + try: self.sh['close'].wait(31556926) # A timeout of a year, + # should be enough + except: print + sys.exit() + + + def update(self, rect = Rect(0,0, 1000, 700)): + """ + Blit all the surfaces (playground, layout and windows) together + and update the screen + """ + + # Prevent multiple threads blitting at + # the same time + self.blit_lock.acquire() + + self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) + self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) + self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + + pygame.display.update(rect) + + self.blit_lock.release() + +if __name__ == "__main__": Main() Property changes on: trunk/client/VP.py ___________________________________________________________________ Added: svn:executable + * Added: trunk/client/functions.py =================================================================== --- trunk/client/functions.py (rev 0) +++ trunk/client/functions.py 2010-04-24 21:22:36 UTC (rev 337) @@ -0,0 +1,27 @@ +import pygame, os, sys, threading +from pygame.locals import * +import core + + +def real_path(*dir): + """ + Get the real path to this file + """ + return os.path.join(sys.path[0], *dir) + +def load_image(alpha, *dir): + """ + This will load an image for pygame + """ + + fullname = real_path(*dir) + try: + image = pygame.image.load(fullname) + if image.get_alpha is None or alpha == False: + image = image.convert() + else: + image = image.convert_alpha() + except pygame.error, message: + print 'Cannot load image:', fullname + raise SystemExit, message + return image Added: trunk/client/layout.py =================================================================== --- trunk/client/layout.py (rev 0) +++ trunk/client/layout.py 2010-04-24 21:22:36 UTC (rev 337) @@ -0,0 +1,9 @@ +from functions import * + +class Layout(): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ + SRCALPHA).convert_alpha() + + self.surf.fill([0,100,0], Rect(100,100, 150,150)) Added: trunk/client/playground.py =================================================================== --- trunk/client/playground.py (rev 0) +++ trunk/client/playground.py 2010-04-24 21:22:36 UTC (rev 337) @@ -0,0 +1,9 @@ +from functions import * + +class Playground(): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ + SRCALPHA).convert_alpha() + + self.surf.fill([0,0,0]) Added: trunk/client/windows.py =================================================================== --- trunk/client/windows.py (rev 0) +++ trunk/client/windows.py 2010-04-24 21:22:36 UTC (rev 337) @@ -0,0 +1,7 @@ +from functions import * + +class Windows(): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ + SRCALPHA).convert_alpha() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-04-24 22:05:43
|
Revision: 338 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=338&view=rev Author: BlueWolf_ Date: 2010-04-24 22:05:37 +0000 (Sat, 24 Apr 2010) Log Message: ----------- Moved the sh a bit and added a event-loop. Use the close-button to exit. Ctrl+c acts random Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-04-24 21:22:36 UTC (rev 337) +++ trunk/client/VP.py 2010-04-24 22:05:37 UTC (rev 338) @@ -9,43 +9,49 @@ class Main(): def __init__(self): - # This will be available ([sh]ared) to all functions - self.sh = {} - self.blit_lock = threading.Lock() # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' pygame.init() pygame.display.set_caption('Virtual Playground') - self.sh['screen'] = pygame.display.set_mode((1000, 700)) + sh['screen'] = pygame.display.set_mode((1000, 700)) #icon = load_image('img','icon.png') #pygame.display.set_icon(icon) pygame.key.set_repeat(250, 40) pygame.scrap.init() - # Give the program a way to close itself. Just call .set() and - # all your problems will be gone - self.sh['close'] = threading.Event() - - # Give the surfaces a way to blit themselves - self.sh['update'] = self.update + sh['update'] = self.update # Create all our surfaces - self.sh['playground'] = Playground(self.sh) - self.sh['layout'] = Layout(self.sh) - self.sh['windows'] = Windows(self.sh) + sh['playground'] = Playground() + sh['layout'] = Layout() + sh['windows'] = Windows() self.update() - - # Wait until someone decides to close VP (Why??) - try: self.sh['close'].wait(31556926) # A timeout of a year, - # should be enough - except: print + # Wait for all the events to come + try: + while 1: + ev = pygame.event.wait() + + if ev.type == QUIT: break + + if ev.type == MOUSEMOTION: + pos = pygame.mouse.get_pos() + pygame.event.clear(MOUSEMOTION) + + # [TODO] Do something + + + except KeyboardInterrupt: # Note: this does not work properly + print + + # Someone decided to close VP (Why??) sys.exit() + def update(self, rect = Rect(0,0, 1000, 700)): @@ -58,9 +64,9 @@ # the same time self.blit_lock.acquire() - self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) - self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) - self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + sh['screen'].blit(sh['playground'].surf, rect, rect) + sh['screen'].blit(sh['layout'].surf, rect, rect) + sh['screen'].blit(sh['windows'].surf, rect, rect) pygame.display.update(rect) Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-04-24 21:22:36 UTC (rev 337) +++ trunk/client/functions.py 2010-04-24 22:05:37 UTC (rev 338) @@ -2,6 +2,9 @@ from pygame.locals import * import core +# This will be used to [sh]are all variables, functions and classes across the +# code +sh = {} def real_path(*dir): """ Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-04-24 21:22:36 UTC (rev 337) +++ trunk/client/layout.py 2010-04-24 22:05:37 UTC (rev 338) @@ -1,8 +1,7 @@ from functions import * class Layout(): - def __init__(self, sh): - self.sh = sh + def __init__(self): self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-04-24 21:22:36 UTC (rev 337) +++ trunk/client/playground.py 2010-04-24 22:05:37 UTC (rev 338) @@ -1,8 +1,7 @@ from functions import * class Playground(): - def __init__(self, sh): - self.sh = sh + def __init__(self): self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-04-24 21:22:36 UTC (rev 337) +++ trunk/client/windows.py 2010-04-24 22:05:37 UTC (rev 338) @@ -1,7 +1,6 @@ from functions import * class Windows(): - def __init__(self, sh): - self.sh = sh + def __init__(self): self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 16:06:53
|
Revision: 341 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=341&view=rev Author: BlueWolf_ Date: 2010-07-28 16:06:43 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Starting with the interface here as well! :D Modified Paths: -------------- trunk/client/VP.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added Paths: ----------- trunk/client/images/ trunk/client/images/loginbg.png trunk/client/images/topbar1.png trunk/client/images/topbar2.png trunk/client/images/topbar3.png Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/VP.py 2010-07-28 16:06:43 UTC (rev 341) @@ -21,8 +21,11 @@ pygame.key.set_repeat(250, 40) pygame.scrap.init() - # Give the surfaces a way to blit themselves + # Give the surfaces a way to blit itself sh['update'] = self.update + + sh['status'] = "login" # What the user is seeing + # login - playground # Create all our surfaces sh['playground'] = Playground() @@ -43,7 +46,10 @@ pos = pygame.mouse.get_pos() pygame.event.clear(MOUSEMOTION) - # [TODO] Do something + # Send through all the layers + if sh['windows'].event(ev): continue + if sh['layout'].event(ev): continue + if sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly @@ -60,8 +66,7 @@ and update the screen """ - # Prevent multiple threads blitting at - # the same time + # Prevent multiple threads from blitting at the same time self.blit_lock.acquire() sh['screen'].blit(sh['playground'].surf, rect, rect) Added: trunk/client/images/loginbg.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/loginbg.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar1.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar1.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar2.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar2.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/images/topbar3.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/topbar3.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/layout.py 2010-07-28 16:06:43 UTC (rev 341) @@ -5,4 +5,5 @@ self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() - self.surf.fill([0,100,0], Rect(100,100, 150,150)) + def event(self, ev): + pass Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/playground.py 2010-07-28 16:06:43 UTC (rev 341) @@ -6,3 +6,13 @@ SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) + + self.loginbg = None + self.drawlogin() + + def event(self, ev): + print ev + + def drawlogin(self): + self.loginbg = load_image(False, "images", "loginbg.png") + self.surf.blit(self.loginbg, (0,0)) Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-07-28 15:37:05 UTC (rev 340) +++ trunk/client/windows.py 2010-07-28 16:06:43 UTC (rev 341) @@ -4,3 +4,6 @@ def __init__(self): self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() + + def event(self, ev): + pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 19:19:10
|
Revision: 342 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=342&view=rev Author: BlueWolf_ Date: 2010-07-28 19:19:04 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Made a really fast (fake) login. But it will connect and login with the server now! Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added Paths: ----------- trunk/client/fonts/ trunk/client/fonts/DejaVuSans-Bold.ttf trunk/client/fonts/DejaVuSans.ttf Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/VP.py 2010-07-28 19:19:04 UTC (rev 342) @@ -2,6 +2,8 @@ from functions import * +import core + from playground import Playground from layout import Layout from windows import Windows @@ -9,30 +11,43 @@ class Main(): def __init__(self): - self.blit_lock = threading.Lock() + self.sh = {} # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' pygame.init() pygame.display.set_caption('Virtual Playground') - sh['screen'] = pygame.display.set_mode((1000, 700)) + self.sh['screen'] = pygame.display.set_mode((1000, 700)) #icon = load_image('img','icon.png') #pygame.display.set_icon(icon) pygame.key.set_repeat(250, 40) pygame.scrap.init() - + self.clock = pygame.time.Clock() + + self.sh['main'] = self + # Give the surfaces a way to blit itself - sh['update'] = self.update + self.sh['update'] = self.update + self.updaterect = [] + self.updatewaiting = False - sh['status'] = "login" # What the user is seeing - # login - playground # Create all our surfaces - sh['playground'] = Playground() - sh['layout'] = Layout() - sh['windows'] = Windows() + self.sh['playground'] = Playground(self.sh) + self.sh['layout'] = Layout(self.sh) + self.sh['windows'] = Windows(self.sh) self.update() + + + # Connect to the server + self.sh['client'] = core.Client({ + 'app_name': "Virtual Playground", + 'app_version': VERSION}, + Callback(self.sh)) + + self.changestatus("connecting") + self.sh['client'].connect('vp.bluewolf.nl', 6653) # Wait for all the events to come @@ -47,9 +62,9 @@ pygame.event.clear(MOUSEMOTION) # Send through all the layers - if sh['windows'].event(ev): continue - if sh['layout'].event(ev): continue - if sh['playground'].event(ev): continue + if self.sh['windows'].event(ev): continue + if self.sh['layout'].event(ev): continue + if self.sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly @@ -66,15 +81,65 @@ and update the screen """ - # Prevent multiple threads from blitting at the same time - self.blit_lock.acquire() + # The following code will prevent it from going crazy on the cpu + # aka: using unlimited FPS. This will limit the FPS to 50 and + # will remember everything that should be updated in the mean + # time - sh['screen'].blit(sh['playground'].surf, rect, rect) - sh['screen'].blit(sh['layout'].surf, rect, rect) - sh['screen'].blit(sh['windows'].surf, rect, rect) + self.updaterect.append(rect) + if self.updatewaiting: + # Rect is saved. Will be updated once self.clock stops + # blocking + return + # When there are more updates from here one, they will be saved + # without being updated immediately. We will do that once tick + # stops blocking + self.updatewaiting = True + self.clock.tick(50) + + # Get all the rects to update + if len(self.updaterect) == 1: + rects = self.updaterect[0] + else: + rects = self.updaterect[0].unionall(self.updaterect[1:]) + + self.updaterect = [] + self.updatewaiting = False + + + # The actual updating happens here + self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) + self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) + self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + pygame.display.update(rect) + + def changestatus(self, status): + self.sh['playground'].changestatus(status) + self.sh['layout'].changestatus(status) + self.sh['windows'].changestatus(status) + + +class Callback(core.Callback): + def __init__(self, sh): + self.sh = sh - self.blit_lock.release() + def data_received(self, data): + print " --> " + repr(data) + + def data_send(self, data): + print " <-- " + repr(data) + + def disconnect(self, reason): + print "Server disconnected: " + reason + + def received_rsa(self, public): + # We are connected + self.sh['main'].changestatus("login") + + def logged_in(self, username, cid, owner): + self.sh['main'].changestatus("playground") + if __name__ == "__main__": Main() Added: trunk/client/fonts/DejaVuSans-Bold.ttf =================================================================== (Binary files differ) Property changes on: trunk/client/fonts/DejaVuSans-Bold.ttf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/client/fonts/DejaVuSans.ttf =================================================================== (Binary files differ) Property changes on: trunk/client/fonts/DejaVuSans.ttf ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/functions.py 2010-07-28 19:19:04 UTC (rev 342) @@ -2,6 +2,8 @@ from pygame.locals import * import core +VERSION = "0.0.1" + # This will be used to [sh]are all variables, functions and classes across the # code sh = {} Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/layout.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,9 +1,38 @@ from functions import * class Layout(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() + self.status = None + + # Login stuff + self.loginbg = None + self.loginfont = None + + # Playground stuff + self.topbar = None + def event(self, ev): pass + + + def changestatus(self, status): + login_list = ['connecting', 'login', 'logging in'] + if status in login_list and self.status not in login_list: + # (Un)load all the data + self.topbar = None + + elif status == "playground": + self.topbar = [ + load_image(True, "images", "topbar1.png"), + load_image(True, "images", "topbar2.png"), + load_image(True, "images", "topbar3.png") + ] + + self.surf.blit(self.topbar[0], (0,0)) + + self.sh['update']() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/playground.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,18 +1,81 @@ from functions import * class Playground(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) + self.status = None + # Login stuff self.loginbg = None - self.drawlogin() + self.loginfont = None + + # Playground stuff + # ... def event(self, ev): - print ev + if self.status == "login": + if ev.type == KEYDOWN and ev.unicode == "\r": + # Fake login + self.drawlogin("logging in") + self.sh['client'].login("myname", "mypass") + - def drawlogin(self): - self.loginbg = load_image(False, "images", "loginbg.png") + def changestatus(self, status): + login_list = ['connecting', 'login', 'logging in'] + if status in login_list and self.status not in login_list: + # (Un)load all the data + self.loginbg = load_image(False, "images", \ + "loginbg.png") + self.loginfont = pygame.font.Font(real_path("fonts", \ + "DejaVuSans.ttf"), 35) + + + elif status == "playground": + # (Un)oad all the data + self.loginbg = None + self.loginfont = None + + self.surf.fill([0,0,0]) + self.sh['update']() + + + if status == "connecting": + self.drawlogin("connecting") + elif status == "login": + self.drawlogin("login") + elif status == "logging in": + self.drawlogin("logging in") + + self.status = status + + + def drawlogin(self, status): + self.loginstatus = status self.surf.blit(self.loginbg, (0,0)) + + if status == "connecting": + + text = self.loginfont.render("Connecting...", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + elif status == "login": + text = self.loginfont.render("Login-placeholder. " + \ + "Hit enter to fake log in", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + elif status == "logging in": + text = self.loginfont.render("Logging in...", True, \ + (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + + self.sh['update']() Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-07-28 16:06:43 UTC (rev 341) +++ trunk/client/windows.py 2010-07-28 19:19:04 UTC (rev 342) @@ -1,9 +1,14 @@ from functions import * class Windows(): - def __init__(self): + def __init__(self, sh): + self.sh = sh + self.surf = pygame.Surface((1000, 700), \ SRCALPHA).convert_alpha() def event(self, ev): pass + + def changestatus(self, status): + pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 20:51:53
|
Revision: 343 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=343&view=rev Author: BlueWolf_ Date: 2010-07-28 20:51:47 +0000 (Wed, 28 Jul 2010) Log Message: ----------- The topnav reacts to hovers. And then I discovered the image isn't perfect symmetric, hence the weird block box that appears next to the right button. grr.. Modified Paths: -------------- trunk/client/layout.py trunk/client/playground.py Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 19:19:04 UTC (rev 342) +++ trunk/client/layout.py 2010-07-28 20:51:47 UTC (rev 343) @@ -1,6 +1,12 @@ from functions import * +TOPBUTTONS = 3 +TOPLEFT = 44 +TOPBUTTONWIDTH = 304 +TOPHEIGHT = 65 + class Layout(): + def __init__(self, sh): self.sh = sh @@ -9,6 +15,9 @@ self.status = None + self.selected = None + self.hover = None + # Login stuff self.loginbg = None self.loginfont = None @@ -17,9 +26,27 @@ self.topbar = None def event(self, ev): - pass + if self.status == "playground": + if ev.type == MOUSEMOTION: + if ev.pos[0] > 44 and ev.pos[0] < 926 and \ + ev.pos[1] < 55: + + index = (ev.pos[0]-TOPLEFT)/ \ + TOPBUTTONWIDTH + + if self.hover == index: return True + self.hover = index + self.updatetop() + + return True + else: + if self.hover == None: return + self.hover = None + self.updatetop() + + def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] if status in login_list and self.status not in login_list: @@ -33,6 +60,28 @@ load_image(True, "images", "topbar3.png") ] + self.selected = None + self.hover = None # [TODO] This can be better self.surf.blit(self.topbar[0], (0,0)) - - self.sh['update']() + self.updatetop() + + self.status = status + + + def updatetop(self): + for i in range(TOPBUTTONS): + left = TOPLEFT + (TOPBUTTONWIDTH*i) + rect = (left, 0, TOPBUTTONWIDTH, TOPHEIGHT) + + self.surf.fill([0,0,0,0], rect) + + if self.selected == i: # This button is selected + self.surf.blit(self.topbar[2], rect, rect) + + elif self.hover == i: # This button is hovered + self.surf.blit(self.topbar[1], rect, rect) + + else: + self.surf.blit(self.topbar[0], rect, rect) + + self.sh['update']() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-28 19:19:04 UTC (rev 342) +++ trunk/client/playground.py 2010-07-28 20:51:47 UTC (rev 343) @@ -22,7 +22,7 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("myname", "mypass") + self.sh['client'].login("BlueWolf", "mypass") def changestatus(self, status): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-07-28 23:02:18
|
Revision: 345 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=345&view=rev Author: BlueWolf_ Date: 2010-07-28 23:02:12 +0000 (Wed, 28 Jul 2010) Log Message: ----------- Topbar looks now good. You can now click on them (nothing happens, only the image will change) and merged the 3 states into a single image Modified Paths: -------------- trunk/client/images/topbar1.png trunk/client/images/topbar2.png trunk/client/images/topbar3.png trunk/client/layout.py Modified: trunk/client/images/topbar1.png =================================================================== (Binary files differ) Modified: trunk/client/images/topbar2.png =================================================================== (Binary files differ) Modified: trunk/client/images/topbar3.png =================================================================== (Binary files differ) Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-28 22:53:36 UTC (rev 344) +++ trunk/client/layout.py 2010-07-28 23:02:12 UTC (rev 345) @@ -28,12 +28,8 @@ def event(self, ev): if self.status == "playground": if ev.type == MOUSEMOTION: - if ev.pos[0] > 44 and ev.pos[0] < 926 and \ - ev.pos[1] < 55: - - index = (ev.pos[0]-TOPLEFT)/ \ - TOPBUTTONWIDTH - + index = self.topbarcursor(ev.pos) + if index is not False: if self.hover == index: return True self.hover = index self.updatetop() @@ -43,7 +39,26 @@ if self.hover == None: return self.hover = None self.updatetop() + + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse events + if ev.gain == 0: # Lost mouse focus + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == MOUSEBUTTONDOWN: + index = self.topbarcursor(ev.pos) + if index is False: return + + if self.selected == index: + self.selected = None + else: + self.selected = index + self.updatetop() + return True + @@ -54,15 +69,11 @@ self.topbar = None elif status == "playground": - self.topbar = [ - load_image(True, "images", "topbar1.png"), - load_image(True, "images", "topbar2.png"), - load_image(True, "images", "topbar3.png") - ] + self.topbar = load_image(True, "images", "topbar.png") self.selected = None - self.hover = None # [TODO] This can be better - self.surf.blit(self.topbar[0], (0,0)) + self.hover = self.topbarcursor(pygame.mouse.get_pos()) + self.surf.blit(self.topbar, (0,0), (0,0,1000,TOPHEIGHT)) self.updatetop() self.status = status @@ -71,17 +82,27 @@ def updatetop(self): for i in range(TOPBUTTONS): left = TOPLEFT + (TOPBUTTONWIDTH*i) - rect = (left, 0, TOPBUTTONWIDTH, TOPHEIGHT) + rect = Rect(left, 0, TOPBUTTONWIDTH, TOPHEIGHT) self.surf.fill([0,0,0,0], rect) - if self.selected == i: # This button is selected - self.surf.blit(self.topbar[2], rect, rect) + if self.selected is i: # This button is selected + rect2 = rect.move(0,TOPHEIGHT*2) - elif self.hover == i: # This button is hovered - self.surf.blit(self.topbar[1], rect, rect) + elif self.hover is i: # This button is hovered + rect2 = rect.move(0,TOPHEIGHT) else: - self.surf.blit(self.topbar[0], rect, rect) + rect2 = rect.move(0,0) + + self.surf.blit(self.topbar, rect, rect2) self.sh['update']() + + + def topbarcursor(self, pos): + if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ + and pos[1] < 55: + return (pos[0]-TOPLEFT) / TOPBUTTONWIDTH + else: + return False This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-01 21:27:20
|
Revision: 350 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=350&view=rev Author: BlueWolf_ Date: 2010-08-01 21:27:14 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Starting with the GUI-stuff. Hitting R when seeing the black box will result in a (fake) signup-request Modified Paths: -------------- trunk/client/VP.py trunk/client/core/client.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py Added Paths: ----------- trunk/client/gui.py trunk/client/images/loginbox.png Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/VP.py 2010-08-01 21:27:14 UTC (rev 350) @@ -71,6 +71,8 @@ print # Someone decided to close VP (Why??) + try: self.sh['client'].close() + except: pass sys.exit() Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/core/client.py 2010-08-01 21:27:14 UTC (rev 350) @@ -110,7 +110,7 @@ If you want to reconnect, you have to close the connection first, if it's still open. - You can to Client.login and Client.bot_login directly after + You can do Client.login and Client.bot_login directly after this. It will be done as soon as it has received a rsa-key. """ @@ -258,6 +258,28 @@ }) + def signup(self, usr, pwd, extra = {}): + """ + Create a new account with on the server. You should have a + connection first before using this. + """ + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + if self.cid != None: + raise SignupError("You are already logged in") + + + # Sign up + self.send("signup", { + "usr": usr, + "pwd": pwd, + "extra": extra + }) + + + def send(self, data_header, data_body = {}): """ Sends `data_body` of type `data_header` to the server. It will @@ -293,9 +315,11 @@ self.__do_connect.clear() # Block the thread-loop self.__sh['is_online'] = False - self.__pinger.cancel() - self.__pinger = None + if self.__pinger != None: + self.__pinger.cancel() + self.__pinger = None + # Reset variables self.__sh['rsakey'] = None self.username = None @@ -350,3 +374,6 @@ class LoginError(Exception): pass + +class SignupError(Exception): + pass Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/functions.py 2010-08-01 21:27:14 UTC (rev 350) @@ -1,6 +1,8 @@ import pygame, os, sys, threading from pygame.locals import * +from hashlib import sha1 import core +import gui VERSION = "0.0.1" Added: trunk/client/gui.py =================================================================== --- trunk/client/gui.py (rev 0) +++ trunk/client/gui.py 2010-08-01 21:27:14 UTC (rev 350) @@ -0,0 +1,84 @@ +from functions import * + +class Plane(): + + def __init__(self, update, width, height): + self.update = update + self.width = width + self.height = height + self.surf = pygame.Surface((self.width, self.height), \ + SRCALPHA).convert_alpha() + self.norender = True + + self.childs = {} + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + + def renderall(self): + self.norender = False + for child in self.childs.values(): + child.renderall(Rect(0,0,0,0), self.surf) + + self.update(Rect(0,0, self.width, self.height)) + + + +class Object(): + + def __init__(self, name, rect): + self.name = name + self.rect = Rect(rect) + self.childs = {} + self.focus = False + self.hover = False + + # Load the defaults + self.__defaults__() + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self, correction, surf): + # First render ourself + self.render(correction, surf) + + # Then render our childs + for child in self.childs.values(): + child.renderall(correction.move(self.rect.topleft), surf) + + + +class Text(Object): + + def __defaults__(self): + self.input = "" + self.cursorpos = 0 + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([255,0,0], pos) + + +class Button(Object): + + def __defaults__(self): + self.caption = "" + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([0,0,255], pos) + Added: trunk/client/images/loginbox.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/loginbox.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/layout.py 2010-08-01 21:27:14 UTC (rev 350) @@ -97,7 +97,7 @@ self.surf.blit(self.topbar, rect, rect2) - self.sh['update']() + self.sh['update']((0,0, 1000, 65)) def topbarcursor(self, pos): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-07-30 00:32:51 UTC (rev 349) +++ trunk/client/playground.py 2010-08-01 21:27:14 UTC (rev 350) @@ -12,7 +12,9 @@ # Login stuff self.loginbg = None + self.loginbox = None self.loginfont = None + self.logingui = None # Playground stuff # ... @@ -22,23 +24,34 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("test", "123") + self.sh['client'].login("test123", sha1("test123").hexdigest()) + + elif ev.type == KEYDOWN and ev.unicode == "r": + # Fake signup + self.sh['client'].signup("test123", sha1("test123").hexdigest(), { + "realname": "Pietje Precies", + "gender": "M" + }) def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] if status in login_list and self.status not in login_list: - # (Un)load all the data + # (Un)load all the data for the login self.loginbg = load_image(False, "images", \ "loginbg.png") + self.loginbox = load_image(True, "images", \ + "loginbox.png") self.loginfont = pygame.font.Font(real_path("fonts", \ "DejaVuSans.ttf"), 35) elif status == "playground": - # (Un)oad all the data + # (Un)load all the data for the playground self.loginbg = None + self.loginbox = None self.loginfont = None + self.logingui = None self.surf.fill([0,0,0]) self.sh['update']() @@ -66,11 +79,17 @@ self.surf.blit(text, (posleft, 330)) elif status == "login": - text = self.loginfont.render("Login-placeholder. " + \ - "Hit enter to fake log in", True, \ - (132,125,114)) - posleft = (1000/2)-(text.get_size()[0]/2) - self.surf.blit(text, (posleft, 330)) + self.surf.blit(self.loginbox, (292,256)) + # Create login-field + #self.logingui = gui.Plane(self.drawlogingui, 417,189) + #username = gui.Text("username", (0,0, 417, 50)) + #password = gui.Text("password", (0,50, 417, 50)) + #login = gui.Button("login", (0, 100, 417, 50)) + #self.logingui.add(username, password, login) + + # [TODO] Give mouseposition + #self.logingui.renderall() + elif status == "logging in": text = self.loginfont.render("Logging in...", True, \ @@ -79,3 +98,13 @@ self.surf.blit(text, (posleft, 330)) self.sh['update']() + + + def drawlogingui(self, rect): + rect_main = rect.move(292,256) + + self.surf.blit(self.loginbg, rect_main, rect_main) + self.surf.blit(self.loginbox, rect_main, rect) + self.surf.blit(self.logingui.surf, rect_main, rect) + + self.sh['update'](rect_main) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-01 22:16:26
|
Revision: 351 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=351&view=rev Author: BlueWolf_ Date: 2010-08-01 22:16:19 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Code is still the same but I changed all tabs. 8 tabs are now 4 spaces. Modified Paths: -------------- trunk/client/VP.py trunk/client/core/__init__.py trunk/client/core/callback.py trunk/client/core/client.py trunk/client/core/parser.py trunk/client/functions.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/VP.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,5 +1,22 @@ #!/usr/bin/env python +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * import core @@ -10,138 +27,135 @@ class Main(): - def __init__(self): - self.sh = {} - - # Fire up pygame - os.environ['SDL_VIDEO_CENTERED']='1' - pygame.init() - pygame.display.set_caption('Virtual Playground') - self.sh['screen'] = pygame.display.set_mode((1000, 700)) - #icon = load_image('img','icon.png') - #pygame.display.set_icon(icon) - pygame.key.set_repeat(250, 40) - pygame.scrap.init() - self.clock = pygame.time.Clock() - - self.sh['main'] = self - - # Give the surfaces a way to blit itself - self.sh['update'] = self.update - self.updaterect = [] - self.updatewaiting = False - - - # Create all our surfaces - self.sh['playground'] = Playground(self.sh) - self.sh['layout'] = Layout(self.sh) - self.sh['windows'] = Windows(self.sh) - - self.update() - - - # Connect to the server - self.sh['client'] = core.Client({ - 'app_name': "Virtual Playground", - 'app_version': VERSION}, - Callback(self.sh)) - - self.changestatus("connecting") - self.sh['client'].connect('localhost', 6653) - - - # Wait for all the events to come - try: - while 1: - ev = pygame.event.wait() - - if ev.type == QUIT: break - - if ev.type == MOUSEMOTION: - pos = pygame.mouse.get_pos() - pygame.event.clear(MOUSEMOTION) - - # Send through all the layers - if self.sh['windows'].event(ev): continue - if self.sh['layout'].event(ev): continue - if self.sh['playground'].event(ev): continue - - - except KeyboardInterrupt: # Note: this does not work properly - print - - # Someone decided to close VP (Why??) - try: self.sh['client'].close() - except: pass - sys.exit() - + def __init__(self): + self.sh = {} + + # Fire up pygame + os.environ['SDL_VIDEO_CENTERED']='1' + pygame.init() + pygame.display.set_caption('Virtual Playground') + self.sh['screen'] = pygame.display.set_mode((1000, 700)) + #icon = load_image('img','icon.png') + #pygame.display.set_icon(icon) + pygame.key.set_repeat(250, 40) + pygame.scrap.init() + self.clock = pygame.time.Clock() + + self.sh['main'] = self + + # Give the surfaces a way to blit itself + self.sh['update'] = self.update + self.updaterect = [] + self.updatewaiting = False + + + # Create all our surfaces + self.sh['playground'] = Playground(self.sh) + self.sh['layout'] = Layout(self.sh) + self.sh['windows'] = Windows(self.sh) + + self.update() + + + # Connect to the server + self.sh['client'] = core.Client({ + 'app_name': "Virtual Playground", + 'app_version': VERSION}, + Callback(self.sh)) + + self.changestatus("connecting") + self.sh['client'].connect('localhost', 6653) + + + # Wait for all the events to come + try: + while 1: + ev = pygame.event.wait() + + if ev.type == QUIT: break + + if ev.type == MOUSEMOTION: + pos = pygame.mouse.get_pos() + pygame.event.clear(MOUSEMOTION) + + # Send through all the layers + if self.sh['windows'].event(ev): continue + if self.sh['layout'].event(ev): continue + if self.sh['playground'].event(ev): continue + + + except KeyboardInterrupt: # Note: this does not work properly + print + + # Someone decided to close VP (Why??) + try: self.sh['client'].close() + except: pass + sys.exit() + - def update(self, rect = Rect(0,0, 1000, 700)): - """ - Blit all the surfaces (playground, layout and windows) together - and update the screen - """ - - # The following code will prevent it from going crazy on the cpu - # aka: using unlimited FPS. This will limit the FPS to 50 and - # will remember everything that should be updated in the mean - # time - - self.updaterect.append(rect) - if self.updatewaiting: - # Rect is saved. Will be updated once self.clock stops - # blocking - return - - # When there are more updates from here one, they will be saved - # without being updated immediately. We will do that once tick - # stops blocking - self.updatewaiting = True - self.clock.tick(50) - - # Get all the rects to update - if len(self.updaterect) == 1: - rects = self.updaterect[0] - else: - rects = self.updaterect[0].unionall(self.updaterect[1:]) - - self.updaterect = [] - self.updatewaiting = False - - - # The actual updating happens here - self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) - self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) - self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) - - pygame.display.update(rect) - - def changestatus(self, status): - self.sh['playground'].changestatus(status) - self.sh['layout'].changestatus(status) - self.sh['windows'].changestatus(status) + def update(self, rect = Rect(0,0, 1000, 700)): + """ + Blit all the surfaces (playground, layout and windows) together + and update the screen + """ + + # The following code will prevent it from going crazy on the cpu. + # aka: using unlimited FPS. This will limit the FPS to 50 and will + # remember everything that should be updated in the mean time + + self.updaterect.append(rect) + if self.updatewaiting: + # Rect is saved. Will be updated once self.clock stops blocking + return + + # When there are more updates from here one, they will be saved without + # being updated immediately. We will do that once tick stops blocking + self.updatewaiting = True + self.clock.tick(50) + + # Get all the rects to update + if len(self.updaterect) == 1: + rects = self.updaterect[0] + else: + rects = self.updaterect[0].unionall(self.updaterect[1:]) + + self.updaterect = [] + self.updatewaiting = False + + + # The actual updating happens here + self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) + self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) + self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + + pygame.display.update(rect) + + def changestatus(self, status): + self.sh['playground'].changestatus(status) + self.sh['layout'].changestatus(status) + self.sh['windows'].changestatus(status) class Callback(core.Callback): - def __init__(self, sh): - self.sh = sh - - def data_received(self, data): - print " --> " + repr(data) - - def data_send(self, data): - print " <-- " + repr(data) - - def disconnect(self, reason): - print "Server disconnected: " + reason - - def received_rsa(self, public): - # We are connected - self.sh['main'].changestatus("login") - - def logged_in(self, username, cid, owner): - self.sh['main'].changestatus("playground") + def __init__(self, sh): + self.sh = sh + + def data_received(self, data): + print " --> " + repr(data) + + def data_send(self, data): + print " <-- " + repr(data) + + def disconnect(self, reason): + print "Server disconnected: " + reason + + def received_rsa(self, public): + # We are connected + self.sh['main'].changestatus("login") + + def logged_in(self, username, cid, owner): + self.sh['main'].changestatus("playground") if __name__ == "__main__": Main() Modified: trunk/client/core/__init__.py =================================================================== --- trunk/client/core/__init__.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/__init__.py 2010-08-01 22:16:19 UTC (rev 351) @@ -28,10 +28,10 @@ The Client is the core. You need to create your own callback class, which should inherit the functions of Callback. You get feedback from your callback-class. >>> class callback(Callback): -... def connect(self): -... print "Connect!" -... def logged_in(self, username, uid, cid): - print "I'm logged in!" +... def connect(self): +... print "Connect!" +... def logged_in(self, username, uid, cid): + print "I'm logged in!" Because it inherits all the (empty) functions from Callback, you don't have to create all the functions yourself. Also, in help(Callback) you see all possible @@ -40,14 +40,14 @@ The next thing is the config. See help(Client) for all the available config-options. >>> config = { -... "app_name": "My awesome application", -... "app_version": "2.0" +... "app_name": "My awesome application", +... "app_version": "2.0" ... } Start the core. >>> client = Client(config, callback()) >>> client.connect("my.host.com", 1234, "Username", \ -... sha.new("Password").hexdigest()) +... sha.new("Password").hexdigest()) If you have the server online and your login is correct, it will print: Connect! Modified: trunk/client/core/callback.py =================================================================== --- trunk/client/core/callback.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/callback.py 2010-08-01 22:16:19 UTC (rev 351) @@ -16,134 +16,126 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Callback: - def connected(self): - """ - When the connection is made, this will be called. Note that the - server can still kick the connection because it is full. You - should not client.login here, because the server still has to - send a rsa-key. See callback.received_rsa for this event. + def connected(self): + """ + When the connection is made, this will be called. Note that the server + can still kick the connection because it is full. You should not + client.login here, because the server still has to send a rsa-key. See + callback.received_rsa for this event. - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def received_rsa(self, public): - """ - When a connection is made, the server will generate a rsa-key. - The client has to wait for this, before logging in. After this - event, you can use client.login (if you haven't specified a - login at client.connect) - - public: - The generated public rsa-key. It is a dict with 2 - values: e and n. It's used for encoding the password - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def disconnected(self, reason): - """ - This is called when the connection dies. For example when you - close the connection manually, the server kicks you, your modem - explodes or your cat eates the LAN cable. - - reason: - A string, representing the reason why it disconnected. - It currently has these options: - * "closed" - Server dropped the connection - unexpectedly - * "full" - Server is full and does not except - - more connections - * "manual" - Client (you) closed the connection - with .close() - * "duplicate" - Another client has logged in on this - account. This connection has been - kicked - * "crash" - A crash happened on the server. Unless - you sent malicious data or you're not - admin of the server, there's nothing - you can do about it - * "gone offline"- The server has just gone offline - - - Return True if you want it to reconnect. To avoid unexpected - behaviour, you should *only* do this when reason is "closed" or - "gone offline"! - If you provided the login in client.connect, it logs in - automatically. - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def data_received(self, data): - """ - Called when we received data from the server. Normally, you - don't need this. - - data: - Dict with the data that has been received - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def data_send(self, data): - """ - Called when we send data to the server. Normally, you - don't need this. - - data: - Dict with the data that will be send. - - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - pass - - def logged_in(self, username, cid, owner): - """ - Called when we are logged in. - - username: - The username for this user. Use this, instead what the - user typed in, because this has the right caps. Also - available in client.username. - cid: - The unique client-id for this connection. Also available - in client.cid - owner: - This is the owner-username for this bot. This variable - will be None when you log in as a normal user - - This is a placeholder. If you want to catch this event, - overwrite this in your own callback - """ - - pass - - def failed_logging_in(self, reason): - """ - This happens when the user could not log in. You can safely use - client.login again. - - reason: - The reason why the user could not log in: - * "bad login" - The username and/or password is wrong. - * "login not allowed" - You may not log in right now - * "bot limit reached" - There're to much bots logged - in for your account - * "login blocked" - You (or your IP) are blocked - * "duplicate user" - There is already someone - online with this username - """ - - pass + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def received_rsa(self, public): + """ + When a connection is made, the server will generate a rsa-key. The + client has to wait for this, before logging in. After this event, you + can use client.login (if you haven't specified a login at client.connect) + + public: + The generated public rsa-key. It is a dict with 2 values: e and n. + It's used for encoding the password + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def disconnected(self, reason): + """ + This is called when the connection dies. For example when you close the + connection manually, the server kicks you, your modem explodes or your + cat ate the LAN cable. + + reason: + A string, representing the reason why it disconnected. + It currently has these options: + * "closed" - Server dropped the connection unexpectedly + * "full" - Server is full and does not except more + connections + * "manual" - Client (you) closed the connection with .close() + * "duplicate" - Another client has logged in on this account. + This connection has been kicked + * "crash" - A crash happened on the server. Unless you sent + malicious data or you're not admin of the server, + there's nothing you can do about it. Live with it. + * "gone offline"- The server has just gone offline + + + Return True if you want it to reconnect. To avoid unexpected behaviour, + you should *only* do this when reason is "closed" or "gone offline"! If + you provided the login in client.connect, it logs in automatically. + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def data_received(self, data): + """ + Called when we received data from the server. Normally, you don't need + this. + + data: + Dict with the data that has been received + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def data_send(self, data): + """ + Called when we send data to the server. Normally, you don't need this. + + data: + Dict with the data that will be send. + + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + pass + + def logged_in(self, username, cid, owner): + """ + Called when we are logged in. + + username: + The username for this user. Use this, instead what the user typed + in, because this has the right caps. Also available in + client.username + cid: + The unique client-id for this connection. Also available in + client.cid + owner: + This is the owner-username for this bot. This variable will be None + when you log in as a normal user + + This is a placeholder. If you want to catch this event, overwrite this + in your own callback + """ + + pass + + def failed_logging_in(self, reason): + """ + This happens when the user could not log in. You can safely use + client.login again + + reason: + The reason why the user could not log in: + * "bad login" - The username and/or password is wrong. + * "login not allowed" - You may not log in right now + * "bot limit reached" - There're to much bots logged in for + your account + * "login blocked" - You (or your IP) are blocked + * "duplicate user" - There is already someone online with + this username + """ + + pass Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/client.py 2010-08-01 22:16:19 UTC (rev 351) @@ -24,356 +24,350 @@ class Client(threading.Thread): - """ - This is the client-core for Virtual Playground. This will handle the - connections and data to and from the server. - - config: - This should be a dict with settings for the client. See the - bottom of this documentation for a list of all possible - settings. - - callback_class: - The callback class will be used to notify you for certain events - that happens in the core. It has to look something like this: - - class Callback(core.Callback): - ... - - See the doc in core.Callback for more information about this. - - -------- - - The settings: - -app_name - The name of your program. Will be send when logging in. - -app_version - The version of your program. Will be send when logging - in. Should be a string. - """ - - def __init__(self, config, callback_class): - - self.__call = callback_class - self.__sock = None - self.__pinger = None - - # This will be available ([sh]ared) to al modules in the core - self.__sh = {} - - self.__sh['call'] = callback_class - self.__sh['core'] = self - self.__sh['isbot'] = None - - # Create all default settings - self.__config_default(config) - self.__sh['config'] = config - - # So the client knows if we are online. Is used for - # disconnecting - self.__sh['is_online'] = False - - # Treading-event so that run() waits before it's allowed to - # connect - self.__do_connect = threading.Event() - self.__do_connect.clear() - - # Auto log in after connecting. - self.__sh['auto_login'] = () - - # RSA - self.__sh['rsakey'] = None - - # Info after logging in - self.username = None - self.owner = None - self.cid = None # Connection-id - - # Class that parsers all incomming data - self.__parse = Parser(self.__sh) - - threading.Thread.__init__(self) - - self.setDaemon(True) - self.start() - - - def __config_default(self, config): - config['app_name'] = str(config.get('app_name', __name__)) - config['app_version'] = str(config.get('app_version', - __version__)) - - - def connect(self, host, port): - """ - Will (try to) connect to the server on `host`:`port`. - If you want to reconnect, you have to close the connection - first, if it's still open. - - You can do Client.login and Client.bot_login directly after - this. It will be done as soon as it has received a rsa-key. - """ - - self.__host = host - self.__port = port - - if self.__sock: - raise ConnectionError("You are already connected!") - - self.__do_connect.set() # Releasing the hounds - - - def run(self): - """ - Used by threading, not for external usage. - """ - while 1: - self.__do_connect.wait() # Wait to connect - - self.__sh['is_online'] = True - disconnect_reason = None - - self.__sock = socket.socket(socket.AF_INET, - socket.SOCK_STREAM) - - while 1: - try: - self.__sock.connect((self.__host, - self.__port)) - break - except: - time.sleep(1) - - self.__call.connected() - - self.__pinger = self.__Pinger(self.send) + """ + This is the client-core for Virtual Playground. This will handle the + connections and data to and from the server. + + config: + This should be a dict with settings for the client. See the bottom of + this documentation for a list of all possible settings. + + callback_class: + The callback class will be used to notify you for certain events that + happens in the core. It has to look something like this: + + class Callback(core.Callback): + ... + + See the doc in core.Callback for more information about this. + + -------- + + The settings: + -app_name + The name of your program. Will be send when logging in. + -app_version + The version of your program. Will be send when logging + in. Should be a string. + """ + + def __init__(self, config, callback_class): + + self.__call = callback_class + self.__sock = None + self.__pinger = None + + # This will be available ([sh]ared) to al modules in the core + self.__sh = {} + + self.__sh['call'] = callback_class + self.__sh['core'] = self + self.__sh['isbot'] = None + + # Create all default settings + self.__config_default(config) + self.__sh['config'] = config + + # So the client knows if we are online. Is used for + # disconnecting + self.__sh['is_online'] = False + + # Treading-event so that run() waits before it's allowed to connect + self.__do_connect = threading.Event() + self.__do_connect.clear() + + # Auto log in after connecting. + self.__sh['auto_login'] = () + + # RSA + self.__sh['rsakey'] = None + + # Info after logging in + self.username = None + self.owner = None + self.cid = None # Connection-id + + # Class that parsers all incomming data + self.__parse = Parser(self.__sh) + + threading.Thread.__init__(self) + + self.setDaemon(True) + self.start() + + + def __config_default(self, config): + config['app_name'] = str(config.get('app_name', __name__)) + config['app_version'] = str(config.get('app_version', __version__)) + + + def connect(self, host, port): + """ + Will (try to) connect to the server on `host`:`port`. If you want to + reconnect, you have to close the connection first, if it's still open. + + You can do Client.login and Client.bot_login directly after this. It + will be done as soon as it has received a rsa-key. + """ + + self.__host = host + self.__port = port + + if self.__sock: + raise ConnectionError("You are already connected!") + + self.__do_connect.set() # Releasing the hounds + + + def run(self): + """ + Used by threading, not for external usage. + """ + while 1: + self.__do_connect.wait() # Wait to connect + + self.__sh['is_online'] = True + disconnect_reason = None + + self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + while 1: + try: + self.__sock.connect((self.__host, self.__port)) + break + except: + time.sleep(1) + + self.__call.connected() + + self.__pinger = self.__Pinger(self.send) - - #Infinite loop that receives data - buffer = '' - while 1: - try: - data = self.__sock.recv(1024) - except: - disconnect_reason = "closed" - break - if not data: - disconnect_reason = "closed" - break - - buffer += data - - #Each dataset must end with a delimiter: chr(1) - if chr(1) not in buffer: continue - - data = buffer.split(chr(1)) - buffer = data[-1] - data = data[:-1] - - for msg in data: - self.__parse(simplejson.loads(msg)) - - if self.__sh['is_online']: - self.close(disconnect_reason) - - def login(self, usr, pwd): - """ - Log in to the server as a normal user. If the RSA-key wasn't - received yet, it will login after is has received the key. pwd - is expected to be sha1. - - >>> import hashlib - >>> hashlib.sha1("MyVerySecretPassword").hexdigest() - 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' - """ - - if self.cid != None: - raise LoginError("You are already logged in") - - # Save this - self.__sh['auto_login'] = (self.login, (usr, pwd)) - - # Wait for the rsa-key to arrive - if not self.__sh['rsakey']: return - - if not self.__sock: - raise ConnectionError("You are not connected!") - - self.__sh['isbot'] = False - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - # Log in - self.send("login", { - "usr": usr, - "pwd": pwd, - "bot": False, - "for": "VP", - "client": ( self.__sh['config']['app_name'], - self.__sh['config']['app_version'] - ), - "version": __version__ - }) - - def login_bot(self, owner, pwd, screenname): - """ - Log in as a bot. If the RSA-key wasn't received yet, it will - login after is has received the key. pwd is expected to be sha1. - - >>> import hashlib - >>> hashlib.sha1("MyVerySecretPassword").hexdigest() - 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' - """ - - if self.cid != None: - raise LoginError("You are already logged in") - - # Save this - self.__sh['auto_login'] = (self.login_bot, \ - (owner, pwd, screenname)) - - # Wait for the rsa-key to arrive - if not self.__sh['rsakey']: return - - if not self.__sock: - raise ConnectionError("You are not connected!") - - self.__sh['isbot'] = True - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - # Log in - self.send("login", { - "usr": owner, - "pwd": pwd, - "name": screenname, - "bot": True, - "for": "VP", - "client": ( self.__sh['config']['app_name'], - self.__sh['config']['app_version'] - ), - "version": __version__ - }) - - - def signup(self, usr, pwd, extra = {}): - """ - Create a new account with on the server. You should have a - connection first before using this. - """ - - # Convert pwd - pwd = rsa.encrypt(pwd, self.__sh['rsakey']) - - if self.cid != None: - raise SignupError("You are already logged in") - - - # Sign up - self.send("signup", { - "usr": usr, - "pwd": pwd, - "extra": extra - }) - - - - def send(self, data_header, data_body = {}): - """ - Sends `data_body` of type `data_header` to the server. It will - automatically be encoded as JSON, and the delimeter character - (chr(1)) will be send automatically too. - `Data_header` is a string, `data_body` a dict. - """ - - self.__call.data_send({data_header:data_body}) - data = simplejson.dumps({data_header:data_body}) - try: - self.__sock.send(data + chr(1)) - except: pass - - - def close(self, reason = "manual"): - """ - Will close the connection to the server. If the connection is - already down, it will raise an exception. This will trigger the - callback `disconnected`. It may reconnect, depending on the - callback. If not, you can reuse this class by calling `connect`. - """ - - if not self.__sh['is_online']: - if reason == "manual": - # Annoy the user - raise ConnectionError("The connection is " + \ - "already closed!") - else: - return; - - - self.__do_connect.clear() # Block the thread-loop - - self.__sh['is_online'] = False - - if self.__pinger != None: - self.__pinger.cancel() - self.__pinger = None - - # Reset variables - self.__sh['rsakey'] = None - self.username = None - self.owner = None - self.cid = None - - try: self.__sock.shutdown(0) - except: pass - self.__sock.close() - self.__sock = None - - if self.__call.disconnected(reason): - # Reconnect - self.__do_connect.set() - else: - # Remove auto-login - self.__sh['auto_login'] = () - - - class __Pinger(): - def __init__(self, send): - """ - Will ping every 30 seconds for food. If the server - doesn't receive anything from us for 45 sec, it will - drop the connection, because it thinks our computer blew - up or something... - """ - self.running = True + + #Infinite loop that receives data + buffer = '' + while 1: + try: + data = self.__sock.recv(1024) + except: + disconnect_reason = "closed" + break + if not data: + disconnect_reason = "closed" + break + + buffer += data + + #Each dataset must end with a delimiter: chr(1) + if chr(1) not in buffer: continue + + data = buffer.split(chr(1)) + buffer = data[-1] + data = data[:-1] + + for msg in data: + self.__parse(simplejson.loads(msg)) + + if self.__sh['is_online']: + self.close(disconnect_reason) + + def login(self, usr, pwd): + """ + Log in to the server as a normal user. If the RSA-key wasn't received + yet, it will login after is has received the key. pwd is expected to be sha1. + + >>> import hashlib + >>> hashlib.sha1("MyVerySecretPassword").hexdigest() + 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' + """ + + if self.cid != None: + raise LoginError("You are already logged in") + + # Save this + self.__sh['auto_login'] = (self.login, (usr, pwd)) + + # Wait for the rsa-key to arrive + if not self.__sh['rsakey']: return + + if not self.__sock: + raise ConnectionError("You are not connected!") + + self.__sh['isbot'] = False + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + # Log in + self.send("login", { + "usr": usr, + "pwd": pwd, + "bot": False, + "for": "VP", + "client": ( + self.__sh['config']['app_name'], + self.__sh['config']['app_version'] + ), + "version": __version__ + }) + + def login_bot(self, owner, pwd, screenname): + """ + Log in as a bot. If the RSA-key wasn't received yet, it will login after + is has received the key. pwd is expected to be sha1. + + >>> import hashlib + >>> hashlib.sha1("MyVerySecretPassword").hexdigest() + 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' + """ + + if self.cid != None: + raise LoginError("You are already logged in") + + # Save this + self.__sh['auto_login'] = (self.login_bot, (owner, pwd, screenname)) + + # Wait for the rsa-key to arrive + if not self.__sh['rsakey']: return + + if not self.__sock: + raise ConnectionError("You are not connected!") + + self.__sh['isbot'] = True + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + # Log in + self.send("login", { + "usr": owner, + "pwd": pwd, + "name": screenname, + "bot": True, + "for": "VP", + "client": ( + self.__sh['config']['app_name'], + self.__sh['config']['app_version'] + ), + "version": __version__ + }) + + + def signup(self, usr, pwd, extra = {}): + """ + Create a new account with on the server. You should have a connection + first before using this. + """ + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + if self.cid != None: + raise SignupError("You are already logged in") + + + # Sign up + self.send("signup", { + "usr": usr, + "pwd": pwd, + "extra": extra, + "version": __version__ + }) + + + + def send(self, data_header, data_body = {}): + """ + Sends `data_body` of type `data_header` to the server. It will + automatically be encoded as JSON, and the delimeter character (chr(1)) + will be send automatically too. `Data_header` is a string, `data_body` + a dict. + """ + + self.__call.data_send({data_header:data_body}) + data = simplejson.dumps({data_header:data_body}) + try: + self.__sock.send(data + chr(1)) + except: pass + + + def close(self, reason = "manual"): + """ + Will close the connection to the server. If the connection is already + down, it will raise an exception. This will trigger the callback + `disconnected`. It may reconnect, depending on the callback. If not, you + can reuse this class by calling `connect`. + """ + + if not self.__sh['is_online']: + if reason == "manual": + # Annoy the user + raise ConnectionError("The connection is " + \ + "already closed!") + else: + return; + + + self.__do_connect.clear() # Block the thread-loop + + self.__sh['is_online'] = False + + if self.__pinger != None: + self.__pinger.cancel() + self.__pinger = None + + # Reset variables + self.__sh['rsakey'] = None + self.username = None + self.owner = None + self.cid = None + + try: self.__sock.shutdown(0) + except: pass + self.__sock.close() + self.__sock = None + + if self.__call.disconnected(reason): + # Reconnect + self.__do_connect.set() + else: + # Remove auto-login + self.__sh['auto_login'] = () + + + class __Pinger(): + def __init__(self, send): + """ + Will ping every 30 seconds for food. If the server doesn't receive + anything from us for 45 sec, it will drop the connection, because it + thinks our computer blew up or something... + """ + self.running = True - self.send = send - self.timer = threading.Timer(30, self.run) - self.timer.start() + self.send = send + self.timer = threading.Timer(30, self.run) + self.timer.start() - def run(self): - if self.running == False: return + def run(self): + if self.running == False: return - #Ping! - self.send('ping', {}) + #Ping! + self.send('ping', {}) - #Start again - self.timer = threading.Timer(30, self.run) - self.timer.start() + #Start again + self.timer = threading.Timer(30, self.run) + self.timer.start() - def cancel(self): - if self.running: - self.timer.cancel() - self.running = False + def cancel(self): + if self.running: + self.timer.cancel() + self.running = False class ConnectionError(Exception): - pass + pass class LoginError(Exception): - pass - + pass + class SignupError(Exception): - pass + pass Modified: trunk/client/core/parser.py =================================================================== --- trunk/client/core/parser.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/core/parser.py 2010-08-01 22:16:19 UTC (rev 351) @@ -16,146 +16,142 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Parser(): - def __init__(self, sh): - """ - This class parses all received messages from the server. - """ - self.sh = sh - self.call = sh['call'] - self.core = sh['core'] - - def __call__(self, msg): - self.call.data_received(msg) - - head = msg.keys()[0] - body = msg[head] - - func = getattr(self, str(head), None) - if (func): - func(body) - - def disconnect(self, msg): - """ - Called just before the server closes our connection. - * reason - Why the server disconnected us - "full" - Because the server is full - "duplicate" - Because another client has logged in - on the same account - "crash" - The server-parser has made a crash - "gone offline" - Server has just shutdown - """ - - self.core.close(msg["reason"]) - - def rsa(self, msg): - """ - Called when the connection has been made and a rsa-key has been - generated. We can now log in using this key - * public - The public rsa-key, which contains e & n - """ - - self.sh['rsakey'] = msg['public'] - - self.call.received_rsa(msg['public']) - - if self.core.cid == None and \ - self.sh['auto_login'] != (): - login = self.sh['auto_login'] - login[0](*login[1]) - - - def login(self, msg): - """ - Called when we can log in - * username - The username (with right caps) - * cid - The server's connection-id - * owner - The owner for this bot (only when logging in - as bot!) - """ - - if self.sh['isbot']: # Logging in as bot - self.core.owner = msg['owner'] - self.core.username = msg['username'] - self.core.cid = msg['cid'] - - self.call.logged_in(msg['username'], msg['cid'], - msg['owner']) - - else: # Logging in as user - self.core.username = msg['username'] - self.core.cid = msg['cid'] - - self.call.logged_in(msg['username'], msg['cid'], None) - - - def userlist(self, msg): - """ - Called after we've logged it. This contains a list with all - online users. This is a _list_ with: - * cid - The unique ID for this connection - * user - The username - * app - [Appname, Appversion] - * version - Which core it's using (string) - * bot - If it's a bot - * owner - The owner for this bot (only available when - bot = True) - * pos - [Z, X, Y] The position for this user. Is None - when you can't see this user. - """ - - # TODO - - pass - - def useronline(self, msg): - """ - Called after a user (or bot) has signed on. - * cid - The unique ID for this connection - * user - The username - * app - [Appname, Appversion] - * version - Which core it's using (string) - * bot - If it's a bot - * owner - The owner for this bot (only available when - bot = True) - * pos - [Z, X, Y] The position for this user. Is None - when you can't see this user. - """ - - # TODO - - pass - - def useroffline(self, msg): - """ - Some user has gone offline - * cid - The connection-id for this client - """ - - # TODO - - pass - - - def error(self, msg): - """ - Called when we did something wrong! - * reason - What we did wrong - "bad login" - Username/password wrong - "login not allowed" - User may not log in right now - "bot limit reached" - Too much bots logged in for this user - "login blocked" - The user (or IP) is blocked - "duplicate user" - There is already someone online with - this username - """ - - if msg['reason'] == "bad login": - self.call.failed_logging_in("bad login") - elif msg['reason'] == "login not allowed": - self.call.failed_logging_in("login not allowed") - elif msg['reason'] == "bot limit reached": - self.call.failed_logging_in("bot limit reached") - elif msg['reason'] == "login blocked": - self.call.failed_logging_in("login blocked") - elif msg['reason'] == "duplicate user": - self.call.failed_logging_in("duplicate user") - + def __init__(self, sh): + """ + This class parses all received messages from the server. + """ + self.sh = sh + self.call = sh['call'] + self.core = sh['core'] + + def __call__(self, msg): + self.call.data_received(msg) + + head = msg.keys()[0] + body = msg[head] + + func = getattr(self, str(head), None) + if (func): + func(body) + + def disconnect(self, msg): + """ + Called just before the server closes our connection. + * reason - Why the server disconnected us + "full - Because the server is full + "duplicate" - Because another client has logged in on the same + account + "crash" - The server-parser has made a crash + "gone offline"- Server has just shutdown + """ + + self.core.close(msg["reason"]) + + def rsa(self, msg): + """ + Called when the connection has been made and a rsa-key has been + generated. We can now log in using this key + * public - The public rsa-key, which contains e & n + """ + + self.sh['rsakey'] = msg['public'] + + self.call.received_rsa(msg['public']) + + if self.core.cid == None and self.sh['auto_login'] != (): + login = self.sh['auto_login'] + login[0](*login[1]) + + + def login(self, msg): + """ + Called when we can log in + * username - The username (with right caps) + * cid - The server's connection-id + * owner - The owner for this bot (only when logging in as bot!) + """ + + if self.sh['isbot']: # Logging in as bot + self.core.owner = msg['owner'] + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], msg['owner']) + + else: # Logging in as user + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], None) + + + def userlist(self, msg): + """ + Called after we've logged it. This contains a list with all + online users. This is a _list_ with: + * cid - The unique ID for this connection + * user - The username + * app - [Appname, Appversion] + * version - Which core it's using (string) + * bot - If it's a bot + * owner - The owner for this bot (only available when bot = True) + * pos - [Z, X, Y] The position for this user. Is None + when you can't see this user. + """ + + # TODO + + pass + + def useronline(self, msg): + """ + Called after a user (or bot) has signed on. + * cid - The unique ID for this connection + * user - The username + * app - [Appname, Appversion] + * version - Which core it's using (string) + * bot - If it's a bot + * owner - The owner for this bot (only available when + bot = True) + * pos - [Z, X, Y] The position for this user. Is None + when you can't see this user. + """ + + # TODO + + pass + + def useroffline(self, msg): + """ + Some user has gone offline + * cid - The connection-id for this client + """ + + # TODO + + pass + + + def error(self, msg): + """ + Called when we did something wrong! + * reason - What we did wrong + "bad login" - Username/password wrong + "login not allowed" - User may not log in right now + "bot limit reached" - Too much bots logged in for this user + "login blocked" - The user (or IP) is blocked + "duplicate user" - There is already someone online with this + username + """ + + if msg['reason'] == "bad login": + self.call.failed_logging_in("bad login") + elif msg['reason'] == "login not allowed": + self.call.failed_logging_in("login not allowed") + elif msg['reason'] == "bot limit reached": + self.call.failed_logging_in("bot limit reached") + elif msg['reason'] == "login blocked": + self.call.failed_logging_in("login blocked") + elif msg['reason'] == "duplicate user": + self.call.failed_logging_in("duplicate user") + Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/functions.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + import pygame, os, sys, threading from pygame.locals import * from hashlib import sha1 @@ -4,31 +21,33 @@ import core import gui + VERSION = "0.0.1" # This will be used to [sh]are all variables, functions and classes across the # code sh = {} + def real_path(*dir): - """ - Get the real path to this file - """ - return os.path.join(sys.path[0], *dir) + """ + Get the real path to this file + """ + return os.path.join(sys.path[0], *dir) def load_image(alpha, *dir): - """ - This will load an image for pygame - """ - - fullname = real_path(*dir) - try: - image = pygame.image.load(fullname) - if image.get_alpha is None or alpha == False: - image = image.convert() - else: - image = image.convert_alpha() - except pygame.error, message: - print 'Cannot load image:', fullname - raise SystemExit, message - return image + """ + This will load an image for pygame + """ + + fullname = real_path(*dir) + try: + image = pygame.image.load(fullname) + if image.get_alpha is None or alpha == False: + image = image.convert() + else: + image = image.convert_alpha() + except pygame.error, message: + print 'Cannot load image:', fullname + raise SystemExit, message + return image Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/gui.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * class Plane(): @@ -2,81 +19,78 @@ - def __init__(self, update, width, height): - self.update = update - self.width = width - self.height = height - self.surf = pygame.Surface((self.width, self.height), \ - SRCALPHA).convert_alpha() - self.norender = True - - self.childs = {} - - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - - def renderall(self): - self.norender = False - for child in self.childs.values(): - child.renderall(Rect(0,0,0,0), self.surf) - - self.update(Rect(0,0, self.width, self.height)) + def __init__(self, update, width, height): + self.update = update + self.width = width + self.height = height + self.surf = pygame.Surface((self.width, self.height), SRCALPHA) \ + .convert_alpha() + self.norender = True + + self.childs = {} + + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self): + self.norender = False + for child in self.childs.values(): + child.renderall(Rect(0,0,0,0), self.surf) + + self.update(Rect(0,0, self.width, self.height)) - class Object(): - def __init__(self, name, rect): - self.name = name - self.rect = Rect(rect) - self.childs = {} - self.focus = False - self.hover = False - - # Load the defaults - self.__defaults__() + def __init__(self, name, rect): + self.name = name + self.rect = Rect(rect) + self.childs = {} + self.focus = False + self.hover = False + + # Load the defaults + self.__defaults__() - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - def renderall(self, correction, surf): - # First render ourself - self.render(correction, surf) - - # Then render our childs - for child in self.childs.values(): - child.renderall(correction.move(self.rect.topleft), surf) - + def __getitem__(self, key): + return self.childs[key] + + def add(self, *objs): + for obj in objs: + self.childs[obj.name] = obj + + def renderall(self, correction, surf): + # First render ourself + self.render(correction, surf) + + # Then render our childs + for child in self.childs.values(): + child.renderall(correction.move(self.rect.topleft), surf) + - class Text(Object): - def __defaults__(self): - self.input = "" - self.cursorpos = 0 - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size - - surf.fill([255,0,0], pos) - - + def __defaults__(self): + self.input = "" + self.cursorpos = 0 + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([255,0,0], pos) + + class Button(Object): - def __defaults__(self): - self.caption = "" - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size - - surf.fill([0,0,255], pos) + def __defaults__(self): + self.caption = "" + + def render(self, correction, surf): + pos = correction.move(self.rect.topleft) + pos.size = self.rect.size + + surf.fill([0,0,255], pos) Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-01 21:27:14 UTC (rev 350) +++ trunk/client/layout.py 2010-08-01 22:16:19 UTC (rev 351) @@ -1,3 +1,20 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + from functions import * TOPBUTTONS = 3 @@ -4,105 +21,99 @@ TOPLEFT = 44 TOPBUTTONWIDTH = 304 TOPHEIGHT = 65 - + class Layout(): - - def __init__(self, sh): - self.sh = sh - - self.surf = pygame.Surface((1000, 700), \ - SRCALPHA).convert_alpha() - - self.status = None - - self.selected = None - self.hover = None - - # Login stuff - self.loginbg = None - self.loginfont = None - - # Playground stuff - self.topbar = None - - def event(self, ev): - if self.status == "playground": - if ev.type == MOUSEMOTION: - index = self.topbarcursor(ev.pos) - if index is not False: - if self.hover == index: return True - self.hover = index - self.updatetop() - - return True - else: - if self.hover == None: return - self.hover = None - self.updatetop() - - elif ev.type == ACTIVEEVENT: - if ev.state == 1: # Mouse events - if ev.gain == 0: # Lost mouse focus - if self.hover == None: return - self.hover = None - self.updatetop() - - elif ev.type == MOUSEBUTTONDOWN: - index = self.topbarcursor(ev.pos) - if index is False: return - - if self.selected == index: - self.selected = None - else: - self.selected = index - self.updatetop() - - return True - - - - - def changestatus(self, status): - login_list = ['connecting', 'login', 'logging in'] - if status in login_list and self.status not in login_list: - # (Un)load all the data - self.topbar = None - - elif status == "playground": - self.topbar = load_image(True, "images", "topbar.png") - - self.selected = None - self.hover = self.topbarcursor(pygame.mouse.get_pos()) - self.surf.blit(self.topbar, (0,0), (0,0,1000,TOPHEIGHT)) - self.updatetop() - - self.status = status - - - def updatetop(self): - for i in range(TOPBUTTONS): - left = TOPLEFT + (TOPBUTTONWIDTH*i) - rect = Rect(left, 0, TOPBUTTONWIDTH, TOPHEIGHT) - - self.surf.fill([0,0,0,0], rect) - - if self.selected is i: # This button is selected - rect2 = rect.move(0,TOPHEIGHT*2) - - elif self.hover is i: # This button is hovered - rect2 = rect.move(0,TOPHEIGHT) - - else: - rect2 = rect.move(0,0) - - self.surf.blit(self.topbar, rect, rect2) - - self.sh['update']((0,0, 1000, 65)) - - - def topbarcursor(self, pos): - if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ - and pos[1] < 55: - return (pos[0]-TOPLEFT) / TOPBUTTONWIDTH - else: - return False + + def __init__(self, sh): + self.sh = sh + + self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() + + self.status = None + + self.selected = None + self.hover = None + + # Login stuff + self.loginbg = None + self.loginfont = None + + # Playground stuff + self.topbar = None + + def event(self, ev): + if self.status == "playground": + if ev.type == MOUSEMOTION: + index = self.topbarcursor(ev.pos) + if index is not False: + if self.hover == index: return True + self.hover = index + self.updatetop() + + return True + else: + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse events + if ev.gain == 0: # Lost mouse focus + if self.hover == None: return + self.hover = None + self.updatetop() + + elif ev.type == MOUSEBUTTONDOWN: + index = self.topbarcursor(ev.pos) + if index is False: return + + if self.selected == index: + self.selected = None + else: + self.selected = index + self.updatetop() + + return True + + def changestatus(... [truncated message content] |
From: <Blu...@us...> - 2010-08-02 20:41:15
|
Revision: 352 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=352&view=rev Author: BlueWolf_ Date: 2010-08-02 20:41:09 +0000 (Mon, 02 Aug 2010) Log Message: ----------- Modified Paths: -------------- trunk/client/functions.py trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/functions.py 2010-08-02 20:41:09 UTC (rev 352) @@ -19,9 +19,7 @@ from pygame.locals import * from hashlib import sha1 import core -import gui - VERSION = "0.0.1" # This will be used to [sh]are all variables, functions and classes across the @@ -51,3 +49,9 @@ print 'Cannot load image:', fullname raise SystemExit, message return image + + +# GUI needs the functions again. That's why it has to be imported after all +# functions have been defined +import gui +gui = gui.Container Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/gui.py 2010-08-02 20:41:09 UTC (rev 352) @@ -17,74 +17,152 @@ from functions import * -class Plane(): - - def __init__(self, update, width, height): - self.update = update - self.width = width - self.height = height - self.surf = pygame.Surface((self.width, self.height), SRCALPHA) \ - .convert_alpha() - self.norender = True - - self.childs = {} - - def __getitem__(self, key): - return self.childs[key] - - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj - - def renderall(self): - self.norender = False - for child in self.childs.values(): - child.renderall(Rect(0,0,0,0), self.surf) - - self.update(Rect(0,0, self.width, self.height)) - - class Object(): - def __init__(self, name, rect): + def __init__(self, name, rect, update): self.name = name self.rect = Rect(rect) - self.childs = {} + self.parent_update = update + + self.children = [] + self.hover = False self.focus = False - self.hover = False # Load the defaults self.__defaults__() + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() def __getitem__(self, key): - return self.childs[key] + for child in self.children: + if child.name == key: + return child + + raise KeyError(key) - def add(self, *objs): - for obj in objs: - self.childs[obj.name] = obj + def add(self, objname, name, rect): + if objname == "textbox": + obj = Text + elif objname == "button": + obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update) + self.children.append(obj) + + return obj - def renderall(self, correction, surf): - # First render ourself - self.render(correction, surf) + def update(self, rect): + # Send a message to our parent, telling them this rect needs to be + # updated - # Then render our childs - for child in self.childs.values(): - child.renderall(correction.move(self.rect.topleft), surf) + # We need to calculate our relative position + return rect.move(self.rect.left, self.rect.top) + + +class Container(): # A modified version of Object + + def __init__(self, size, update): + self.rect = Rect(0,0,size[0], size[1]) + self.parent_update = update + + self.children = [] + self.hover = False + self.focus = False + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() + + def __getitem__(self, key): + for child in self.children: + if child.name == key: + return child + raise KeyError(key) + + def add(self, objname, name, rect): + if objname == "textbox": + Obj = Textbox + elif objname == "button": + Obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update) + self.children.append(obj) + + return obj + + + def update(self, rect): + # Clear this part of our surface + self.surf.fill(rect, [0,0,0,0]) + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.render(rect, surf, rect) + + self.parent_update(rect) + + + -class Text(Object): +class Textbox(Object): + def __defaults__(self): self.input = "" self.cursorpos = 0 + self.style = None + self.layout = None + self.type = "text" def render(self, correction, surf): + if self.layout == None: return + pos = correction.move(self.rect.topleft) pos.size = self.rect.size + print correction, pos surf.fill([255,0,0], pos) + def update(self): + pass + + def set_style(self, style): + """ + Possible styles: + * login + """ + if style == "text": + pass + elif style == "login": + self.layout = load_image(True, "images", "gui", "text_login.png") + else: + raise GuiError("Style '%s' has not been found" % style) + + self.style = style + def set_type(self, type): + """ + Possible types: + * text + * password + """ + if type not in ("text", "password"): + raise GuiError("Type '%s' has not been found" % type) + + self.type = type + + + class Button(Object): def __defaults__(self): @@ -96,3 +174,6 @@ surf.fill([0,0,255], pos) + +class GuiError(Exception): + pass Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-01 22:16:19 UTC (rev 351) +++ trunk/client/playground.py 2010-08-02 20:41:09 UTC (rev 352) @@ -91,14 +91,22 @@ elif status == "login": self.surf.blit(self.loginbox, (292,256)) + # Create login-field - #self.logingui = gui.Plane(self.drawlogingui, 417,189) + self.logingui = gui((417,189), self.drawlogingui) + + username = self.logingui.add("textbox", "usr", (0,0, 417, 50)) #username = gui.Text("username", (0,0, 417, 50)) + #username.set_style("login") + #password = gui.Text("password", (0,50, 417, 50)) + #password.set_style("login") + #password.set_type("password") + #login = gui.Button("login", (0, 100, 417, 50)) - #self.logingui.add(username, password, login) # [TODO] Give mouseposition + #self.logingui.renderall() @@ -110,6 +118,7 @@ self.sh['update']() def drawlogingui(self, rect): + print rect rect_main = rect.move(292,256) self.surf.blit(self.loginbg, rect_main, rect_main) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-03 22:21:11
|
Revision: 354 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=354&view=rev Author: BlueWolf_ Date: 2010-08-03 22:21:05 +0000 (Tue, 03 Aug 2010) Log Message: ----------- The GUI so far. Looks pretty solid. Will be adding events soon Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Added Paths: ----------- trunk/client/images/gui/ trunk/client/images/gui/text_login.png Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-03 19:13:58 UTC (rev 353) +++ trunk/client/gui.py 2010-08-03 22:21:05 UTC (rev 354) @@ -16,24 +16,29 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. from functions import * +import random class Object(): - def __init__(self, name, rect, update): + def __init__(self, name, rect, update, update_mouse): self.name = name self.rect = Rect(rect) self.parent_update = update + self.update_mouse = update_mouse + self.needs_update = False + self.frozen = True # Don't update until everything has been + # loaded self.children = [] self.hover = False self.focus = False - # Load the defaults - self.__defaults__() - # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() + + # Load the defaults + self.__defaults__() def __getitem__(self, key): for child in self.children: @@ -43,6 +48,10 @@ raise KeyError(key) def add(self, objname, name, rect): + """ + Append a child to this object + """ + if objname == "textbox": obj = Text elif objname == "button": @@ -50,28 +59,80 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update) + obj = Obj(name, rect, self.update, self.update_mouse) self.children.append(obj) return obj - def update(self, rect): + def update(self, rect = None): + """ + Update this part of the object + """ + # Send a message to our parent, telling them this rect needs to be # updated - # We need to calculate our relative position - return rect.move(self.rect.left, self.rect.top) + self.needs_update = True + + if self.frozen: return + + if rect == None: + rect = self.rect + + else: + # We need to calculate our relative position + rect.move_ip(self.rect.left, self.rect.top) + self.parent_update(rect) + + def blit(self, rect, surf, onto): + """ + Render our object and our childs to this surface + """ + + # Render ourself and our childs to surf + if self.needs_update: + self.render() + self.needs_update = False + + surf.blit(self.surf, onto, rect) + + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.blit(new_rect, surf, onto) + + def unfreeze(self, isparent = True): + """ + Unfreeze this and all the childs and update all of them + """ + + for child in self.children: + child.unfreeze(False) + + if isparent: + self.update_mouse() + self.frozen = False + self.update(self.rect) + else: + self.frozen = False + + + class Container(): # A modified version of Object - def __init__(self, size, update): - self.rect = Rect(0,0,size[0], size[1]) + def __init__(self, update): + self.rect = Rect(0, 0, 1000, 700) self.parent_update = update + self.frozen = True # Don't update until everything has been + # loaded self.children = [] - self.hover = False - self.focus = False + self.hover = None + self.focus = None # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ @@ -85,6 +146,10 @@ raise KeyError(key) def add(self, objname, name, rect): + """ + Append a child to this object + """ + if objname == "textbox": Obj = Textbox elif objname == "button": @@ -92,63 +157,97 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update) + obj = Obj(name, rect, self.update, self.update_mouse) self.children.append(obj) return obj - def update(self, rect): + def update(self, rect = None): + """ + Update this part of the object + """ + + if self.frozen: return + + if rect == None: + rect = self.rect + # Clear this part of our surface - self.surf.fill(rect, [0,0,0,0]) + self.surf.fill([0,0,0,0], rect) # Find all the children within this rect for child in self.children: if not rect.colliderect(child.rect): continue new_rect = rect.move(-child.rect.left, -child.rect.top) - child.render(rect, surf, rect) + child.blit(new_rect, self.surf, rect) self.parent_update(rect) - - + + def unfreeze(self): + """ + Unfreeze this and all the childs and update all of them + """ - - + for child in self.children: + child.unfreeze(False) + + self.update_mouse() + self.frozen = False + self.update() + + def update_mouse(self): + """ + Get the current mouse position and check if the focus has changed + """ + + print "mousecheck" + + class Textbox(Object): def __defaults__(self): self.input = "" self.cursorpos = 0 self.style = None - self.layout = None self.type = "text" - - def render(self, correction, surf): - if self.layout == None: return - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size + self.backgroundsurf = pygame.Surface((self.rect.width, \ + self.rect.height*2), SRCALPHA).convert_alpha() - print correction, pos - surf.fill([255,0,0], pos) - - def update(self): - pass - def set_style(self, style): """ Possible styles: * login """ - if style == "text": - pass - elif style == "login": - self.layout = load_image(True, "images", "gui", "text_login.png") + if style == "login": + if self.rect.height != 37: + raise GuiError("Height should be 37") + if self.rect.width < 25: + raise GuiError("Width should be 25 or bigger ") + + layoutimg = load_image(True, "images", "gui", "text_login.png") + + # Create backgroundsurf + self.backgroundsurf.fill([0,0,0,0]) + + # Left + self.backgroundsurf.blit(layoutimg, (0, 0), (0, 0, 12, 74)) + # Right + self.backgroundsurf.blit(layoutimg, (self.rect.width-12, 0), \ + (15, 0, 12, 74)) + # Middle + middle = pygame.Surface((1, 74), SRCALPHA).convert_alpha() + middle.blit(layoutimg, (0, 0,), (13, 0, 1, 74)) + middle = pygame.transform.scale(middle, (self.rect.width-24, 74)) + self.backgroundsurf.blit(middle, (12, 0)) + else: raise GuiError("Style '%s' has not been found" % style) self.style = style + self.update() def set_type(self, type): """ @@ -160,20 +259,23 @@ raise GuiError("Type '%s' has not been found" % type) self.type = type + self.update() + + def render(self): + if self.backgroundsurf == None: return - - -class Button(Object): - - def __defaults__(self): - self.caption = "" - - def render(self, correction, surf): - pos = correction.move(self.rect.topleft) - pos.size = self.rect.size + self.surf.fill([0,0,0,0]) - surf.fill([0,0,255], pos) + if self.style == "login": + # Which state do we need? + if self.focus: + top = 37 + else: + top = 0 + + self.surf.blit(self.backgroundsurf, (0,0), \ + (0,top, self.rect.width, 37)) + - class GuiError(Exception): pass Added: trunk/client/images/gui/text_login.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/gui/text_login.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-03 19:13:58 UTC (rev 353) +++ trunk/client/playground.py 2010-08-03 22:21:05 UTC (rev 354) @@ -37,6 +37,8 @@ def event(self, ev): if self.status == "login": + + # Some temporary debug stuff if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") @@ -49,6 +51,11 @@ "realname": "Pietje Precies", "gender": "M" }) + + #if self.logingui != None: + # self.logingui.event(ev) + + def changestatus(self, status): login_list = ['connecting', 'login', 'logging in'] @@ -93,22 +100,19 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui((417,189), self.drawlogingui) - - username = self.logingui.add("textbox", "usr", (0,0, 417, 50)) - #username = gui.Text("username", (0,0, 417, 50)) - #username.set_style("login") + self.logingui = gui(self.drawlogingui) - #password = gui.Text("password", (0,50, 417, 50)) - #password.set_style("login") - #password.set_type("password") + username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) + username.set_style("login") + password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) + password.set_style("login") + password.set_type("password") + #login = gui.Button("login", (0, 100, 417, 50)) - # [TODO] Give mouseposition + self.logingui.unfreeze() - #self.logingui.renderall() - elif status == "logging in": text = self.loginfont.render("Logging in...", True, (132,125,114)) @@ -118,11 +122,10 @@ self.sh['update']() def drawlogingui(self, rect): - print rect - rect_main = rect.move(292,256) + print "GUIupdate", rect - self.surf.blit(self.loginbg, rect_main, rect_main) - self.surf.blit(self.loginbox, rect_main, rect) - self.surf.blit(self.logingui.surf, rect_main, rect) + self.surf.blit(self.loginbg, rect, rect) + self.surf.blit(self.loginbox, (292, 256)) + self.surf.blit(self.logingui.surf, rect, rect) - self.sh['update'](rect_main) + self.sh['update'](rect) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 15:52:52
|
Revision: 355 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=355&view=rev Author: BlueWolf_ Date: 2010-08-07 15:52:43 +0000 (Sat, 07 Aug 2010) Log Message: ----------- GUI is slowly starting to work! I also changed all the self.sh's to plain sh Modified Paths: -------------- trunk/client/VP.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/VP.py 2010-08-07 15:52:43 UTC (rev 355) @@ -28,67 +28,85 @@ class Main(): def __init__(self): - self.sh = {} + sh['has_focus'] = True + sh['has_hover'] = True # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' pygame.init() pygame.display.set_caption('Virtual Playground') - self.sh['screen'] = pygame.display.set_mode((1000, 700)) + sh['screen'] = pygame.display.set_mode((1000, 700)) #icon = load_image('img','icon.png') #pygame.display.set_icon(icon) pygame.key.set_repeat(250, 40) pygame.scrap.init() self.clock = pygame.time.Clock() - self.sh['main'] = self + sh['main'] = self # Give the surfaces a way to blit itself - self.sh['update'] = self.update + sh['update'] = self.update self.updaterect = [] self.updatewaiting = False # Create all our surfaces - self.sh['playground'] = Playground(self.sh) - self.sh['layout'] = Layout(self.sh) - self.sh['windows'] = Windows(self.sh) + sh['playground'] = Playground() + sh['layout'] = Layout() + sh['windows'] = Windows() self.update() # Connect to the server - self.sh['client'] = core.Client({ + sh['client'] = core.Client({ 'app_name': "Virtual Playground", 'app_version': VERSION}, - Callback(self.sh)) + Callback()) self.changestatus("connecting") - self.sh['client'].connect('localhost', 6653) + sh['client'].connect('localhost', 6653) # Wait for all the events to come try: while 1: ev = pygame.event.wait() - + if ev.type == QUIT: break if ev.type == MOUSEMOTION: + # Prevent this event from overflowing the queue. Always + # return the position right now and remove al other + # mousemotions in the queue + pos = pygame.mouse.get_pos() pygame.event.clear(MOUSEMOTION) + ev = pygame.event.Event(MOUSEMOTION, + buttons = ev.buttons, + pos = pos) + + # As (sometimes) the mouse focus doesn't get through when + # switching workspaces (Linux), this should "fix" it + sh['has_hover'] = True + elif ev.type == ACTIVEEVENT: + if ev.state == 1: # Mouse focus + sh['has_hover'] = (ev.gain == 1) + elif ev.state == 2: # Window focus + sh['has_focus'] = (ev.gain == 1) + # Send through all the layers - if self.sh['windows'].event(ev): continue - if self.sh['layout'].event(ev): continue - if self.sh['playground'].event(ev): continue + if sh['windows'].event(ev): continue + if sh['layout'].event(ev): continue + if sh['playground'].event(ev): continue except KeyboardInterrupt: # Note: this does not work properly print # Someone decided to close VP (Why??) - try: self.sh['client'].close() + try: sh['client'].close() except: pass sys.exit() @@ -125,21 +143,19 @@ # The actual updating happens here - self.sh['screen'].blit(self.sh['playground'].surf, rect, rect) - self.sh['screen'].blit(self.sh['layout'].surf, rect, rect) - self.sh['screen'].blit(self.sh['windows'].surf, rect, rect) + sh['screen'].blit(sh['playground'].surf, rect, rect) + sh['screen'].blit(sh['layout'].surf, rect, rect) + sh['screen'].blit(sh['windows'].surf, rect, rect) pygame.display.update(rect) def changestatus(self, status): - self.sh['playground'].changestatus(status) - self.sh['layout'].changestatus(status) - self.sh['windows'].changestatus(status) + sh['playground'].changestatus(status) + sh['layout'].changestatus(status) + sh['windows'].changestatus(status) class Callback(core.Callback): - def __init__(self, sh): - self.sh = sh def data_received(self, data): print " --> " + repr(data) @@ -152,10 +168,10 @@ def received_rsa(self, public): # We are connected - self.sh['main'].changestatus("login") + sh['main'].changestatus("login") def logged_in(self, username, cid, owner): - self.sh['main'].changestatus("playground") + sh['main'].changestatus("playground") if __name__ == "__main__": Main() Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/gui.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,6 +18,143 @@ from functions import * import random + +class Container(): # A modified version of Object + + def __init__(self, update): + self.rect = Rect(0, 0, 1000, 700) + self.parent_update = update + self.frozen = True # Don't update until everything has been + # loaded + + self.children = [] + self.hover = None + self.focus = None + + # Create a surface where an object blits itself onto + self.surf = pygame.Surface((self.rect.width, self.rect.height), \ + SRCALPHA).convert_alpha() + + def __getitem__(self, key): + for child in self.children: + if child.name == key: + return child + + raise KeyError(key) + + def add(self, objname, name, rect): + """ + Append a child to this object + """ + + if objname == "textbox": + Obj = Textbox + elif objname == "button": + Obj = Button + else: + raise GuiError("Object '%s' has not been found" % objname) + + obj = Obj(name, rect, self.update, self.update_mouse) + self.children.append(obj) + + return obj + + + def update(self, rect = None): + """ + Update this part of the object + """ + + if self.frozen: return + + if rect == None: + rect = self.rect + + # Clear this part of our surface + self.surf.fill([0,0,0,0], rect) + + # Find all the children within this rect + for child in self.children: + if not rect.colliderect(child.rect): continue + + new_rect = rect.move(-child.rect.left, -child.rect.top) + child.blit(new_rect, self.surf, rect) + + self.parent_update(rect) + + def unfreeze(self): + """ + Unfreeze this and all the children and update all of them + """ + + for child in self.children: + child.unfreeze(False) + + self.update_mouse() + self.frozen = False + self.update() + + def update_mouse(self, pos = None): + """ + Get the current mouse position and check if the focus has changed + """ + + if pos == None: pos = pygame.mouse.get_pos() + + if sh['has_hover']: + # Get the current hovered object + hover = self.this_pos(pos) + + # Is it different from the previous check? + if hover != self.hover: + # De-hover the previous one + if self.hover: + self.hover.hover = False + self.hover.update() + + self.hover = hover + + # Hover the current one + if self.hover: + self.hover.hover = True + self.hover.update() + + else: + # Remove the previous hover + if self.hover: + self.hover.hover = False + self.hover.update() + self.hover = None + + + + def event(self, ev): + """ + All the events from pygame should go here + """ + + if self.frozen: return + + if ev.type == MOUSEMOTION: # Mouse movement + self.update_mouse(ev.pos) + + elif ev.type == ACTIVEEVENT and ev.state == 1: # Mouse focus + self.update_mouse() + + def this_pos(self, pos): + # Return the object on this position + + for child in self.children: + if not child.rect.collidepoint(pos): continue + + child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) + + hover = child.this_pos(child_pos) + if hover: return hover + + return None + + class Object(): def __init__(self, name, rect, update, update_mouse): @@ -53,9 +190,9 @@ """ if objname == "textbox": - obj = Text + Obj = Textbox elif objname == "button": - obj = Button + Obj = Button else: raise GuiError("Object '%s' has not been found" % objname) @@ -77,7 +214,7 @@ if self.frozen: return if rect == None: - rect = self.rect + rect = self.rect.move(0, 0) else: # We need to calculate our relative position @@ -87,10 +224,10 @@ def blit(self, rect, surf, onto): """ - Render our object and our childs to this surface + Render our object and our children to this surface """ - # Render ourself and our childs to surf + # Render ourself and our children to surf if self.needs_update: self.render() self.needs_update = False @@ -107,7 +244,7 @@ def unfreeze(self, isparent = True): """ - Unfreeze this and all the childs and update all of them + Unfreeze this and all the children and update all of them """ for child in self.children: @@ -119,92 +256,21 @@ self.update(self.rect) else: self.frozen = False - -class Container(): # A modified version of Object - - def __init__(self, update): - self.rect = Rect(0, 0, 1000, 700) - self.parent_update = update - self.frozen = True # Don't update until everything has been - # loaded - - self.children = [] - self.hover = None - self.focus = None - - # Create a surface where an object blits itself onto - self.surf = pygame.Surface((self.rect.width, self.rect.height), \ - SRCALPHA).convert_alpha() - - def __getitem__(self, key): - for child in self.children: - if child.name == key: - return child + def this_pos(self, pos): + # Return the object on this position - raise KeyError(key) - - def add(self, objname, name, rect): - """ - Append a child to this object - """ - - if objname == "textbox": - Obj = Textbox - elif objname == "button": - Obj = Button - else: - raise GuiError("Object '%s' has not been found" % objname) - - obj = Obj(name, rect, self.update, self.update_mouse) - self.children.append(obj) - - return obj - - - def update(self, rect = None): - """ - Update this part of the object - """ - - if self.frozen: return - - if rect == None: - rect = self.rect - - # Clear this part of our surface - self.surf.fill([0,0,0,0], rect) - - # Find all the children within this rect for child in self.children: - if not rect.colliderect(child.rect): continue + if not child.rect.collidepoint(pos): continue - new_rect = rect.move(-child.rect.left, -child.rect.top) - child.blit(new_rect, self.surf, rect) + child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) + + return child.this_pos(child_pos) - self.parent_update(rect) - - def unfreeze(self): - """ - Unfreeze this and all the childs and update all of them - """ - - for child in self.children: - child.unfreeze(False) - - self.update_mouse() - self.frozen = False - self.update() - - def update_mouse(self): - """ - Get the current mouse position and check if the focus has changed - """ - - print "mousecheck" - - + return self + + class Textbox(Object): def __defaults__(self): @@ -268,13 +334,13 @@ if self.style == "login": # Which state do we need? - if self.focus: + if self.hover: top = 37 else: top = 0 self.surf.blit(self.backgroundsurf, (0,0), \ - (0,top, self.rect.width, 37)) + (0, top, self.rect.width, 37)) class GuiError(Exception): Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/layout.py 2010-08-07 15:52:43 UTC (rev 355) @@ -24,9 +24,7 @@ class Layout(): - def __init__(self, sh): - self.sh = sh - + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() self.status = None @@ -109,7 +107,7 @@ self.surf.blit(self.topbar, rect, rect2) - self.sh['update']((0,0, 1000, 65)) + sh['update']((0,0, 1000, 65)) def topbarcursor(self, pos): if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/playground.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,9 +18,8 @@ from functions import * class Playground(): - def __init__(self, sh): - self.sh = sh - + + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() self.surf.fill([0,0,0]) @@ -42,18 +41,18 @@ if ev.type == KEYDOWN and ev.unicode == "\r": # Fake login self.drawlogin("logging in") - self.sh['client'].login("test123", sha1("test123").hexdigest()) + sh['client'].login("test123", sha1("test123").hexdigest()) elif ev.type == KEYDOWN and ev.unicode == "r": # Fake signup - self.sh['client'].signup("test123", sha1("test123").hexdigest(), + sh['client'].signup("test123", sha1("test123").hexdigest(), { "realname": "Pietje Precies", "gender": "M" }) - #if self.logingui != None: - # self.logingui.event(ev) + if self.logingui != None: + self.logingui.event(ev) @@ -74,7 +73,7 @@ self.logingui = None self.surf.fill([0,0,0]) - self.sh['update']() + sh['update']() if status == "connecting": @@ -119,7 +118,7 @@ posleft = (1000/2)-(text.get_size()[0]/2) self.surf.blit(text, (posleft, 330)) - self.sh['update']() + sh['update']() def drawlogingui(self, rect): print "GUIupdate", rect @@ -128,4 +127,4 @@ self.surf.blit(self.loginbox, (292, 256)) self.surf.blit(self.logingui.surf, rect, rect) - self.sh['update'](rect) + sh['update'](rect) Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-08-03 22:21:05 UTC (rev 354) +++ trunk/client/windows.py 2010-08-07 15:52:43 UTC (rev 355) @@ -18,9 +18,7 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Windows(): - def __init__(self, sh): - self.sh = sh - + def __init__(self): self.surf = pygame.Surface((1000, 700), SRCALPHA).convert_alpha() def event(self, ev): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-07 21:37:42
|
Revision: 361 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=361&view=rev Author: BlueWolf_ Date: 2010-08-07 21:37:36 +0000 (Sat, 07 Aug 2010) Log Message: ----------- Added more interaction with the GUI. You can now type something into the textboxes. I also moved the fake-registration button to F1, in case one still needs it Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-07 20:18:26 UTC (rev 360) +++ trunk/client/gui.py 2010-08-07 21:37:36 UTC (rev 361) @@ -30,6 +30,7 @@ self.children = [] self.hover = None self.focus = None + self.mousedown = None # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ @@ -103,31 +104,32 @@ if sh['has_hover']: # Get the current hovered object - hover = self.this_pos(pos) + rect, hover = self.this_pos(pos) # Is it different from the previous check? if hover != self.hover: # De-hover the previous one if self.hover: self.hover.hover = False - self.hover.update() + self.hover.hovering(False) self.hover = hover # Hover the current one if self.hover: self.hover.hover = True - self.hover.update() + self.hover.hovering(True) + + if hover: return True # Disable events further down the interface + else: # Remove the previous hover if self.hover: self.hover.hover = False - self.hover.update() + self.hover.hovering(False) self.hover = None - - def event(self, ev): """ All the events from pygame should go here @@ -136,23 +138,79 @@ if self.frozen: return if ev.type == MOUSEMOTION: # Mouse movement - self.update_mouse(ev.pos) + + # When the mousebutton is pressed on a object + if self.mousedown: + # Tell this object and stop processing this event further down + # the interface + pos = (ev.pos[0] - self.mousedown[0][0], \ + ev.pos[1] - self.mousedown[0][1]) + self.mousedown[1].click(1, pos) + return True + else: + # Check which object we hover + return self.update_mouse(ev.pos) elif ev.type == ACTIVEEVENT and ev.state == 1: # Mouse focus self.update_mouse() + + elif ev.type == MOUSEBUTTONDOWN: # Clicking + # Check which object we've focused + rect, hover = self.this_pos(ev.pos) + if hover: + # Change the focus + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = hover + + # Tell this object + self.mousedown = (rect, hover) + + hover.focus = True + pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) + hover.click(0, pos) + + self.update_mouse() + + return True + else: + # Did an object lost focus? + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + elif ev.type == MOUSEBUTTONUP and self.mousedown: # Clicking + # Release mousebutton after we've clicked on an object + pos = (ev.pos[0] - self.mousedown[0][0], \ + ev.pos[1] - self.mousedown[0][1]) + self.mousedown[1].click(2, pos) + self.mousedown = None + + self.update_mouse() + + return True + + elif (ev.type == KEYDOWN or ev.type == KEYUP) and self.focus: + self.focus.keypress(ev) + def this_pos(self, pos): - # Return the object on this position + # Return the object and their actual rect on this position for child in self.children: if not child.rect.collidepoint(pos): continue child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) - hover = child.this_pos(child_pos) - if hover: return hover + rect, hover = child.this_pos(child_pos) + if hover: + return rect, hover - return None + return None, None class Object(): @@ -266,9 +324,11 @@ child_pos = (pos[0] - child.rect[0], pos[1] - child.rect[1]) - return child.this_pos(child_pos) + rect, hover = child.this_pos(child_pos) + rect.move_ip(child.rect[0], child.rect[1]) + return rect, hover - return self + return self.rect.move(0,0), self class Textbox(Object): @@ -279,6 +339,7 @@ self.style = None self.type = "text" + self.font = None self.backgroundsurf = pygame.Surface((self.rect.width, \ self.rect.height*2), SRCALPHA).convert_alpha() @@ -295,6 +356,9 @@ layoutimg = load_image(True, "images", "gui", "text_login.png") + self.font = pygame.font.Font(real_path("fonts", \ + "DejaVuSans-Bold.ttf"), 14) + # Create backgroundsurf self.backgroundsurf.fill([0,0,0,0]) @@ -334,13 +398,68 @@ if self.style == "login": # Which state do we need? - if self.hover: + if self.focus: top = 37 else: top = 0 self.surf.blit(self.backgroundsurf, (0,0), \ (0, top, self.rect.width, 37)) + + # Blit the text + inp = self.input + if self.type == "password": + inp = "*"*len(self.input) + + color = [(141, 56, 0), (189, 84, 15)][self.focus] + text = self.font.render(inp, True, color) + self.surf.blit(text, (10, 10)) + + def hovering(self, value): + print "hover", self.name, value + + def click(self, state, pos): + print "click", self.name, state, pos + + if state == 0: # We got the focus! + # [TODO] Calculate position based on pos + + self.update() + + def lost_focus(self): + print "lost_focus", self.name + + self.cursorpos = len(self.input) + self.update() + + def keypress(self, ev): + if ev.type == KEYDOWN: + if ev.key == K_LEFT: # Cursorpos change + if self.cursorpos > 0: self.cursorpos -= 1 + + elif ev.key == K_RIGHT: # Cursorpos change + if self.cursorpos < len(self.input): self.cursorpos += 1 + + elif ev.key == K_BACKSPACE: # Backspace + if ev.mod & KMOD_CTRL: + self.input = "" + self.cursorpos = 0 + else: + self.input = self.input[:self.cursorpos-1] + \ + self.input[self.cursorpos:] + if self.cursorpos > 0: self.cursorpos -= 1 + + elif ev.key == K_DELETE: # Delete + self.input = self.input[:self.cursorpos] + \ + self.input[self.cursorpos+1:] + + elif ev.unicode != "": # Normal text + + self.input = self.input[:self.cursorpos] + ev.unicode + \ + self.input[self.cursorpos:] + self.cursorpos += 1 + + self.update() class GuiError(Exception): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-07 20:18:26 UTC (rev 360) +++ trunk/client/playground.py 2010-08-07 21:37:36 UTC (rev 361) @@ -43,7 +43,7 @@ self.drawlogin("logging in") sh['client'].login("test123", sha1("test123").hexdigest()) - elif ev.type == KEYDOWN and ev.unicode == "r": + elif ev.type == KEYDOWN and ev.key == K_F1: # Fake signup sh['client'].signup("test123", sha1("test123").hexdigest(), { @@ -52,7 +52,7 @@ }) if self.logingui != None: - self.logingui.event(ev) + return self.logingui.event(ev) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-08 15:24:59
|
Revision: 362 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=362&view=rev Author: BlueWolf_ Date: 2010-08-08 15:24:53 +0000 (Sun, 08 Aug 2010) Log Message: ----------- Textbox now with working cursor! Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-07 21:37:36 UTC (rev 361) +++ trunk/client/gui.py 2010-08-08 15:24:53 UTC (rev 362) @@ -55,7 +55,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update, self.update_mouse) + obj = Obj(name, rect, self, self) self.children.append(obj) return obj @@ -130,6 +130,25 @@ self.hover.hovering(False) self.hover = None + def give_focus(self, *obj): + if type(obj[0]) == str: + child = self + for part in obj: + child = child[part] + else: + child = obj[0] + + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = child + + # Tell this object + child.focus = True + child.got_focus(0) + def event(self, ev): """ All the events from pygame should go here @@ -145,7 +164,7 @@ # the interface pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].click(1, pos) + self.mousedown[1].got_focus(1, pos) return True else: # Check which object we hover @@ -171,7 +190,7 @@ hover.focus = True pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) - hover.click(0, pos) + hover.got_focus(0, pos) self.update_mouse() @@ -188,7 +207,7 @@ # Release mousebutton after we've clicked on an object pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].click(2, pos) + self.mousedown[1].got_focus(2, pos) self.mousedown = None self.update_mouse() @@ -211,15 +230,21 @@ return rect, hover return None, None + + def focus_next(self, current): + pos = self.children.index(current) + 1 + if pos == len(self.children): pos = 0 + + self.give_focus(self.children[pos]) class Object(): - def __init__(self, name, rect, update, update_mouse): + def __init__(self, name, rect, main_parent, parent): self.name = name self.rect = Rect(rect) - self.parent_update = update - self.update_mouse = update_mouse + self.main_parent = main_parent + self.parent = parent self.needs_update = False self.frozen = True # Don't update until everything has been # loaded @@ -228,6 +253,9 @@ self.hover = False self.focus = False + # Callbacks + self.cb_keypress = None + # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -254,7 +282,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.update, self.update_mouse) + obj = Obj(name, rect, self.main_parent, self) self.children.append(obj) return obj @@ -278,7 +306,7 @@ # We need to calculate our relative position rect.move_ip(self.rect.left, self.rect.top) - self.parent_update(rect) + self.parent.update(rect) def blit(self, rect, surf, onto): """ @@ -309,13 +337,12 @@ child.unfreeze(False) if isparent: - self.update_mouse() + self.main_parent.update_mouse() self.frozen = False self.update(self.rect) else: self.frozen = False - - + def this_pos(self, pos): # Return the object on this position @@ -329,6 +356,12 @@ return rect, hover return self.rect.move(0,0), self + + def focus_next(self, current): + pos = self.children.index(current) + 1 + if pos == len(self.children): pos = 0 + + self.give_focus(self.children[pos]) class Textbox(Object): @@ -406,6 +439,8 @@ self.surf.blit(self.backgroundsurf, (0,0), \ (0, top, self.rect.width, 37)) + truewidth = self.rect.width - 12 # Width without the borders + # Blit the text inp = self.input if self.type == "password": @@ -413,13 +448,29 @@ color = [(141, 56, 0), (189, 84, 15)][self.focus] text = self.font.render(inp, True, color) - self.surf.blit(text, (10, 10)) + textwidth = text.get_width() + + cursorpos = self.font.size(inp[:self.cursorpos])[0] + if textwidth < truewidth: # Text is smaller than the input + pos = (truewidth/2) - (textwidth/2) + elif cursorpos < (truewidth/2): # Cursor is on the left + pos = 0 + elif textwidth-cursorpos < (truewidth/2): # Cursor is on the right + pos = -textwidth + truewidth - 2 + else: # Cursor is in the center + pos = -cursorpos + (truewidth/2) + + self.surf.blit(text, (6, 10), (-pos, 0, truewidth, 17)) + + # Blit cursor + if self.focus: + pygame.draw.line(self.surf, [118, 58, 19], (pos+cursorpos+6, 10), (pos+cursorpos+6, 26), 2) def hovering(self, value): print "hover", self.name, value - def click(self, state, pos): - print "click", self.name, state, pos + def got_focus(self, state, pos = None): + print "got_focus", self.name, state, pos if state == 0: # We got the focus! # [TODO] Calculate position based on pos @@ -452,14 +503,26 @@ elif ev.key == K_DELETE: # Delete self.input = self.input[:self.cursorpos] + \ self.input[self.cursorpos+1:] - + + elif ev.key == K_HOME: # Go to the beginning + self.cursorpos = 0 + + elif ev.key == K_END: # Go to the end + self.cursorpos = len(self.input) + + elif ev.key == K_TAB: # Focus the next object + self.parent.focus_next(self) + + elif ev.unicode == "\r": # Ignore this + pass elif ev.unicode != "": # Normal text - self.input = self.input[:self.cursorpos] + ev.unicode + \ self.input[self.cursorpos:] self.cursorpos += 1 self.update() + + if self.cb_keypress: self.cb_keypress(self, ev) class GuiError(Exception): Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-07 21:37:36 UTC (rev 361) +++ trunk/client/playground.py 2010-08-08 15:24:53 UTC (rev 362) @@ -38,7 +38,7 @@ if self.status == "login": # Some temporary debug stuff - if ev.type == KEYDOWN and ev.unicode == "\r": + if ev.type == KEYDOWN and ev.key == K_F2: # Fake login self.drawlogin("logging in") sh['client'].login("test123", sha1("test123").hexdigest()) @@ -103,13 +103,15 @@ username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) username.set_style("login") + username.cb_keypress = self.guikeypress password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) password.set_style("login") password.set_type("password") + password.cb_keypress = self.guikeypress #login = gui.Button("login", (0, 100, 417, 50)) - + self.logingui.give_focus(username) self.logingui.unfreeze() @@ -128,3 +130,9 @@ self.surf.blit(self.logingui.surf, rect, rect) sh['update'](rect) + + def guikeypress(self, obj, ev): + if ev.type == KEYDOWN: + if ev.unicode == "\r": + if obj.name == "usr": + self.logingui.give_focus("pwd") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-09 17:28:31
|
Revision: 364 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=364&view=rev Author: BlueWolf_ Date: 2010-08-09 17:28:24 +0000 (Mon, 09 Aug 2010) Log Message: ----------- Fixed the GUI textbox regarding getting focus and getting clicks. The GUI was a bit confused with both of them Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-08 17:38:24 UTC (rev 363) +++ trunk/client/gui.py 2010-08-09 17:28:24 UTC (rev 364) @@ -32,6 +32,9 @@ self.focus = None self.mousedown = None + # Settings + self.can_lose_focus = True + # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -147,13 +150,12 @@ # Tell this object child.focus = True - child.got_focus(0) + child.got_focus() def event(self, ev): """ All the events from pygame should go here """ - if self.frozen: return if ev.type == MOUSEMOTION: # Mouse movement @@ -164,7 +166,7 @@ # the interface pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].got_focus(1, pos) + self.mousedown[1].click(1, pos) return True else: # Check which object we hover @@ -177,28 +179,29 @@ # Check which object we've focused rect, hover = self.this_pos(ev.pos) if hover: - # Change the focus - if self.focus: - self.focus.focus = False - self.focus.lost_focus() - self.focus = None + pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) + hover.click(0, pos) - self.focus = hover - - # Tell this object self.mousedown = (rect, hover) - hover.focus = True - pos = (ev.pos[0] - rect[0], ev.pos[1] - rect[1]) - hover.got_focus(0, pos) + if self.focus != hover: + # Change the focus + if self.focus: + self.focus.focus = False + self.focus.lost_focus() + self.focus = None + + self.focus = hover - self.update_mouse() + # Tell this object + hover.focus = True + hover.got_focus() return True else: # Did an object lost focus? - if self.focus: + if self.focus and self.can_lose_focus: self.focus.focus = False self.focus.lost_focus() self.focus = None @@ -207,7 +210,7 @@ # Release mousebutton after we've clicked on an object pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].got_focus(2, pos) + self.mousedown[1].click(2, pos) self.mousedown = None self.update_mouse() @@ -238,6 +241,9 @@ self.give_focus(self.children[pos]) + + + class Object(): def __init__(self, name, rect, main_parent, parent): @@ -364,6 +370,9 @@ self.give_focus(self.children[pos]) + + + class Textbox(Object): def __defaults__(self): @@ -378,15 +387,20 @@ def set_style(self, style): """ + Change the stle for this textbox Possible styles: * login """ if style == "login": + + # Check the requirements if self.rect.height != 37: raise GuiError("Height should be 37") if self.rect.width < 25: raise GuiError("Width should be 25 or bigger ") + # Load the base images. We will generated the actual images right + # now layoutimg = load_image(True, "images", "gui", "text_login.png") self.font = pygame.font.Font(real_path("fonts", \ @@ -395,12 +409,12 @@ # Create backgroundsurf self.backgroundsurf.fill([0,0,0,0]) - # Left + # Left part self.backgroundsurf.blit(layoutimg, (0, 0), (0, 0, 12, 74)) - # Right + # Right part self.backgroundsurf.blit(layoutimg, (self.rect.width-12, 0), \ (15, 0, 12, 74)) - # Middle + # Middle part middle = pygame.Surface((1, 74), SRCALPHA).convert_alpha() middle.blit(layoutimg, (0, 0,), (13, 0, 1, 74)) middle = pygame.transform.scale(middle, (self.rect.width-24, 74)) @@ -414,6 +428,7 @@ def set_type(self, type): """ + Change the type for this textbox Possible types: * text * password @@ -425,6 +440,9 @@ self.update() def render(self): + """ + Render our surface, as requested from the all mighty Container + """ if self.backgroundsurf == None: return self.surf.fill([0,0,0,0]) @@ -467,20 +485,21 @@ pygame.draw.line(self.surf, [118, 58, 19], (pos+cursorpos+6, 10), (pos+cursorpos+6, 26), 2) def hovering(self, value): - print "hover", self.name, value + pass - def got_focus(self, state, pos = None): - print "got_focus", self.name, state, pos - - if state == 0: # We got the focus! + def click(self, state, pos): + if state == 0: # [TODO] Calculate position based on pos + # self.cursorpos = ... - self.update() + if self.focus: + self.update() + + def got_focus(self): + # We got the focus! + self.update() def lost_focus(self): - print "lost_focus", self.name - - self.cursorpos = len(self.input) self.update() def keypress(self, ev): @@ -492,7 +511,7 @@ self.cursorpos = 0 else: - + print pygame.key.name(ev.key) if ev.key == K_LEFT: # Cursorpos change if self.cursorpos > 0: self.cursorpos -= 1 @@ -500,9 +519,10 @@ if self.cursorpos < len(self.input): self.cursorpos += 1 elif ev.key == K_BACKSPACE: # Backspace - self.input = self.input[:self.cursorpos-1] + \ - self.input[self.cursorpos:] - if self.cursorpos > 0: self.cursorpos -= 1 + if self.cursorpos != 0: + self.input = self.input[:self.cursorpos-1] + \ + self.input[self.cursorpos:] + self.cursorpos -= 1 elif ev.key == K_DELETE: # Delete self.input = self.input[:self.cursorpos] + \ Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-08 17:38:24 UTC (rev 363) +++ trunk/client/playground.py 2010-08-09 17:28:24 UTC (rev 364) @@ -99,16 +99,17 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui(self.drawlogingui) + self.logingui = gui(self.logingui_draw) + self.logingui.can_lose_focus = False - username = self.logingui.add("textbox", "usr", (351, 279, 298, 37)) + username = self.logingui.add("textbox", "usr", (345, 279, 310, 37)) username.set_style("login") - username.cb_keypress = self.guikeypress + username.cb_keypress = self.logingui_keypress - password = self.logingui.add("textbox", "pwd", (351, 340, 298, 37)) + password = self.logingui.add("textbox", "pwd", (345, 340, 310, 37)) password.set_style("login") password.set_type("password") - password.cb_keypress = self.guikeypress + password.cb_keypress = self.logingui_keypress #login = gui.Button("login", (0, 100, 417, 50)) self.logingui.give_focus(username) @@ -122,7 +123,7 @@ sh['update']() - def drawlogingui(self, rect): + def logingui_draw(self, rect): print "GUIupdate", rect self.surf.blit(self.loginbg, rect, rect) @@ -131,7 +132,7 @@ sh['update'](rect) - def guikeypress(self, obj, ev): + def logingui_keypress(self, obj, ev): if ev.type == KEYDOWN: if ev.unicode == "\r": if obj.name == "usr": This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-19 20:12:43
|
Revision: 366 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=366&view=rev Author: BlueWolf_ Date: 2010-08-19 20:12:36 +0000 (Thu, 19 Aug 2010) Log Message: ----------- Added a button. Sort off. Not finished but looks like it's working so far Modified Paths: -------------- trunk/client/gui.py trunk/client/playground.py Added Paths: ----------- trunk/client/images/gui/button_login.png Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-09 17:30:56 UTC (rev 365) +++ trunk/client/gui.py 2010-08-19 20:12:36 UTC (rev 366) @@ -210,10 +210,13 @@ # Release mousebutton after we've clicked on an object pos = (ev.pos[0] - self.mousedown[0][0], \ ev.pos[1] - self.mousedown[0][1]) - self.mousedown[1].click(2, pos) + + obj = self.mousedown[1] + obj.frozen = True + obj.click(2, pos) self.mousedown = None - self.update_mouse() + obj.unfreeze() return True @@ -235,9 +238,16 @@ return None, None def focus_next(self, current): - pos = self.children.index(current) + 1 + startpos = self.children.index(current) + pos = startpos + 1 if pos == len(self.children): pos = 0 + while self.children[pos].cangetfocus == False: + pos += 1 + if pos == len(self.children): pos = 0 + + if pos == startpos: return + self.give_focus(self.children[pos]) @@ -300,18 +310,16 @@ # Send a message to our parent, telling them this rect needs to be # updated - self.needs_update = True if self.frozen: return if rect == None: - rect = self.rect.move(0, 0) - - else: - # We need to calculate our relative position - rect.move_ip(self.rect.left, self.rect.top) + rect = Rect(0, 0, self.rect.width, self.rect.height) + # We need to calculate our relative position + rect = rect.move(self.rect.left, self.rect.top) + self.parent.update(rect) def blit(self, rect, surf, onto): @@ -345,7 +353,7 @@ if isparent: self.main_parent.update_mouse() self.frozen = False - self.update(self.rect) + self.update() else: self.frozen = False @@ -376,6 +384,8 @@ class Textbox(Object): def __defaults__(self): + self.cangetfocus = True + self.input = "" self.cursorpos = 0 self.style = None @@ -511,7 +521,6 @@ self.cursorpos = 0 else: - print pygame.key.name(ev.key) if ev.key == K_LEFT: # Cursorpos change if self.cursorpos > 0: self.cursorpos -= 1 @@ -547,7 +556,97 @@ self.update() if self.cb_keypress: self.cb_keypress(self, ev) - + +class Button(Object): + + def __defaults__(self): + self.cangetfocus = False + + self.caption = "" + self.style = None + + self.mousedown = False + self.ispressed = False + + self.font = None + self.backgroundsurf = pygame.Surface((self.rect.width, \ + self.rect.height*3), SRCALPHA).convert_alpha() + + def set_style(self, style): + """ + Change the stle for this textbox + Possible styles: + * login + """ + if style == "login": + + # Check the requirements + if self.rect.width != 151: + raise GuiError("Width should be 151") + if self.rect.height != 34: + raise GuiError("Height should be 34") + + # Load the background images + self.backgroundsurf = load_image(True, "images", "gui", "button_login.png") + + else: + raise GuiError("Style '%s' has not been found" % style) + + self.style = style + self.update() + + def render(self): + """ + Render our surface, as requested from the all mighty Container + """ + if self.backgroundsurf == None: return + + self.surf.fill([0,0,0,0]) + + if self.style == "login": + # Which state do we need? + if self.mousedown: + if self.ispressed: + top = 68 + else: + top = 0 + elif self.hover: + top = 34 + else: + top = 0 + + self.surf.blit(self.backgroundsurf, (0,0), \ + (0, top, self.rect.width, self.rect.height)) + + def hovering(self, value): + self.update() + + def click(self, state, pos): + if state == 0: + self.mousedown = True + self.ispressed = True + self.update() + + elif state == 1: + hover = bool(Rect(0, 0, self.rect.width, self.rect.height).collidepoint(pos)) + if hover != self.ispressed: + self.ispressed = hover + self.update() + + elif state == 2: + self.mousedown = False + self.update() + + def got_focus(self): + pass + + def lost_focus(self): + pass + + def keypress(self, ev): + pass + + class GuiError(Exception): pass Added: trunk/client/images/gui/button_login.png =================================================================== (Binary files differ) Property changes on: trunk/client/images/gui/button_login.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-09 17:30:56 UTC (rev 365) +++ trunk/client/playground.py 2010-08-19 20:12:36 UTC (rev 366) @@ -111,7 +111,9 @@ password.set_type("password") password.cb_keypress = self.logingui_keypress - #login = gui.Button("login", (0, 100, 417, 50)) + login = self.logingui.add("button", "login", (425, 398, 151, 34)) + login.set_style("login") + self.logingui.give_focus(username) self.logingui.unfreeze() @@ -135,5 +137,5 @@ def logingui_keypress(self, obj, ev): if ev.type == KEYDOWN: if ev.unicode == "\r": - if obj.name == "usr": - self.logingui.give_focus("pwd") + if obj.name == "pwd": + self.logingui.give_focus("usr") # [TODO] Not working? This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-23 21:59:47
|
Revision: 368 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=368&view=rev Author: BlueWolf_ Date: 2010-08-23 21:59:40 +0000 (Mon, 23 Aug 2010) Log Message: ----------- Now handles logging in properly. Although it won't give any reason for disconnects and failed logins yet Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-19 20:13:11 UTC (rev 367) +++ trunk/client/VP.py 2010-08-23 21:59:40 UTC (rev 368) @@ -65,7 +65,7 @@ Callback()) self.changestatus("connecting") - sh['client'].connect('localhost', 6653) + sh['client'].connect(*SERVER) # Wait for all the events to come @@ -172,6 +172,31 @@ def logged_in(self, username, cid, owner): sh['main'].changestatus("playground") + + def failed_logging_in(self, reason): + # [TODO] Send the reason in some way + sh['main'].changestatus("login") + + def disconnected(self, reason): + if reason == "manual": return + + # [TODO] Send the reason in some way + if reason in ["closed", "gone offline"]: + # Reconnect while logging in + sh['main'].changestatus("connecting") + return True + + elif reason in ["duplicate", "crash"]: + # Reconnecting while not logging in + sh['main'].changestatus("connecting") + sh['client'].connect(*SERVER) + + else: + # Not doing anything at all + # [TODO] Show popup or something, without reconnecting? + sh['main'].changestatus("connecting") + + if __name__ == "__main__": Main() Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-19 20:13:11 UTC (rev 367) +++ trunk/client/functions.py 2010-08-23 21:59:40 UTC (rev 368) @@ -22,6 +22,8 @@ VERSION = "0.0.1" +SERVER = ("localhost", 6653) + # This will be used to [sh]are all variables, functions and classes across the # code sh = {} Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-19 20:13:11 UTC (rev 367) +++ trunk/client/gui.py 2010-08-23 21:59:40 UTC (rev 368) @@ -21,9 +21,10 @@ class Container(): # A modified version of Object - def __init__(self, update): + def __init__(self, update, feedback): self.rect = Rect(0, 0, 1000, 700) self.parent_update = update + self.feedback = feedback self.frozen = True # Don't update until everything has been # loaded @@ -58,7 +59,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self, self) + obj = Obj(name, rect, self, self, self.feedback) self.children.append(obj) return obj @@ -256,11 +257,12 @@ class Object(): - def __init__(self, name, rect, main_parent, parent): + def __init__(self, name, rect, main_parent, parent, feedback): self.name = name self.rect = Rect(rect) self.main_parent = main_parent self.parent = parent + self.feedback = feedback self.needs_update = False self.frozen = True # Don't update until everything has been # loaded @@ -269,9 +271,6 @@ self.hover = False self.focus = False - # Callbacks - self.cb_keypress = None - # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -298,7 +297,7 @@ else: raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.main_parent, self) + obj = Obj(name, rect, self.main_parent, self, self.feedback) self.children.append(obj) return obj @@ -555,7 +554,7 @@ self.update() - if self.cb_keypress: self.cb_keypress(self, ev) + self.feedback.keypress(self, ev) class Button(Object): @@ -590,6 +589,10 @@ # Load the background images self.backgroundsurf = load_image(True, "images", "gui", "button_login.png") + # Load the font + self.font = pygame.font.Font(real_path("fonts", \ + "DejaVuSans-Bold.ttf"), 15) + else: raise GuiError("Style '%s' has not been found" % style) @@ -606,18 +609,31 @@ if self.style == "login": # Which state do we need? - if self.mousedown: - if self.ispressed: + if self.ispressed: top = 68 - else: - top = 0 + elif self.mousedown and not self.ispressed: + top = 0 elif self.hover: top = 34 else: top = 0 + # Blit the background self.surf.blit(self.backgroundsurf, (0,0), \ (0, top, self.rect.width, self.rect.height)) + + # Blit the text + if top == 0: + textcolor = [141, 56, 0] + elif top == 34: + textcolor = [214, 126, 68] + elif top == 68: + textcolor = [147, 81, 37] + textwidth = self.font.size(self.caption)[0] + font = self.font.render(self.caption, True, textcolor) + pos = ((self.rect.width/2) - (textwidth/2), 8) + self.surf.blit(font, pos) + def hovering(self, value): self.update() @@ -636,7 +652,13 @@ elif state == 2: self.mousedown = False + self.update() + + if self.ispressed: + self.submit() + + self.ispressed = False def got_focus(self): pass @@ -646,6 +668,13 @@ def keypress(self, ev): pass + + def submit(self): + self.feedback.submit(self) + + def manualpush(self, state): + self.ispressed = state + self.update() class GuiError(Exception): Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-19 20:13:11 UTC (rev 367) +++ trunk/client/layout.py 2010-08-23 21:59:40 UTC (rev 368) @@ -78,6 +78,9 @@ if status in login_list and self.status not in login_list: # (Un)load all the data self.topbar = None + + if self.status == "playground": + self.cleartop() elif status == "playground": self.topbar = load_image(True, "images", "topbar.png") @@ -109,6 +112,11 @@ sh['update']((0,0, 1000, 65)) + def cleartop(self): + # Remove the top bar from view + self.surf.fill([0,0,0,0]) + sh['update']((0,0, 1000, 65)) + def topbarcursor(self, pos): if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ and pos[1] < 55: Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-19 20:13:11 UTC (rev 367) +++ trunk/client/playground.py 2010-08-23 21:59:40 UTC (rev 368) @@ -38,12 +38,7 @@ if self.status == "login": # Some temporary debug stuff - if ev.type == KEYDOWN and ev.key == K_F2: - # Fake login - self.drawlogin("logging in") - sh['client'].login("test123", sha1("test123").hexdigest()) - - elif ev.type == KEYDOWN and ev.key == K_F1: + if ev.type == KEYDOWN and ev.key == K_F1: # Fake signup sh['client'].signup("test123", sha1("test123").hexdigest(), { @@ -64,6 +59,7 @@ self.loginbox = load_image(True, "images", "loginbox.png") self.loginfont = pygame.font.Font(real_path("fonts", \ "DejaVuSans.ttf"), 35) + self.loginfeedback = LoginFeedback(self) elif status == "playground": # (Un)load all the data for the playground @@ -99,19 +95,18 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui(self.logingui_draw) + self.logingui = gui(self.logingui_draw, LoginFeedback(self)) self.logingui.can_lose_focus = False username = self.logingui.add("textbox", "usr", (345, 279, 310, 37)) username.set_style("login") - username.cb_keypress = self.logingui_keypress password = self.logingui.add("textbox", "pwd", (345, 340, 310, 37)) password.set_style("login") password.set_type("password") - password.cb_keypress = self.logingui_keypress login = self.logingui.add("button", "login", (425, 398, 151, 34)) + login.caption = "Log in!" login.set_style("login") self.logingui.give_focus(username) @@ -128,14 +123,42 @@ def logingui_draw(self, rect): print "GUIupdate", rect + if self.logingui == None: return + self.surf.blit(self.loginbg, rect, rect) self.surf.blit(self.loginbox, (292, 256)) self.surf.blit(self.logingui.surf, rect, rect) sh['update'](rect) + + +class LoginFeedback(): + def __init__(self, parent): + self.parent = parent + + def keypress(self, obj, ev): + if obj.name == "usr": + # Using the enter key in the username field + if ev.type == KEYUP and ev.key == K_RETURN: + self.parent.logingui.give_focus("pwd") + + elif obj.name == "pwd": + # Using the enter key in the password field + if ev.type == KEYDOWN and ev.key == K_RETURN: + self.parent.logingui['login'].manualpush(True) + + elif ev.type == KEYUP and ev.key == K_RETURN: + self.parent.logingui['login'].manualpush(False) + self.parent.logingui['login'].submit() + - def logingui_keypress(self, obj, ev): - if ev.type == KEYDOWN: - if ev.unicode == "\r": - if obj.name == "pwd": - self.logingui.give_focus("usr") # [TODO] Not working? + def submit(self, obj): + # Clicking the login button + if obj.name == "login": + usr = self.parent.logingui['usr'].input + pwd = sha1(self.parent.logingui['pwd'].input).hexdigest() + + self.parent.logingui = None + sh['main'].changestatus("logging in") + + sh['client'].login(usr, pwd) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-25 11:42:19
|
Revision: 370 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=370&view=rev Author: BlueWolf_ Date: 2010-08-25 11:42:12 +0000 (Wed, 25 Aug 2010) Log Message: ----------- Added labels and (correctly) clickable textboxes! Modified Paths: -------------- trunk/client/functions.py trunk/client/gui.py trunk/client/playground.py Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-24 23:40:51 UTC (rev 369) +++ trunk/client/functions.py 2010-08-25 11:42:12 UTC (rev 370) @@ -56,4 +56,3 @@ # GUI needs the functions again. That's why it has to be imported after all # functions have been defined import gui -gui = gui.Container Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-24 23:40:51 UTC (rev 369) +++ trunk/client/gui.py 2010-08-25 11:42:12 UTC (rev 370) @@ -19,6 +19,17 @@ import random +class Feedback(): + def keypress(self, obj, ev): + pass + + def submit(self, obj): + pass + + def mousedown(self, obj): + pass + + class Container(): # A modified version of Object def __init__(self, update, feedback): @@ -47,18 +58,11 @@ raise KeyError(key) - def add(self, objname, name, rect): + def add(self, Obj, name, rect): """ Append a child to this object """ - if objname == "textbox": - Obj = Textbox - elif objname == "button": - Obj = Button - else: - raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self, self, self.feedback) self.children.append(obj) @@ -197,6 +201,7 @@ # Tell this object hover.focus = True hover.got_focus() + self.feedback.mousedown(hover) return True @@ -285,18 +290,11 @@ raise KeyError(key) - def add(self, objname, name, rect): + def add(self, Obj, name, rect): """ Append a child to this object """ - if objname == "textbox": - Obj = Textbox - elif objname == "button": - Obj = Button - else: - raise GuiError("Object '%s' has not been found" % objname) - obj = Obj(name, rect, self.main_parent, self, self.feedback) self.children.append(obj) @@ -390,13 +388,15 @@ self.style = None self.type = "text" + self.textpos = None # Position of the text currently + self.font = None self.backgroundsurf = pygame.Surface((self.rect.width, \ self.rect.height*2), SRCALPHA).convert_alpha() def set_style(self, style): """ - Change the stle for this textbox + Change the style for this textbox Possible styles: * login """ @@ -486,7 +486,9 @@ pos = -textwidth + truewidth - 2 else: # Cursor is in the center pos = -cursorpos + (truewidth/2) - + + self.textpos = pos + self.surf.blit(text, (6, 10), (-pos, 0, truewidth, 17)) # Blit cursor @@ -498,9 +500,22 @@ def click(self, state, pos): if state == 0: - # [TODO] Calculate position based on pos - # self.cursorpos = ... + # Calculate position based on pos + actualpos = pos[0]-6-self.textpos + lastsize = 0 + for i in range(len(self.input)+1): + textsize = self.font.size(self.input[:i])[0] + if textsize > actualpos: + # Which direction is closer, left or right? + if textsize-actualpos > actualpos-lastsize: + i = i -1 + break + lastsize = textsize + + if i == -1: i = 0 + self.cursorpos = i + if self.focus: self.update() @@ -574,7 +589,7 @@ def set_style(self, style): """ - Change the stle for this textbox + Change the style for this textbox Possible styles: * login """ @@ -677,5 +692,65 @@ self.update() +class Label(Object): + + def __defaults__(self): + self.cangetfocus = False + + self.caption = "" + + self.font = None + self.color = [0, 0, 0] + self.align = 0 + + def set_font(self, font, size): + """ + Change the font for this label + """ + + self.font = pygame.font.Font(real_path(*font), size) + + self.update() + + def render(self): + """ + Render our surface, as requested from the all mighty Container + """ + + # [TODO] Make enters work as it should + + if self.font == None: return + + self.surf.fill([0,0,0,0]) + + textwidth = self.font.size(self.caption)[0] + font = self.font.render(self.caption, True, self.color) + + # Calculate position + if self.align == 0: # Left + pos = 0 + elif self.align == 1: # Center + pos = (self.rect.width/2) - (textwidth/2) + elif self.align == 2: # Right + pos = self.rect.width - textwidth + + self.surf.blit(font, (pos, 0)) + + def hovering(self, value): + pass + + def click(self, state, pos): + pass + + def got_focus(self): + pass + + def lost_focus(self): + pass + + def keypress(self, ev): + pass + + class GuiError(Exception): pass Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-24 23:40:51 UTC (rev 369) +++ trunk/client/playground.py 2010-08-25 11:42:12 UTC (rev 370) @@ -95,21 +95,36 @@ self.surf.blit(self.loginbox, (292,256)) # Create login-field - self.logingui = gui(self.logingui_draw, LoginFeedback(self)) + self.logingui = gui.Container(self.logingui_draw, \ + LoginFeedback(self)) self.logingui.can_lose_focus = False - username = self.logingui.add("textbox", "usr", (345, 279, 310, 37)) - username.set_style("login") + usrlabel = self.logingui.add(gui.Label, "usrlabel", \ + (345, 265, 310, 18)) + usrlabel.caption = "Username:" + usrlabel.align = 1 + usrlabel.color = [177, 93, 39] + usrlabel.set_font(("fonts", "DejaVuSans-Bold.ttf"), 15) - password = self.logingui.add("textbox", "pwd", (345, 340, 310, 37)) - password.set_style("login") - password.set_type("password") + usr = self.logingui.add(gui.Textbox, "usr", (345, 285, 310, 37)) + usr.set_style("login") - login = self.logingui.add("button", "login", (425, 398, 151, 34)) + pwdlabel = self.logingui.add(gui.Label, "pwdlabel", \ + (345, 330, 310, 18)) + pwdlabel.caption = "Password:" + pwdlabel.align = 1 + pwdlabel.color = [177, 93, 39] + pwdlabel.set_font(("fonts", "DejaVuSans-Bold.ttf"), 15) + + pwd = self.logingui.add(gui.Textbox, "pwd", (345, 350, 310, 37)) + pwd.set_style("login") + pwd.set_type("password") + + login = self.logingui.add(gui.Button, "login", (425, 398, 151, 34)) login.caption = "Log in!" login.set_style("login") - self.logingui.give_focus(username) + self.logingui.give_focus(usr) self.logingui.unfreeze() @@ -132,7 +147,7 @@ sh['update'](rect) -class LoginFeedback(): +class LoginFeedback(gui.Feedback): def __init__(self, parent): self.parent = parent @@ -162,3 +177,10 @@ sh['main'].changestatus("logging in") sh['client'].login(usr, pwd) + + def mousedown(self, obj): + if obj.name == "usrlabel": + self.parent.logingui.give_focus('usr') + + elif obj.name == "pwdlabel": + self.parent.logingui.give_focus('pwd') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-25 12:45:28
|
Revision: 372 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=372&view=rev Author: BlueWolf_ Date: 2010-08-25 12:45:22 +0000 (Wed, 25 Aug 2010) Log Message: ----------- Note to myself: Don't program when feeling sleepy Modified Paths: -------------- trunk/client/core/callback.py trunk/client/core/client.py trunk/client/core/parser.py trunk/client/gui.py Modified: trunk/client/core/callback.py =================================================================== --- trunk/client/core/callback.py 2010-08-25 11:45:11 UTC (rev 371) +++ trunk/client/core/callback.py 2010-08-25 12:45:22 UTC (rev 372) @@ -101,10 +101,10 @@ """ pass - def custom_receive(self, header, body): + def custom_received(self, header, body): """ - This is when custom data from the server's app has been send. This can - be used to send custom stuff like money e.d + This is when custom data from the server' app has been sent. This can be + used to send custom stuff like money header: What type the body is (string) Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2010-08-25 11:45:11 UTC (rev 371) +++ trunk/client/core/client.py 2010-08-25 12:45:22 UTC (rev 372) @@ -292,9 +292,9 @@ def custom_send(self, data_header, data_body = {}): """ - Sends custom data 'data_body' of type 'data_header' directly to the - others custom_receive of the server's app. This can be used to send - money and other custom events. + Sends custom data 'data_body' of type 'data_header' directly to the the + custom_receive of the server' app. This can be used to send money and + other custom events. """ self.send("custom", {"header": data_header, "body": data_body}) Modified: trunk/client/core/parser.py =================================================================== --- trunk/client/core/parser.py 2010-08-25 11:45:11 UTC (rev 371) +++ trunk/client/core/parser.py 2010-08-25 12:45:22 UTC (rev 372) @@ -157,7 +157,7 @@ def custom(self, msg): """ - A custom command send from the server' app. + A custom command sent from the server' app. * header: The type of the message @@ -165,5 +165,5 @@ The message itself """ - self.call.custom(msg['header'], msg['body']) + self.call.custom_received(msg['header'], msg['body']) Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-25 11:45:11 UTC (rev 371) +++ trunk/client/gui.py 2010-08-25 12:45:22 UTC (rev 372) @@ -520,7 +520,6 @@ if i == -1: i = 0 self.cursorpos = i - if self.focus: self.update() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-25 22:03:09
|
Revision: 375 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=375&view=rev Author: BlueWolf_ Date: 2010-08-25 22:02:44 +0000 (Wed, 25 Aug 2010) Log Message: ----------- Added a Link object in the GUI, starting with the Window one and added the ability to create timers for stuff like animations Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/gui.py trunk/client/layout.py trunk/client/playground.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-25 21:07:48 UTC (rev 374) +++ trunk/client/VP.py 2010-08-25 22:02:44 UTC (rev 375) @@ -30,6 +30,8 @@ def __init__(self): sh['has_focus'] = True sh['has_hover'] = True + sh['filetable'] = {} + sh['timer'] = Timer() # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' @@ -122,7 +124,7 @@ # aka: using unlimited FPS. This will limit the FPS to 50 and will # remember everything that should be updated in the mean time - self.updaterect.append(rect) + self.updaterect.append(Rect(rect)) if self.updatewaiting: # Rect is saved. Will be updated once self.clock stops blocking return @@ -154,6 +156,44 @@ sh['layout'].changestatus(status) sh['windows'].changestatus(status) +class Timer(): + """ + This timer will update every 33ms (30fps) ones called + """ + def __init__(self): + self.speed = 0.033 + self.callers = {} + self.timer = None + + def start(self, name, call, *extra): + # Start a timer for this call + + self.callers[name] = (call, extra) + + if self.timer == None: # Start a timer + self.timer = threading.Timer(self.speed, self.update) + self.timer.start() + + def stop(self, name): + try: del self.callers[name] + except: pass + + if self.callers == {} and self.timer: + self.timer.cancel() + self.timer = None + + def update(self): + for name, info in self.callers.items(): + if info[0](name, *info[1]): + del self.callers[name] + + # Start the next timer + if self.callers != {}: + self.timer = threading.Timer(self.speed, self.update) + self.timer.start() + else: + self.timer = None + class Callback(core.Callback): @@ -195,7 +235,10 @@ # Not doing anything at all # [TODO] Show popup or something, without reconnecting? sh['main'].changestatus("connecting") - + + def custom_received(self, header, body): + if header == "filetable": # List of all the downloadable objects + sh['filetable'] = body Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-25 21:07:48 UTC (rev 374) +++ trunk/client/functions.py 2010-08-25 22:02:44 UTC (rev 375) @@ -15,7 +15,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -import pygame, os, sys, threading +import pygame, os, sys, threading, time, math from pygame.locals import * from hashlib import sha1 import core Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-25 21:07:48 UTC (rev 374) +++ trunk/client/gui.py 2010-08-25 22:02:44 UTC (rev 375) @@ -58,12 +58,13 @@ raise KeyError(key) - def add(self, Obj, name, rect): + def add(self, Obj, name, rect, feedback = None): """ Append a child to this object """ - obj = Obj(name, rect, self, self, self.feedback) + if feedback == None: feedback = self.feedback + obj = Obj(name, rect, self, self, feedback) self.children.append(obj) return obj @@ -276,6 +277,9 @@ self.hover = False self.focus = False + self.cangetfocus = True + self.canrise = False + # Create a surface where an object blits itself onto self.surf = pygame.Surface((self.rect.width, self.rect.height), \ SRCALPHA).convert_alpha() @@ -290,12 +294,34 @@ raise KeyError(key) - def add(self, Obj, name, rect): + def __defaults__(self): + pass + + def render(self): + pass + + def hovering(self, value): + pass + + def click(self, state, pos): + pass + + def got_focus(self): + pass + + def lost_focus(self): + pass + + def keypress(self, ev): + pass + + def add(self, Obj, name, rect, feedback = None): """ Append a child to this object """ - obj = Obj(name, rect, self.main_parent, self, self.feedback) + if feedback == None: feedback = self.feedback + obj = Obj(name, rect, self.main_parent, self) self.children.append(obj) return obj @@ -376,24 +402,37 @@ +class Window(Object): + def __defaults__(self): + self.cangetfocus = False + self.canrise = True + + self.canmove = True + self.hasborder = True + self.caption = "" + self.canclose = True + + def move(self, topos): + # [TODO] + pass + + class Textbox(Object): def __defaults__(self): - self.cangetfocus = True + self.textpos = None # Position of the text currently - self.input = "" + self.font = None + self.backgroundsurf = pygame.Surface((self.rect.width, \ + self.rect.height*2), SRCALPHA).convert_alpha() self.cursorpos = 0 self.style = None self.type = "text" - self.textpos = None # Position of the text currently + self.input = "" - self.font = None - self.backgroundsurf = pygame.Surface((self.rect.width, \ - self.rect.height*2), SRCALPHA).convert_alpha() - def set_style(self, style): """ Change the style for this textbox @@ -495,9 +534,6 @@ if self.focus: pygame.draw.line(self.surf, [118, 58, 19], (pos+cursorpos+6, 10), (pos+cursorpos+6, 26), 2) - def hovering(self, value): - pass - def click(self, state, pos): if state == 0: @@ -580,16 +616,14 @@ def __defaults__(self): self.cangetfocus = False - - self.caption = "" + self.font = None + self.backgroundsurf = pygame.Surface((self.rect.width, \ + self.rect.height*3), SRCALPHA).convert_alpha() self.style = None - self.mousedown = False self.ispressed = False - self.font = None - self.backgroundsurf = pygame.Surface((self.rect.width, \ - self.rect.height*3), SRCALPHA).convert_alpha() + self.caption = "" def set_style(self, style): """ @@ -629,10 +663,8 @@ if self.style == "login": # Which state do we need? if self.ispressed: - top = 68 - elif self.mousedown and not self.ispressed: - top = 0 - elif self.hover: + top = 68 + elif self.hover:# and not self.mousedown: top = 34 else: top = 0 @@ -678,16 +710,7 @@ self.submit() self.ispressed = False - - def got_focus(self): - pass - - def lost_focus(self): - pass - def keypress(self, ev): - pass - def submit(self): self.feedback.submit(self) @@ -700,10 +723,9 @@ def __defaults__(self): self.cangetfocus = False + self.font = None self.caption = "" - - self.font = None self.color = [0, 0, 0] self.align = 0 @@ -739,21 +761,92 @@ pos = self.rect.width - textwidth self.surf.blit(font, (pos, 0)) + + +class Link(Object): + + def __defaults__(self): + self.cangetfocus = False + self.font = None + self.mousedown = False + self.ispressed = False + + self.caption = "" + self.color = [0, 0, 0] + self.color_hover = [100, 100, 100] + self.color_click = [255, 255, 255] + self.align = 0 + + def set_font(self, font, size): + """ + Change the font for this label + """ + + self.font = pygame.font.Font(real_path(*font), size) + + self.update() + + def render(self): + """ + Render our surface, as requested from the all mighty Container + """ + + if self.font == None: return + + self.surf.fill([0,0,0,0]) + + textwidth = self.font.size(self.caption)[0] + + # Calculate position + if self.align == 0: # Left + pos = 0 + elif self.align == 1: # Center + pos = (self.rect.width/2) - (textwidth/2) + elif self.align == 2: # Right + pos = self.rect.width - textwidth + + # Which state do we need? + if self.ispressed: + color = self.color_click + self.font.set_underline(True) + elif self.hover and not self.mousedown: + color = self.color_hover + self.font.set_underline(True) + else: + color = self.color + self.font.set_underline(False) + + font = self.font.render(self.caption, True, color) + + self.surf.blit(font, (pos, 0)) - def hovering(self, value): - pass + def hovering(self, state): + self.update() def click(self, state, pos): - pass + if state == 0: + self.mousedown = True + self.ispressed = True + self.update() + + elif state == 1: + hover = bool(Rect(0, 0, self.rect.width, self.rect.height).collidepoint(pos)) + if hover != self.ispressed: + self.ispressed = hover + self.update() - def got_focus(self): - pass + elif state == 2: + self.mousedown = False - def lost_focus(self): - pass + self.update() + + if self.ispressed: + self.submit() + + self.ispressed = False - def keypress(self, ev): - pass + def submit(self): + self.feedback.submit(self) class GuiError(Exception): Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-25 21:07:48 UTC (rev 374) +++ trunk/client/layout.py 2010-08-25 22:02:44 UTC (rev 375) @@ -38,6 +38,7 @@ # Playground stuff self.topbar = None + self.toppos = None def event(self, ev): if self.status == "playground": @@ -69,33 +70,43 @@ self.selected = None else: self.selected = index + self.updatetop() return True def changestatus(self, status): + sh['timer'].stop("layout-topslide") # Just in case + login_list = ['connecting', 'login', 'logging in'] if status in login_list and self.status not in login_list: # (Un)load all the data - self.topbar = None - if self.status == "playground": - self.cleartop() + if self.topbar: + # Slide the topbar out + sh['timer'].start("layout-topslide", self.timer, time.time(), 0) elif status == "playground": self.topbar = load_image(True, "images", "topbar.png") self.selected = None self.hover = self.topbarcursor(pygame.mouse.get_pos()) - self.surf.blit(self.topbar, (0,0), (0,0,1000,TOPHEIGHT)) - self.updatetop() + + self.toppos = 0 + + # Slide the topbar in + sh['timer'].start("layout-topslide", self.timer, time.time(), 1) self.status = status - def updatetop(self): + def updatetop(self, wholebar = False): + if wholebar: + self.surf.fill([0,0,0,0]) + self.surf.blit(self.topbar, (0,self.toppos), (0,0,1000,TOPHEIGHT)) + for i in range(TOPBUTTONS): left = TOPLEFT + (TOPBUTTONWIDTH*i) - rect = Rect(left, 0, TOPBUTTONWIDTH, TOPHEIGHT) + rect = Rect(left, self.toppos, TOPBUTTONWIDTH, TOPHEIGHT) self.surf.fill([0,0,0,0], rect) @@ -108,18 +119,45 @@ else: rect2 = rect.move(0,0) + rect2.move_ip(0, -self.toppos) self.surf.blit(self.topbar, rect, rect2) sh['update']((0,0, 1000, 65)) - def cleartop(self): - # Remove the top bar from view - self.surf.fill([0,0,0,0]) - sh['update']((0,0, 1000, 65)) - def topbarcursor(self, pos): if pos[0] > TOPLEFT and pos[0] < (TOPBUTTONWIDTH*TOPBUTTONS+TOPLEFT) \ and pos[1] < 55: return (pos[0]-TOPLEFT) / TOPBUTTONWIDTH else: return False + + + def timer(self, name, starttime, direction): + if name == "layout-topslide": # Slide the topbar! + length = 0.3 + timeline = (time.time() - starttime) / length + + # Timer has ended + if timeline > 1: + if direction == 0 : # Up + # Clear the bar + self.topbar = None + self.surf.fill([0,0,0,0]) + sh['update']((0,0, 1000, 65)) + + elif direction == 1: # Down + toppos = 0 + self.updatetop(True) + + return True + + # Calculate current position + if direction == 0: # Up + pos = 1-math.pow(timeline, 2) + pos = (pos - 1) * TOPHEIGHT + elif direction == 1: # Down + pos = 1 - math.pow(1-timeline, 2) + pos = (pos - 1) * TOPHEIGHT + + self.toppos = pos + self.updatetop(True) Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-25 21:07:48 UTC (rev 374) +++ trunk/client/playground.py 2010-08-25 22:02:44 UTC (rev 375) @@ -124,6 +124,14 @@ login.caption = "Log in!" login.set_style("login") + signup = self.logingui.add(gui.Link, "signup", (345, 470, 310, 18)) + signup.caption = "Don't have an account yet?" + signup.align = 1 + signup.color = [140, 74, 31] + signup.color_hover = [177, 93, 39] + signup.color_click = [255, 217, 192] + signup.set_font(("fonts", "DejaVuSans.ttf"), 12) + self.logingui.give_focus(usr) self.logingui.unfreeze() @@ -177,6 +185,9 @@ sh['main'].changestatus("logging in") sh['client'].login(usr, pwd) + + elif obj.name == "signup": + print "signup!" def mousedown(self, obj): if obj.name == "usrlabel": This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-30 22:22:23
|
Revision: 378 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=378&view=rev Author: BlueWolf_ Date: 2010-08-30 22:22:16 +0000 (Mon, 30 Aug 2010) Log Message: ----------- Added the ability to download files and fixed some other stuff, including how the playground gets notified about the current status (changed changestatus to a more general 'call'). I also changed rsa_received to connection_ready in the client-core as that's a more appropriate name for what it is used for Modified Paths: -------------- trunk/client/VP.py trunk/client/core/callback.py trunk/client/core/parser.py trunk/client/functions.py trunk/client/layout.py trunk/client/playground.py trunk/client/windows.py Added Paths: ----------- trunk/client/downloader.py trunk/client/downloads/ trunk/client/downloads/img/ trunk/client/downloads/snd/ Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/VP.py 2010-08-30 22:22:16 UTC (rev 378) @@ -24,6 +24,7 @@ from playground import Playground from layout import Layout from windows import Windows +from downloader import Downloader class Main(): @@ -32,6 +33,7 @@ sh['has_hover'] = True sh['filetable'] = {} sh['timer'] = Timer() + sh['downloader'] = Downloader() # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' @@ -66,7 +68,10 @@ 'app_version': VERSION}, Callback()) - self.changestatus("connecting") + self.call("status", { + "status": "login", + "where": "connecting" + }) sh['client'].connect(*SERVER) @@ -151,10 +156,10 @@ pygame.display.update(rect) - def changestatus(self, status): - sh['playground'].changestatus(status) - sh['layout'].changestatus(status) - sh['windows'].changestatus(status) + def call(self, name, data): + sh['playground'].call(name, data) + sh['layout'].call(name, data) + sh['windows'].call(name, data) class Timer(): """ @@ -206,16 +211,33 @@ def disconnect(self, reason): print "Server disconnected: " + reason - def received_rsa(self, public): + def connection_ready(self, public_rsa, reconnecting): # We are connected - sh['main'].changestatus("login") + + if reconnecting: + sh['main'].call("status", { + "status": "login", + "where": "logging in" + }) + else: + sh['main'].call("status", { + "status": "login", + "where": "waiting" + }) def logged_in(self, username, cid, owner): - sh['main'].changestatus("playground") + sh['main'].call("status", { + "status": "login", + "where": "downloading" + }) def failed_logging_in(self, reason): # [TODO] Send the reason in some way - sh['main'].changestatus("login") + + sh['main'].call("status", { + "status": "login", + "where": "waiting" + }) def disconnected(self, reason): if reason == "manual": return @@ -223,22 +245,35 @@ # [TODO] Send the reason in some way if reason in ["closed", "gone offline"]: # Reconnect while logging in - sh['main'].changestatus("connecting") + sh['main'].call("status", { + "status": "login", + "where": "connecting" + }) return True elif reason in ["duplicate", "crash"]: # Reconnecting while not logging in - sh['main'].changestatus("connecting") + sh['main'].call("status", { + "status": "login", + "where": "connecting" + }) sh['client'].connect(*SERVER) else: # Not doing anything at all # [TODO] Show popup or something, without reconnecting? - sh['main'].changestatus("connecting") + sh['main'].call("status", { + "status": "login", + "where": "connecting" + }) def custom_received(self, header, body): if header == "filetable": # List of all the downloadable objects sh['filetable'] = body + + sh['main'].call("filetable", { + "action": "update" + }) Modified: trunk/client/core/callback.py =================================================================== --- trunk/client/core/callback.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/core/callback.py 2010-08-30 22:22:16 UTC (rev 378) @@ -28,15 +28,19 @@ """ pass - def received_rsa(self, public): + def connection_ready(self, public_rsa, reconnecting): """ When a connection is made, the server will generate a rsa-key. The client has to wait for this, before logging in. After this event, you - can use client.login (if you haven't specified a login at client.connect) + can use client.login (if you haven't specified a login at + client.connect) public: The generated public rsa-key. It is a dict with 2 values: e and n. It's used for encoding the password + reconnecting: + Boolean which is True when the core automatically tries to log in + again This is a placeholder. If you want to catch this event, overwrite this Modified: trunk/client/core/parser.py =================================================================== --- trunk/client/core/parser.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/core/parser.py 2010-08-30 22:22:16 UTC (rev 378) @@ -56,9 +56,11 @@ self.sh['rsakey'] = msg['public'] - self.call.received_rsa(msg['public']) + reconnect = (self.core.cid == None and self.sh['auto_login']) - if self.core.cid == None and self.sh['auto_login'] != (): + self.call.connection_ready(msg['public'], reconnect) + + if reconnect: login = self.sh['auto_login'] login[0](*login[1]) Added: trunk/client/downloader.py =================================================================== --- trunk/client/downloader.py (rev 0) +++ trunk/client/downloader.py 2010-08-30 22:22:16 UTC (rev 378) @@ -0,0 +1,221 @@ +## This file is part of Virtual Playground +## Copyright (c) 2009 Jos Ratsma + Koen Koning + +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either +## version 2 of the License, or (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software + +from functions import * +from Queue import Queue +import urllib2, shutil + +DOWNLOAD_THREADS = 2 + +class Downloader(): + """ + This class will download and check all the stuff that is needed + """ + def __init__(self): + self.notify = threading.Condition() + + self.tasks = [] # Dict within a list with the following things: + # filename, filetype, callbacks, usages + + self.loaded_files = {} # Dict with the following things: + # filetype, cache, usages + + self.workers = [] + for i in range(DOWNLOAD_THREADS): + self.workers.append(Worker(self.tasks, self.notify, self.error, \ + self.loaded_files)) + + + def get_file(self, filename, filetype, callback, *arg): + # First check if we already have this file loaded + + if filename in self.loaded_files: + # File is already loaded. Easy! + load = self.loaded_files[filename] + load['usages'] += 1 + callback(filename, load['cache'], *arg) + + + if filename in sh['filetable']: + # We know where it lives. Do we already have a task for this? + task = self.find_task(filename) + if task: + # Append our callback + task['usages'] += 1 + task['callbacks'].append((callback, arg)) + + else: + # Create a new task + self.tasks.append({ + "filename": filename, + "filetype": filetype, + "callbacks": [(callback, arg),], + "usages": 1, + }) + self.notify.acquire() + self.notify.notify() + self.notify.release() + + else: + print "File '" + filename + "' is not in the repository!" + callback(filename, self.error(filetype, "not in repos"), *arg) + + + def remove_usage(self, filename): + try: load = self.loaded_files[filename] + except: pass + + load['usages'] -= 1 + if load['usages'] == 0: + # Remove the file + self.remove_loaded_file(filename) + + + def remove_loaded_file(self, filename): + try: del self.loaded_files[filename] + except: pass + + + def find_task(self, filename): + for task in self.tasks: + if task['filename'] == filename: + return task + + return None + + def error(self, filetype, error): + if filetype == "img": + # [TODO] Maybe show a little error-image? + return pygame.Surface((1,1)) + + +class Worker(threading.Thread): + def __init__(self, tasks, notify, error, loaded_files): + self.tasks = tasks + self.notify = notify + self.error = error + self.loaded_files = loaded_files + + threading.Thread.__init__(self) + self.start() + + def run(self): + self.notify.acquire() + + while 1: + try: + task = self.tasks.pop(0) + except IndexError: + self.notify.wait() + continue + + + # Setting some variables + destination = real_path("downloads", task['filetype'], \ + task['filename']) + + if not task['filename'] in sh['filetable']: + print "File '" + filename + "' is not in the repository!" + self.callbacks(task, self.error(task['filetype'], \ + "not in repos")) + return + + filetable = sh['filetable'][task['filename']] + url = filetable['url'] + checksum = filetable['checksum'] + + + need_download = not os.path.exists(destination) + + # Is this file already downloaded? + if os.path.exists(destination): + # Check if we need to download the file + filehash = file_checksum("downloads", task['filetype'], \ + task['filename']) + + if checksum != filehash: + need_download = True + + # Remove existing file + os.remove(destination) + + + # Do we need to (re)download it? + if need_download: + # Download the file! + request = urllib2.Request(url) + request.add_header('User-agent', \ + "VirtualPlayground-downloader/3.0") + + try: f = urllib2.urlopen(request) + except urllib2.URLError, e: + print "Url '" + url + "' could not be found!" + self.callbacks(task, self.error(task['filetype'], \ + "not found")) + return + + target = file(destination + ".tmp", "wb") + + while 1: + bytes = f.read(10240) #Read 10240 bytes each time + + #If its zero, we've reached the end of the file! + if len(bytes) == 0: break + + target.write(bytes) + + target.close() + + # Check the checksum + filehash = file_checksum("downloads", task['filetype'], \ + task['filename'] + ".tmp") + + if checksum != filehash: + print "Checksum mismatch for '" + task['filename'] + "! " + \ + filehash + " > " + checksum + self.callbacks(task, self.error(task['filetype'], "checksum")) + + # Remove tmp file + os.remove(destination + ".tmp") + return + + # Move the file + shutil.move(destination + ".tmp", destination) + + + # Everything went good! Now load the file + load = { + "filename": task['filename'], + "filetype": task['filetype'], + "cache": None, + "usages": task['usages'] + } + + if task['filetype'] == "img": + # Load image + load['cache'] = load_image(True, "downloads", task['filetype'],\ + task['filename']) + + self.loaded_files[task['filename']] = load + self.callbacks(task, load['cache']) + + + self.notify.release() + + + def callbacks(self, task, cache): + for callback in task['callbacks']: + callback[0](task['filename'], cache, *callback[1]) Property changes on: trunk/client/downloads/img ___________________________________________________________________ Added: svn:ignore + * Property changes on: trunk/client/downloads/snd ___________________________________________________________________ Added: svn:ignore + * Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/functions.py 2010-08-30 22:22:16 UTC (rev 378) @@ -17,7 +17,7 @@ import pygame, os, sys, threading, time, math from pygame.locals import * -from hashlib import sha1 +from hashlib import sha1, md5 import core VERSION = "0.0.1" @@ -51,6 +51,19 @@ print 'Cannot load image:', fullname raise SystemExit, message return image + +def file_checksum(*dir): + # Read the file in chunks of 32KB + f = file(real_path(*dir)) + checksum = md5() + while 1: + data = f.read(32768) + if not data: break + checksum.update(data) + + return checksum.hexdigest() + + # GUI needs the functions again. That's why it has to be imported after all Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/layout.py 2010-08-30 22:22:16 UTC (rev 378) @@ -75,30 +75,34 @@ return True - def changestatus(self, status): - sh['timer'].stop("layout-topslide") # Just in case + def call(self, name, data): + if name == "status": + if data['status'] == "login": + if self.status == "playground": + # Unload all the from playground + + # Slide the topbar out + sh['timer'].start("layout-topslide", self.timer, \ + time.time(), 0) - login_list = ['connecting', 'login', 'logging in'] - if status in login_list and self.status not in login_list: - # (Un)load all the data - if self.topbar: - # Slide the topbar out - sh['timer'].start("layout-topslide", self.timer, time.time(), 0) + elif data['status'] == "playground": + if self.status != "playground": + # load al the data for the playground + self.topbar = load_image(True, "images", "topbar.png") + + self.selected = None + self.hover = self.topbarcursor(pygame.mouse.get_pos()) + + self.toppos = 0 + + # Slide the topbar in + sh['timer'].start("layout-topslide", self.timer, \ + time.time(), 1) - elif status == "playground": - self.topbar = load_image(True, "images", "topbar.png") - - self.selected = None - self.hover = self.topbarcursor(pygame.mouse.get_pos()) - - self.toppos = 0 - - # Slide the topbar in - sh['timer'].start("layout-topslide", self.timer, time.time(), 1) - - self.status = status + self.status = data['status'] + def updatetop(self, wholebar = False): if wholebar: self.surf.fill([0,0,0,0]) Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/playground.py 2010-08-30 22:22:16 UTC (rev 378) @@ -24,6 +24,7 @@ self.surf.fill([0,0,0]) self.status = None + self.statuswhere = None # Login stuff self.loginbg = None @@ -32,7 +33,7 @@ self.logingui = None # Playground stuff - # ... + self.backgrounds = {} def event(self, ev): if self.status == "login": @@ -51,36 +52,60 @@ - def changestatus(self, status): - login_list = ['connecting', 'login', 'logging in'] - if status in login_list and self.status not in login_list: - # (Un)load all the data for the login - self.loginbg = load_image(False, "images", "loginbg.png") - self.loginbox = load_image(True, "images", "loginbox.png") - self.loginfont = pygame.font.Font(real_path("fonts", \ - "DejaVuSans.ttf"), 35) - self.loginfeedback = LoginFeedback(self) - - elif status == "playground": - # (Un)load all the data for the playground - self.loginbg = None - self.loginbox = None - self.loginfont = None - self.logingui = None + def call(self, name, data): + if name == "status": # A status update + if data['status'] == "login": + if data['status'] != self.status: + # Unload data from the playground + if self.status != None: + self.backgrounds = {} + + # Load the data for the login + self.loginbg = load_image(False, "images", "loginbg.png") + self.loginbox = load_image(True, "images", "loginbox.png") + self.loginfont = pygame.font.Font(real_path("fonts", \ + "DejaVuSans.ttf"), 35) + self.loginfeedback = LoginFeedback(self) + + + if data['where'] == "connecting": + self.drawlogin("connecting") + + elif data['where'] == "waiting": + self.drawlogin("login") + + elif data['where'] == "logging in": + self.drawlogin("logging in") + + elif data['where'] == "downloading": + self.drawlogin("downloading") - self.surf.fill([0,0,0]) - sh['update']() + elif data['status'] == "playground": + if data['status'] != self.status: + # Unload data from the login + self.loginbg = None + self.loginbox = None + self.loginfont = None + self.logingui = None + + # Load the data for the playground + self.surf.fill([0,0,0]) + sh['update']() + + self.status = data['status'] + self.statuswhere = data['where'] - if status == "connecting": - self.drawlogin("connecting") - elif status == "login": - self.drawlogin("login") - elif status == "logging in": - self.drawlogin("logging in") + elif name == "filetable": + if data['action'] == "update" and self.status == "login" and \ + self.statuswhere == "downloading": + + # Pre-load the necessarily files for the playground + counter = {"counter": 1} + sh['downloader'].get_file("bg-grass.png", "img", self.download,\ + "background", counter) + - self.status = status - def drawlogin(self, status): self.loginstatus = status self.surf.blit(self.loginbg, (0,0)) @@ -141,6 +166,12 @@ posleft = (1000/2)-(text.get_size()[0]/2) self.surf.blit(text, (posleft, 330)) + + elif status == "downloading": + text = self.loginfont.render("Downloading...", True, (132,125,114)) + posleft = (1000/2)-(text.get_size()[0]/2) + self.surf.blit(text, (posleft, 330)) + sh['update']() def logingui_draw(self, rect): @@ -153,8 +184,26 @@ self.surf.blit(self.logingui.surf, rect, rect) sh['update'](rect) + + + + def download(self, filename, cache, name, *arg): + if name == "background": + self.backgrounds[filename] = cache + + counter = arg[0] + counter['counter'] -= 1 + + if counter['counter'] == 0: + # We're finished downloading the necessarily stuff + sh['main'].call("status", { + "status": "playground", + "where": "playground" + }) - + + + class LoginFeedback(gui.Feedback): def __init__(self, parent): self.parent = parent @@ -182,7 +231,10 @@ pwd = sha1(self.parent.logingui['pwd'].input).hexdigest() self.parent.logingui = None - sh['main'].changestatus("logging in") + sh['main'].call("status", { + "status": "login", + "where": "logging in" + }) sh['client'].login(usr, pwd) Modified: trunk/client/windows.py =================================================================== --- trunk/client/windows.py 2010-08-28 13:36:11 UTC (rev 377) +++ trunk/client/windows.py 2010-08-30 22:22:16 UTC (rev 378) @@ -24,5 +24,5 @@ def event(self, ev): pass - def changestatus(self, status): + def call(self, name, data): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-08-31 18:19:48
|
Revision: 381 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=381&view=rev Author: BlueWolf_ Date: 2010-08-31 18:19:41 +0000 (Tue, 31 Aug 2010) Log Message: ----------- Removed has_focus and has_hover from sh as it's practically a duplicate from key.get_focused() and mouse.get_focused() Modified Paths: -------------- trunk/client/VP.py trunk/client/gui.py trunk/client/layout.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-08-31 18:13:16 UTC (rev 380) +++ trunk/client/VP.py 2010-08-31 18:19:41 UTC (rev 381) @@ -29,8 +29,6 @@ class Main(): def __init__(self): - sh['has_focus'] = True - sh['has_hover'] = True sh['filetable'] = {} sh['timer'] = Timer() sh['downloader'] = Downloader() @@ -92,17 +90,7 @@ ev = pygame.event.Event(MOUSEMOTION, buttons = ev.buttons, pos = pos) - - # As (sometimes) the mouse focus doesn't get through when - # switching workspaces (Linux), this should "fix" it - sh['has_hover'] = True - elif ev.type == ACTIVEEVENT: - if ev.state == 1: # Mouse focus - sh['has_hover'] = (ev.gain == 1) - elif ev.state == 2: # Window focus - sh['has_focus'] = (ev.gain == 1) - # Send through all the layers if sh['windows'].event(ev): continue if sh['layout'].event(ev): continue Modified: trunk/client/gui.py =================================================================== --- trunk/client/gui.py 2010-08-31 18:13:16 UTC (rev 380) +++ trunk/client/gui.py 2010-08-31 18:19:41 UTC (rev 381) @@ -111,7 +111,7 @@ if pos == None: pos = pygame.mouse.get_pos() - if sh['has_hover']: + if pygame.mouse.get_focused(): # Get the current hovered object rect, hover = self.this_pos(pos) Modified: trunk/client/layout.py =================================================================== --- trunk/client/layout.py 2010-08-31 18:13:16 UTC (rev 380) +++ trunk/client/layout.py 2010-08-31 18:19:41 UTC (rev 381) @@ -92,7 +92,10 @@ self.topbar = load_image(True, "images", "topbar.png") self.selected = None - self.hover = self.topbarcursor(pygame.mouse.get_pos()) + if pygame.mouse.get_focused(): + self.hover = self.topbarcursor(pygame.mouse.get_pos()) + else: + self.hover = None self.toppos = 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-09-01 15:37:28
|
Revision: 385 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=385&view=rev Author: BlueWolf_ Date: 2010-09-01 15:37:21 +0000 (Wed, 01 Sep 2010) Log Message: ----------- * Download-threads will now stop when closing VP. * The playground-test-walk now works with the timer to test the performance. * Also moved the FPS to 100 because I suspect a bug in the updater which halves the FPS in some situations. In the future 50FPS will probably be enough Modified Paths: -------------- trunk/client/VP.py trunk/client/downloader.py trunk/client/functions.py trunk/client/playground.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-09-01 14:24:10 UTC (rev 384) +++ trunk/client/VP.py 2010-09-01 15:37:21 UTC (rev 385) @@ -103,6 +103,7 @@ # Someone decided to close VP (Why??) try: sh['client'].close() except: pass + sh['downloader'].stop() sys.exit() @@ -125,7 +126,7 @@ # When there are more updates from here one, they will be saved without # being updated immediately. We will do that once tick stops blocking self.updatewaiting = True - self.clock.tick(50) + self.clock.tick(UPDATE_FPS) # Get all the rects to update if len(self.updaterect) == 1: @@ -154,7 +155,7 @@ This timer will update every 33ms (30fps) ones called """ def __init__(self): - self.speed = 0.033 + self.speed = 1/float(UPDATE_FPS) self.callers = {} self.timer = None Modified: trunk/client/downloader.py =================================================================== --- trunk/client/downloader.py 2010-09-01 14:24:10 UTC (rev 384) +++ trunk/client/downloader.py 2010-09-01 15:37:21 UTC (rev 385) @@ -15,7 +15,7 @@ ## along with this program; if not, write to the Free Software from functions import * -from Queue import Queue +import Queue import urllib2, shutil DOWNLOAD_THREADS = 2 @@ -25,17 +25,17 @@ This class will download and check all the stuff that is needed """ def __init__(self): - self.notify = threading.Condition() + self.queue = Queue.PriorityQueue() - self.tasks = [] # Dict within a list with the following things: - # filename, filetype, callbacks, usages + self.tasks = {} # Dict with the key being the filename and value being a + # dict with: filetype, callbacks, usages self.loaded_files = {} # Dict with the following things: # filetype, cache, usages self.workers = [] for i in range(DOWNLOAD_THREADS): - self.workers.append(Worker(self.tasks, self.notify, self.error, \ + self.workers.append(Worker(self.tasks, self.queue, self.error, \ self.loaded_files)) @@ -51,23 +51,20 @@ if filename in sh['filetable']: # We know where it lives. Do we already have a task for this? - task = self.find_task(filename) - if task: + if self.tasks.has_key(filename): # Append our callback + task = self.tasks[filename] task['usages'] += 1 task['callbacks'].append((callback, arg)) else: # Create a new task - self.tasks.append({ - "filename": filename, + self.tasks[filename] = { "filetype": filetype, "callbacks": [(callback, arg),], "usages": 1, - }) - self.notify.acquire() - self.notify.notify() - self.notify.release() + } + self.queue.put((1, filename)) else: print "File '" + filename + "' is not in the repository!" @@ -87,53 +84,50 @@ def remove_loaded_file(self, filename): try: del self.loaded_files[filename] except: pass - - - def find_task(self, filename): - for task in self.tasks: - if task['filename'] == filename: - return task - return None def error(self, filetype, error): if filetype == "img": # [TODO] Maybe show a little error-image? return pygame.Surface((1,1)) + + def stop(self): + # Stop the download-threads + for i in range(DOWNLOAD_THREADS): + self.queue.put((0, "STOP")) + class Worker(threading.Thread): - def __init__(self, tasks, notify, error, loaded_files): + def __init__(self, tasks, queue, error, loaded_files): self.tasks = tasks - self.notify = notify + self.queue = queue self.error = error self.loaded_files = loaded_files + self.quiting = False threading.Thread.__init__(self) self.start() def run(self): - self.notify.acquire() - while 1: - try: - task = self.tasks.pop(0) - except IndexError: - self.notify.wait() - continue + task = self.queue.get()[1] + if task == "STOP": return - + filename = task + task = self.tasks[filename] + # Setting some variables destination = real_path("downloads", task['filetype'], \ - task['filename']) + filename) - if not task['filename'] in sh['filetable']: + if not filename in sh['filetable']: print "File '" + filename + "' is not in the repository!" - self.callbacks(task, self.error(task['filetype'], \ - "not in repos")) + self.callbacks(filename, task['callbacks'], \ + self.error(task['filetype'], "not in repos")) return - filetable = sh['filetable'][task['filename']] + filetable = sh['filetable'][filename] url = filetable['url'] checksum = filetable['checksum'] @@ -144,7 +138,7 @@ if os.path.exists(destination): # Check if we need to download the file filehash = file_checksum("downloads", task['filetype'], \ - task['filename']) + filename) if checksum != filehash: need_download = True @@ -163,8 +157,8 @@ try: f = urllib2.urlopen(request) except urllib2.URLError, e: print "Url '" + url + "' could not be found!" - self.callbacks(task, self.error(task['filetype'], \ - "not found")) + self.callbacks(filename, task['callbacks'], \ + self.error(filename, "not found")) return target = file(destination + ".tmp", "wb") @@ -181,12 +175,13 @@ # Check the checksum filehash = file_checksum("downloads", task['filetype'], \ - task['filename'] + ".tmp") + filename + ".tmp") if checksum != filehash: - print "Checksum mismatch for '" + task['filename'] + "! " + \ + print "Checksum mismatch for '" + filename + "! " + \ filehash + " > " + checksum - self.callbacks(task, self.error(task['filetype'], "checksum")) + self.callbacks(filename, task['callbacks'], \ + self.error(task['filetype'], "checksum")) # Remove tmp file os.remove(destination + ".tmp") @@ -198,7 +193,6 @@ # Everything went good! Now load the file load = { - "filename": task['filename'], "filetype": task['filetype'], "cache": None, "usages": task['usages'] @@ -207,15 +201,12 @@ if task['filetype'] == "img": # Load image load['cache'] = load_image(True, "downloads", task['filetype'],\ - task['filename']) + filename) - self.loaded_files[task['filename']] = load - self.callbacks(task, load['cache']) + self.loaded_files[filename] = load + self.callbacks(filename, task['callbacks'], load['cache']) - - self.notify.release() - - def callbacks(self, task, cache): - for callback in task['callbacks']: - callback[0](task['filename'], cache, *callback[1]) + def callbacks(self, filename, callbacks, cache): + for callback in callbacks: + callback[0](filename, cache, *callback[1]) Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-09-01 14:24:10 UTC (rev 384) +++ trunk/client/functions.py 2010-09-01 15:37:21 UTC (rev 385) @@ -22,8 +22,10 @@ VERSION = "0.0.1" -SERVER = ("localhost", 6653) +SERVER = ("vp.bluewolf.nl", 6653) +UPDATE_FPS = 100 + # This will be used to [sh]are all variables, functions and classes across the # code sh = {} Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-09-01 14:24:10 UTC (rev 384) +++ trunk/client/playground.py 2010-09-01 15:37:21 UTC (rev 385) @@ -38,6 +38,7 @@ # Playground stuff self.backgrounds = {} self.viewport = None + self.direction_pressed = None def event(self, ev): @@ -58,18 +59,27 @@ elif self.status == "playground": if ev.type == KEYDOWN: - if ev.key == K_UP: - self.viewport.move_ip(0, -10) - self.playground_render() - if ev.key == K_DOWN: - self.viewport.move_ip(0, 10) - self.playground_render() - if ev.key == K_LEFT: - self.viewport.move_ip(-10, 0) - self.playground_render() - if ev.key == K_RIGHT: - self.viewport.move_ip(10, 0) - self.playground_render() + if ev.key == K_UP and self.direction_pressed != 0: + self.direction_pressed = 0 + sh['timer'].start("playground_move", self.playground_move, \ + time.time(), self.viewport.top, 0) + elif ev.key == K_DOWN and self.direction_pressed != 1: + self.direction_pressed = 1 + sh['timer'].start("playground_move", self.playground_move, \ + time.time(), self.viewport.top, 1) + elif ev.key == K_LEFT and self.direction_pressed != 2: + self.direction_pressed = 2 + sh['timer'].start("playground_move", self.playground_move, \ + time.time(), self.viewport.left, 2) + elif ev.key == K_RIGHT and self.direction_pressed != 3: + self.direction_pressed = 3 + sh['timer'].start("playground_move", self.playground_move, \ + time.time(), self.viewport.left, 3) + + elif ev.type == KEYUP: + if ev.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]: + self.direction_pressed = None + sh['timer'].stop("playground_move") def call(self, name, data): @@ -281,8 +291,25 @@ self.transit = 1 - timeline self.playground_render() + + + def playground_move(self, name, startime, startpos, direction): + # Temporary test function to walk + + timeline = time.time() - startime + speed = 175 + move = timeline*speed + + if direction == 0: + self.viewport.top = startpos - move + elif direction == 1: + self.viewport.top = startpos + move + elif direction == 2: + self.viewport.left = startpos - move + elif direction == 3: + self.viewport.left = startpos + move + self.playground_render() - class LoginFeedback(gui.Feedback): def __init__(self, parent): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-09-01 17:41:11
|
Revision: 386 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=386&view=rev Author: BlueWolf_ Date: 2010-09-01 17:41:05 +0000 (Wed, 01 Sep 2010) Log Message: ----------- Limited the FPS to 50 and also fixed the update-function blocking too much code (which dropped the framerate dramatically) Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/playground.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-09-01 15:37:21 UTC (rev 385) +++ trunk/client/VP.py 2010-09-01 17:41:05 UTC (rev 386) @@ -114,30 +114,20 @@ and update the screen """ - # The following code will prevent it from going crazy on the cpu. - # aka: using unlimited FPS. This will limit the FPS to 50 and will - # remember everything that should be updated in the mean time - - self.updaterect.append(Rect(rect)) + # When something updates due to a timer-update, nothing will be updated + # as long as the frame is still being rendered. Instead, the rect will + # be saved and will be updated once the timer has finished this frame if self.updatewaiting: - # Rect is saved. Will be updated once self.clock stops blocking + self.updaterect.append(Rect(rect)) return - # When there are more updates from here one, they will be saved without - # being updated immediately. We will do that once tick stops blocking - self.updatewaiting = True - self.clock.tick(UPDATE_FPS) - # Get all the rects to update - if len(self.updaterect) == 1: - rects = self.updaterect[0] - else: - rects = self.updaterect[0].unionall(self.updaterect[1:]) + if type(rect) == list: + if len(rect) == 1: + rect = rect[0] + else: + rect = rect[0].unionall(rect[1:]) - self.updaterect = [] - self.updatewaiting = False - - # The actual updating happens here sh['screen'].blit(sh['playground'].surf, rect, rect) sh['screen'].blit(sh['layout'].surf, rect, rect) @@ -152,7 +142,7 @@ class Timer(): """ - This timer will update every 33ms (30fps) ones called + This timer will update every frame as defined in UPDATE_FPS @ functions.py """ def __init__(self): self.speed = 1/float(UPDATE_FPS) @@ -177,10 +167,22 @@ self.timer = None def update(self): + # Stop blitting to the screen + sh['main'].updaterect = [] + sh['main'].updatewaiting = True + + # Do stuff for name, info in self.callers.items(): if info[0](name, *info[1]): del self.callers[name] + # Force one big update + sh['main'].updatewaiting = False + if sh['main'].updaterect != []: + sh['main'].update(sh['main'].updaterect) + sh['main'].updaterect = [] + + # Start the next timer if self.callers != {}: self.timer = threading.Timer(self.speed, self.update) Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-09-01 15:37:21 UTC (rev 385) +++ trunk/client/functions.py 2010-09-01 17:41:05 UTC (rev 386) @@ -24,7 +24,7 @@ SERVER = ("vp.bluewolf.nl", 6653) -UPDATE_FPS = 100 +UPDATE_FPS = 50 # This will be used to [sh]are all variables, functions and classes across the # code Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-09-01 15:37:21 UTC (rev 385) +++ trunk/client/playground.py 2010-09-01 17:41:05 UTC (rev 386) @@ -61,25 +61,25 @@ if ev.type == KEYDOWN: if ev.key == K_UP and self.direction_pressed != 0: self.direction_pressed = 0 - sh['timer'].start("playground_move", self.playground_move, \ + sh['timer'].start("playground-move", self.playground_move, \ time.time(), self.viewport.top, 0) elif ev.key == K_DOWN and self.direction_pressed != 1: self.direction_pressed = 1 - sh['timer'].start("playground_move", self.playground_move, \ + sh['timer'].start("playground-move", self.playground_move, \ time.time(), self.viewport.top, 1) elif ev.key == K_LEFT and self.direction_pressed != 2: self.direction_pressed = 2 - sh['timer'].start("playground_move", self.playground_move, \ + sh['timer'].start("playground-move", self.playground_move, \ time.time(), self.viewport.left, 2) elif ev.key == K_RIGHT and self.direction_pressed != 3: self.direction_pressed = 3 - sh['timer'].start("playground_move", self.playground_move, \ + sh['timer'].start("playground-move", self.playground_move, \ time.time(), self.viewport.left, 3) elif ev.type == KEYUP: if ev.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]: self.direction_pressed = None - sh['timer'].stop("playground_move") + sh['timer'].stop("playground-move") def call(self, name, data): @@ -89,6 +89,7 @@ # Unload data from the playground if self.status != None: sh['timer'].stop("playground-transit") + sh['timer'].stop("playground-move") for name in self.backgrounds.keys(): sh['downloader'].remove_usage(name) self.backgrounds = {} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-09-01 18:20:23
|
Revision: 387 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=387&view=rev Author: BlueWolf_ Date: 2010-09-01 18:20:17 +0000 (Wed, 01 Sep 2010) Log Message: ----------- Forgot to let the downloader remove a task once it's finished. Also changed some debugging stuff to make it a (bit) more debugable Modified Paths: -------------- trunk/client/VP.py trunk/client/downloader.py trunk/client/playground.py Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-09-01 17:41:05 UTC (rev 386) +++ trunk/client/VP.py 2010-09-01 18:20:17 UTC (rev 387) @@ -136,6 +136,8 @@ pygame.display.update(rect) def call(self, name, data): + print " [>] \t", name, data + sh['playground'].call(name, data) sh['layout'].call(name, data) sh['windows'].call(name, data) @@ -194,14 +196,11 @@ class Callback(core.Callback): def data_received(self, data): - print " --> " + repr(data) + print " --> \t" + repr(data) def data_send(self, data): - print " <-- " + repr(data) + print " <-- \t" + repr(data) - def disconnect(self, reason): - print "Server disconnected: " + reason - def connection_ready(self, public_rsa, reconnecting): # We are connected @@ -231,6 +230,8 @@ }) def disconnected(self, reason): + print " !!! \tConnection closed: " + reason + if reason == "manual": return # [TODO] Send the reason in some way Modified: trunk/client/downloader.py =================================================================== --- trunk/client/downloader.py 2010-09-01 17:41:05 UTC (rev 386) +++ trunk/client/downloader.py 2010-09-01 18:20:17 UTC (rev 387) @@ -40,6 +40,7 @@ def get_file(self, filename, filetype, callback, *arg): + print " !!! \tDownload task:", filename # First check if we already have this file loaded if filename in self.loaded_files: @@ -116,6 +117,7 @@ filename = task task = self.tasks[filename] + del self.tasks[filename] # Setting some variables destination = real_path("downloads", task['filetype'], \ Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-09-01 17:41:05 UTC (rev 386) +++ trunk/client/playground.py 2010-09-01 18:20:17 UTC (rev 387) @@ -213,8 +213,6 @@ sh['update']() def logingui_draw(self, rect): - print "GUIupdate", rect - if self.logingui == None: return self.surf.blit(self.loginbg, rect, rect) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <Blu...@us...> - 2010-09-01 21:01:28
|
Revision: 388 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=388&view=rev Author: BlueWolf_ Date: 2010-09-01 21:01:21 +0000 (Wed, 01 Sep 2010) Log Message: ----------- * Added a config to the client * Stuff like FPS and host is now configurable * Client now stores the login information and uses that (no way to log out yet) * 'Effects' option doesn't do anything yet Modified Paths: -------------- trunk/client/VP.py trunk/client/functions.py trunk/client/playground.py Added Paths: ----------- trunk/client/configspec Property Changed: ---------------- trunk/client/ Property changes on: trunk/client ___________________________________________________________________ Added: svn:ignore + config.conf Modified: trunk/client/VP.py =================================================================== --- trunk/client/VP.py 2010-09-01 18:20:17 UTC (rev 387) +++ trunk/client/VP.py 2010-09-01 21:01:21 UTC (rev 388) @@ -29,9 +29,12 @@ class Main(): def __init__(self): + load_config() + sh['filetable'] = {} sh['timer'] = Timer() sh['downloader'] = Downloader() + sh['login_info'] = None # Fire up pygame os.environ['SDL_VIDEO_CENTERED']='1' @@ -70,7 +73,8 @@ "status": "login", "where": "connecting" }) - sh['client'].connect(*SERVER) + sh['client'].connect(sh['config']['host']['host'], \ + sh['config']['host']['port']) # Wait for all the events to come @@ -104,6 +108,7 @@ try: sh['client'].close() except: pass sh['downloader'].stop() + sh['config'].write() sys.exit() @@ -144,10 +149,10 @@ class Timer(): """ - This timer will update every frame as defined in UPDATE_FPS @ functions.py + This timer will update every frame as defined in the config """ def __init__(self): - self.speed = 1/float(UPDATE_FPS) + self.speed = 1/float(sh['config']['graphics']['fps']) self.callers = {} self.timer = None @@ -210,16 +215,33 @@ "where": "logging in" }) else: - sh['main'].call("status", { - "status": "login", - "where": "waiting" - }) + # Do we need to log in automatically? + if sh['config']['user']['username'] != "": + sh['main'].call("status", { + "status": "login", + "where": "logging in" + }) + sh['client'].login(sh['config']['user']['username'], \ + sh['config']['user']['password']) + + else: + sh['main'].call("status", { + "status": "login", + "where": "waiting" + }) def logged_in(self, username, cid, owner): sh['main'].call("status", { "status": "login", "where": "downloading" }) + + # Save the login + if sh['login_info'] != None: + sh['config']['user']['username'] = sh['login_info'][0] + sh['config']['user']['password'] = sh['login_info'][1] + sh['login_info'] = None + sh['config'].write() def failed_logging_in(self, reason): # [TODO] Send the reason in some way @@ -228,10 +250,18 @@ "status": "login", "where": "waiting" }) + + sh['config']['user']['username'] = "" + sh['config']['user']['password'] = "" + sh['login_info'] = None + sh['config'].write() + def disconnected(self, reason): print " !!! \tConnection closed: " + reason + sh['login_info'] = None + if reason == "manual": return # [TODO] Send the reason in some way @@ -249,8 +279,16 @@ "status": "login", "where": "connecting" }) - sh['client'].connect(*SERVER) + # But don't reconnect when we where a duplicate + if reason == "duplicate": + sh['config']['user']['username'] = "" + sh['config']['user']['password'] = "" + sh['config'].write() + + sh['client'].connect(sh['config']['host']['host'], \ + sh['config']['host']['port']) + else: # Not doing anything at all # [TODO] Show popup or something, without reconnecting? Added: trunk/client/configspec =================================================================== --- trunk/client/configspec (rev 0) +++ trunk/client/configspec 2010-09-01 21:01:21 UTC (rev 388) @@ -0,0 +1,11 @@ +[user] +username = string(default="") +password = string(default="") + +[graphics] +fps = integer(min=1, default=50) +effects = boolean(default=True) + +[host] +host = string(default=vp.bluewolf.nl) +port = integer(default=6653) Modified: trunk/client/functions.py =================================================================== --- trunk/client/functions.py 2010-09-01 18:20:17 UTC (rev 387) +++ trunk/client/functions.py 2010-09-01 21:01:21 UTC (rev 388) @@ -18,14 +18,12 @@ import pygame, os, sys, threading, time, math from pygame.locals import * from hashlib import sha1, md5 +import configobj +from validate import Validator import core VERSION = "0.0.1" -SERVER = ("vp.bluewolf.nl", 6653) - -UPDATE_FPS = 50 - # This will be used to [sh]are all variables, functions and classes across the # code sh = {} @@ -64,7 +62,31 @@ checksum.update(data) return checksum.hexdigest() + +def load_config(): + # Load the config file and apply the default values to it if needed + + try: + sh['config'] = configobj.ConfigObj(real_path("config.conf"), \ + configspec = real_path("configspec")) + except configobj.ParseError: + print "Config: The config-file is malformed. Please check the file " + \ + "or remove it to create a new default one" + sys.exit() + + validator = Validator() + result = sh['config'].validate(validator, copy = True) + + if result != True: + for (section_list, key, _) in configobj.flatten_errors(sh['config'], \ + result): + if key is not None: + print "Config: Something is wrong with the " + \ + "'%s/%s' key. Please check" % (section_list[0], key) + else: + print "Config: The '%s' section is missing" % section_list[0] + sys.exit() Modified: trunk/client/playground.py =================================================================== --- trunk/client/playground.py 2010-09-01 18:20:17 UTC (rev 387) +++ trunk/client/playground.py 2010-09-01 21:01:21 UTC (rev 388) @@ -342,6 +342,9 @@ "where": "logging in" }) + # Save the info so it can be saved it the login succeeds + sh['login_info'] = (usr,pwd) + sh['client'].login(usr, pwd) elif obj.name == "signup": This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |