From: pin Date: Wed, 19 May 2010 12:28:12 +0000 (+0000) Subject: ménage (par le vide) X-Git-Url: https://svn.cri.ensmp.fr/git/minwii.git/commitdiff_plain/4c4732c6ed8cb0aaa70fb2d4c6e5a958868c5349?ds=sidebyside;hp=346a9b8e1fcfe30629f0d1ee4675e9e8f89890cf ménage (par le vide) git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@173 fe552daf-6dbe-4428-90eb-1537e0879342 --- diff --git a/src/controllers/Wiimote.py b/src/controllers/Wiimote.py deleted file mode 100755 index e75cdc3..0000000 --- a/src/controllers/Wiimote.py +++ /dev/null @@ -1,133 +0,0 @@ -''' -Created on 15 juil. 2009 - -@author: Samuel Benveniste -''' -from gui.constants import * -import fluidsynth - -class Wiimote: - ''' - Object representing a Wiimote - - number: - The number of the Wiimote - port: - The pypm object representing the MIDI port on which the Wiimote emits - instrument: - The instrument associated with the Wiimote - cursor: - The cursor associated with the Wiimote - ''' - - def __init__(self, number, portNumber, port, instrument, cursor): - ''' - Constructor - - number: - The number of the Wiimote - portNumber: - The number of the port (as numbered by pypm) on which the wiimote emits - port: - The pypm object representing the MIDI port on which the Wiimote emits - instrument: - The instrument associated with the Wiimote - cursor: - The cursor associated with the Wiimote - ''' - self.number = number - self.portNumber = portNumber - self.port = port - self.instrument = instrument - self.cursor = cursor - self.numberPlayed = 0 - - self.fs = fs = fluidsynth.Synth() - fs.start() - soundFont = r"C:\Documents and Settings\Administrator\My Documents\Telechargements\fluid-soundfont-3.1\FluidR3_GM.sf2" - self.fsid = fsid = fs.sfload(soundFont) - bank = 0 - preset = 0 - fs.program_select(0, fsid, bank, preset) - - def __del__(self) : - self.fs.delete() - - def getNoteOnHexCode(self): - return (0x90 + self.instrument.channel - 1) - - def getAftertouchHexCode(self): - return (0xA0 + self.instrument.channel - 1) - - def getCCHexCode(self): - return (0xB0 + self.instrument.channel - 1) - -# def playNote(self, note, velocity): -# print 'playNote' -# noteNumber = self.instrument.getNote(note) -# -# if noteNumber != None : -# noteOnHexCode = self.getNoteOnHexCode() -# CCHexCode = self.getCCHexCode() -# else : -# noteNumber = defaultInstrumentNote -# noteOnHexCode = defaultNoteOnHexCode -# CCHexCode = defaultCCHexCode -# -# self.port.write_short(noteOnHexCode, noteNumber , 127) -# self.port.write_short(CCHexCode, 07, velocity) - - def playNoteByNoteNumber(self, midiNoteNumber, velocity): - print 'playNoteByNumber' - noteNumber = self.instrument.getNoteByNoteNumber(midiNoteNumber) - fs = self.fs - fs.noteon(0, noteNumber, velocity) - - return - noteNumber = self.instrument.getNoteByNoteNumber(midiNoteNumber) - - if noteNumber != None : - noteOnHexCode = self.getNoteOnHexCode() - CCHexCode = self.getCCHexCode() - else : - noteNumber = defaultInstrumentNote - noteOnHexCode = defaultNoteOnHexCode - CCHexCode = defaultCCHexCode - - self.port.write_short(noteOnHexCode, noteNumber , 127) - self.port.write_short(CCHexCode, 07, velocity) - - self.numberPlayed += 1 - -# def stopNote(self, note): -# print 'stopNote' -# noteNumber = self.instrument.getNote(note) -# if noteNumber != None : -# noteOnHexCode = self.getNoteOnHexCode() -# else : -# noteNumber = defaultInstrumentNote -# noteOnHexCode = defaultNoteOnHexCode -# -# self.port.write_short(noteOnHexCode, noteNumber, 0) - - def stopNoteByNoteNumber(self, midiNoteNumber): - print 'stopNoteByNoteNumber' - - noteNumber = self.instrument.getNoteByNoteNumber(midiNoteNumber) - fs = self.fs - fs.noteoff(0, noteNumber) - - return - noteNumber = self.instrument.getNoteByNoteNumber(midiNoteNumber) - if noteNumber != None : - noteOnHexCode = self.getNoteOnHexCode() - else : - noteNumber = defaultInstrumentNote - noteOnHexCode = defaultNoteOnHexCode - - self.port.write_short(noteOnHexCode, noteNumber, 0) - -# def allNotesOff(self): -# print 'allNoteOff' -# CCHexCode = self.getCCHexCode() -# self.port.write_short(CCHexCode,123,0) diff --git a/src/controllers/__init__.py b/src/controllers/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/cursor/WarpingCursor.py b/src/cursor/WarpingCursor.py deleted file mode 100755 index 57985e1..0000000 --- a/src/cursor/WarpingCursor.py +++ /dev/null @@ -1,155 +0,0 @@ -''' -Created on 29 mai 2009 - -@author: samsam -''' - -import os, sys, math - -import pygame -from pygame.sprite import Sprite - -class WarpingCursor(Sprite): - ''' - The class for animating the warping cursor - - screen: - the screen on which the WarpingCursor is painted - images: - The images constituting the animation of the cursor - durations: - The duration of each image in the animation - centerPosition: - The Position of the center of the cursor - _imagePointer: - A pointer to the current image - _animationOffset: - The time elapsed since when the current image should have been displayed - ''' - screen = None - images = None - durations = None - centerPosition = None - _imagePointer = None - _animationOffset = None - - - def __init__(self, scr, images, durations, initCenterPosition,flashImage): - ''' - Constructor - - scr: - the screen on which the WarpingCursor is painted - images: - The images constituting the animation of the cursor - durations: - The duration of each image in the animation - initCenterPosition: - The Position of the center of the cursor at the beginning - ''' - self.screen = scr - self.images = images - self.flashImagePath = flashImage - self.durations = durations - self.centerPosition = initCenterPosition - self.flashLength = 100 - self.flashing = False - self.image = pygame.image.load(self.images[0]).convert_alpha() - self._imagePointer = 0 - self._animationOffset = 0 - self._flashTimer = 0 - - def update(self, elapsedTime, centerPosition): - ''' - Update the cursor's look and position - - elapsedTime: - The time passed since the previous update - centerPosition: - the new position of the creep - ''' - self._updateImage(elapsedTime) - self.centerPosition = centerPosition - if self.flashing : - self._flashTimer += elapsedTime - if self._flashTimer > self.flashLength: - self.flashing = False - - def _updateImage(self, elapsedTime): - ''' - Update the cursor's image - - elapsedTime: - The time passed since the previous update - ''' - self._animationOffset += elapsedTime - - if self._animationOffset > self.durations[self._imagePointer]: - #New animation offset is computed first, before updating the pointer - self._animationOffset -= self.durations[self._imagePointer] - #point to the next image (restarts from the beginning when it reaches the end) - self._imagePointer = (self._imagePointer + 1) % len(self.images) - - if self.flashing: - self.image = pygame.image.load(self.flashImagePath).convert_alpha() - else : - self.image = pygame.image.load(self.images[self._imagePointer]).convert_alpha() - - def flash(self,flashLength = None): - self._flashTimer = 0 - self.flashing = True - if flashLength: - self.flashlength = flashLength - - def blit(self,surface): - ''' - Draw the circle on surface - ''' - - newPos = (self.centerPosition[0] - self.image.get_width() / 2, self.centerPosition[1] - self.image.get_height() / 2) - surface.blit(self.image, newPos) - -def createImageListFromPath(path, imageCount): - ''' - Create a list of images for a cursor (the concatenation of the original and reversed lists of images). - Images must be stored as path/imageNumber.png - - path: - The folder where the images for that cursor are stored - imageCount: - The number of images in the folder - ''' - - tempImages = [''.join([path, '/', str(i), '.png']) for i in range(imageCount)] - #tempImagesReversed = tempImages[:] - #tempImagesReversed.reverse() - #return(tempImages+tempImagesReversed) - return(tempImages) - -#testing -if __name__ == "__main__" : - window = pygame.display.set_mode((1680, 1050), pygame.FULLSCREEN) - screen = pygame.display.get_surface() - clock = pygame.time.Clock() - - images = createImageListFromPath('cursorImages/black',11) - durations = [50 for i in range(22)] - position = (400, 300) - cursor = WarpingCursor(screen, images, durations, position) - - while True: - # Limit frame speed to 50 FPS - # - timePassed = clock.tick(50) - - for event in pygame.event.get(): - if event.type == pygame.QUIT: - sys.exit() - if event.type == pygame.MOUSEMOTION: - position = event.pos - - cursor.update(timePassed, position) - cursor.blit(screen) - pygame.display.flip() - - diff --git a/src/cursor/__init__.py b/src/cursor/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/cursor/cursorImages/black/0.png b/src/cursor/cursorImages/black/0.png deleted file mode 100755 index d676349..0000000 Binary files a/src/cursor/cursorImages/black/0.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/1.png b/src/cursor/cursorImages/black/1.png deleted file mode 100755 index 7703e89..0000000 Binary files a/src/cursor/cursorImages/black/1.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/10.png b/src/cursor/cursorImages/black/10.png deleted file mode 100755 index 6c85004..0000000 Binary files a/src/cursor/cursorImages/black/10.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/2.png b/src/cursor/cursorImages/black/2.png deleted file mode 100755 index 9eec08e..0000000 Binary files a/src/cursor/cursorImages/black/2.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/3.png b/src/cursor/cursorImages/black/3.png deleted file mode 100755 index ce93f45..0000000 Binary files a/src/cursor/cursorImages/black/3.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/4.png b/src/cursor/cursorImages/black/4.png deleted file mode 100755 index 7c9d191..0000000 Binary files a/src/cursor/cursorImages/black/4.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/5.png b/src/cursor/cursorImages/black/5.png deleted file mode 100755 index 34b149d..0000000 Binary files a/src/cursor/cursorImages/black/5.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/6.png b/src/cursor/cursorImages/black/6.png deleted file mode 100755 index d118680..0000000 Binary files a/src/cursor/cursorImages/black/6.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/7.png b/src/cursor/cursorImages/black/7.png deleted file mode 100755 index 68ec2dd..0000000 Binary files a/src/cursor/cursorImages/black/7.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/8.png b/src/cursor/cursorImages/black/8.png deleted file mode 100755 index c938fe9..0000000 Binary files a/src/cursor/cursorImages/black/8.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/9.png b/src/cursor/cursorImages/black/9.png deleted file mode 100755 index e5e4f09..0000000 Binary files a/src/cursor/cursorImages/black/9.png and /dev/null differ diff --git a/src/cursor/cursorImages/black/cursorBlack.svg b/src/cursor/cursorImages/black/cursorBlack.svg deleted file mode 100755 index 7c3c9b4..0000000 --- a/src/cursor/cursorImages/black/cursorBlack.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/cursor/cursorImages/black/flash.png b/src/cursor/cursorImages/black/flash.png deleted file mode 100644 index 412cbce..0000000 Binary files a/src/cursor/cursorImages/black/flash.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/0.png b/src/cursor/cursorImages/blue/0.png deleted file mode 100644 index 9535e33..0000000 Binary files a/src/cursor/cursorImages/blue/0.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/1.png b/src/cursor/cursorImages/blue/1.png deleted file mode 100644 index 894e8c4..0000000 Binary files a/src/cursor/cursorImages/blue/1.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/10.png b/src/cursor/cursorImages/blue/10.png deleted file mode 100644 index 8ef30f7..0000000 Binary files a/src/cursor/cursorImages/blue/10.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/2.png b/src/cursor/cursorImages/blue/2.png deleted file mode 100644 index 5dcd4a9..0000000 Binary files a/src/cursor/cursorImages/blue/2.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/3.png b/src/cursor/cursorImages/blue/3.png deleted file mode 100644 index e547688..0000000 Binary files a/src/cursor/cursorImages/blue/3.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/4.png b/src/cursor/cursorImages/blue/4.png deleted file mode 100644 index 0fb1d9d..0000000 Binary files a/src/cursor/cursorImages/blue/4.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/5.png b/src/cursor/cursorImages/blue/5.png deleted file mode 100644 index 6f3b35a..0000000 Binary files a/src/cursor/cursorImages/blue/5.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/6.png b/src/cursor/cursorImages/blue/6.png deleted file mode 100644 index 7ca3eb6..0000000 Binary files a/src/cursor/cursorImages/blue/6.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/7.png b/src/cursor/cursorImages/blue/7.png deleted file mode 100644 index 0a2033b..0000000 Binary files a/src/cursor/cursorImages/blue/7.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/8.png b/src/cursor/cursorImages/blue/8.png deleted file mode 100644 index c75055c..0000000 Binary files a/src/cursor/cursorImages/blue/8.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/9.png b/src/cursor/cursorImages/blue/9.png deleted file mode 100644 index f013e60..0000000 Binary files a/src/cursor/cursorImages/blue/9.png and /dev/null differ diff --git a/src/cursor/cursorImages/blue/cursorBlue.svg b/src/cursor/cursorImages/blue/cursorBlue.svg deleted file mode 100644 index 34c72b0..0000000 --- a/src/cursor/cursorImages/blue/cursorBlue.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/cursor/cursorImages/green/0.png b/src/cursor/cursorImages/green/0.png deleted file mode 100644 index a601813..0000000 Binary files a/src/cursor/cursorImages/green/0.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/1.png b/src/cursor/cursorImages/green/1.png deleted file mode 100644 index a0343a6..0000000 Binary files a/src/cursor/cursorImages/green/1.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/10.png b/src/cursor/cursorImages/green/10.png deleted file mode 100644 index a57da5e..0000000 Binary files a/src/cursor/cursorImages/green/10.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/2.png b/src/cursor/cursorImages/green/2.png deleted file mode 100644 index 3c611a1..0000000 Binary files a/src/cursor/cursorImages/green/2.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/3.png b/src/cursor/cursorImages/green/3.png deleted file mode 100644 index 75169da..0000000 Binary files a/src/cursor/cursorImages/green/3.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/4.png b/src/cursor/cursorImages/green/4.png deleted file mode 100644 index 19b9062..0000000 Binary files a/src/cursor/cursorImages/green/4.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/5.png b/src/cursor/cursorImages/green/5.png deleted file mode 100644 index f0d521c..0000000 Binary files a/src/cursor/cursorImages/green/5.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/6.png b/src/cursor/cursorImages/green/6.png deleted file mode 100644 index 9732994..0000000 Binary files a/src/cursor/cursorImages/green/6.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/7.png b/src/cursor/cursorImages/green/7.png deleted file mode 100644 index 8c77ca7..0000000 Binary files a/src/cursor/cursorImages/green/7.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/8.png b/src/cursor/cursorImages/green/8.png deleted file mode 100644 index a2a97a7..0000000 Binary files a/src/cursor/cursorImages/green/8.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/9.png b/src/cursor/cursorImages/green/9.png deleted file mode 100644 index b950aa1..0000000 Binary files a/src/cursor/cursorImages/green/9.png and /dev/null differ diff --git a/src/cursor/cursorImages/green/cursorGreen.svg b/src/cursor/cursorImages/green/cursorGreen.svg deleted file mode 100644 index 34e8bc6..0000000 --- a/src/cursor/cursorImages/green/cursorGreen.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/cursor/cursorImages/red/0.png b/src/cursor/cursorImages/red/0.png deleted file mode 100644 index 839bc89..0000000 Binary files a/src/cursor/cursorImages/red/0.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/1.png b/src/cursor/cursorImages/red/1.png deleted file mode 100644 index 7124ee3..0000000 Binary files a/src/cursor/cursorImages/red/1.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/10.png b/src/cursor/cursorImages/red/10.png deleted file mode 100644 index e4323c2..0000000 Binary files a/src/cursor/cursorImages/red/10.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/2.png b/src/cursor/cursorImages/red/2.png deleted file mode 100644 index 7df10de..0000000 Binary files a/src/cursor/cursorImages/red/2.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/3.png b/src/cursor/cursorImages/red/3.png deleted file mode 100644 index 3088b82..0000000 Binary files a/src/cursor/cursorImages/red/3.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/4.png b/src/cursor/cursorImages/red/4.png deleted file mode 100644 index 8e7549d..0000000 Binary files a/src/cursor/cursorImages/red/4.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/5.png b/src/cursor/cursorImages/red/5.png deleted file mode 100644 index a18a1a4..0000000 Binary files a/src/cursor/cursorImages/red/5.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/6.png b/src/cursor/cursorImages/red/6.png deleted file mode 100644 index 6a6c2af..0000000 Binary files a/src/cursor/cursorImages/red/6.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/7.png b/src/cursor/cursorImages/red/7.png deleted file mode 100644 index 865f580..0000000 Binary files a/src/cursor/cursorImages/red/7.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/8.png b/src/cursor/cursorImages/red/8.png deleted file mode 100644 index 785a4b1..0000000 Binary files a/src/cursor/cursorImages/red/8.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/9.png b/src/cursor/cursorImages/red/9.png deleted file mode 100644 index e4c9758..0000000 Binary files a/src/cursor/cursorImages/red/9.png and /dev/null differ diff --git a/src/cursor/cursorImages/red/cursorRed.svg b/src/cursor/cursorImages/red/cursorRed.svg deleted file mode 100644 index 54f5fc0..0000000 --- a/src/cursor/cursorImages/red/cursorRed.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/data/themes/default/Vera.ttf b/src/data/themes/default/Vera.ttf deleted file mode 100644 index 58cd6b5..0000000 Binary files a/src/data/themes/default/Vera.ttf and /dev/null differ diff --git a/src/data/themes/default/box.down.png b/src/data/themes/default/box.down.png deleted file mode 100644 index b9e965d..0000000 Binary files a/src/data/themes/default/box.down.png and /dev/null differ diff --git a/src/data/themes/default/box.hover.png b/src/data/themes/default/box.hover.png deleted file mode 100644 index ef3c225..0000000 Binary files a/src/data/themes/default/box.hover.png and /dev/null differ diff --git a/src/data/themes/default/box.normal.png b/src/data/themes/default/box.normal.png deleted file mode 100644 index 90f8d40..0000000 Binary files a/src/data/themes/default/box.normal.png and /dev/null differ diff --git a/src/data/themes/default/box.xcf b/src/data/themes/default/box.xcf deleted file mode 100644 index 960ca8d..0000000 Binary files a/src/data/themes/default/box.xcf and /dev/null differ diff --git a/src/data/themes/default/button.down.tga b/src/data/themes/default/button.down.tga deleted file mode 100644 index 64873c1..0000000 Binary files a/src/data/themes/default/button.down.tga and /dev/null differ diff --git a/src/data/themes/default/button.hover.tga b/src/data/themes/default/button.hover.tga deleted file mode 100644 index 5e5c53a..0000000 Binary files a/src/data/themes/default/button.hover.tga and /dev/null differ diff --git a/src/data/themes/default/button.normal.tga b/src/data/themes/default/button.normal.tga deleted file mode 100644 index e9371c7..0000000 Binary files a/src/data/themes/default/button.normal.tga and /dev/null differ diff --git a/src/data/themes/default/check.png b/src/data/themes/default/check.png deleted file mode 100644 index 4ef58a3..0000000 Binary files a/src/data/themes/default/check.png and /dev/null differ diff --git a/src/data/themes/default/checkbox.off.hover.tga b/src/data/themes/default/checkbox.off.hover.tga deleted file mode 100644 index 9a4d8a8..0000000 Binary files a/src/data/themes/default/checkbox.off.hover.tga and /dev/null differ diff --git a/src/data/themes/default/checkbox.off.normal.tga b/src/data/themes/default/checkbox.off.normal.tga deleted file mode 100644 index de59f19..0000000 Binary files a/src/data/themes/default/checkbox.off.normal.tga and /dev/null differ diff --git a/src/data/themes/default/checkbox.on.hover.tga b/src/data/themes/default/checkbox.on.hover.tga deleted file mode 100644 index 4940c26..0000000 Binary files a/src/data/themes/default/checkbox.on.hover.tga and /dev/null differ diff --git a/src/data/themes/default/checkbox.on.normal.tga b/src/data/themes/default/checkbox.on.normal.tga deleted file mode 100644 index 9cf658e..0000000 Binary files a/src/data/themes/default/checkbox.on.normal.tga and /dev/null differ diff --git a/src/data/themes/default/config.txt b/src/data/themes/default/config.txt deleted file mode 100644 index e4ef48b..0000000 --- a/src/data/themes/default/config.txt +++ /dev/null @@ -1,291 +0,0 @@ -desktop background desktop.png - -input font Vera.ttf 16 -input background input.normal.png -input color #000000 -input:focus background input.focus.png -input padding_left 6 -input padding_right 6 -input padding_top 3 -input padding_bottom 3 - -link font Vera.ttf 24 -link color #0000FF -link:hover color #FF0000 -link:down color #00FF00 - -label font Vera.ttf 16 -label color #000000 - -document font Vera.ttf 16 -document color #000000 -div font Vera.ttf 16 -div color #000000 - -td font Vera.ttf 16 -td color #000000 -th font Vera.ttf 16 -th color #000000 - -h1 font Vera.ttf 24 -h1 color #000000 -h2 font Vera.ttf 20 -h2 color #000000 -h3 font Vera.ttf 16 -h3 color #000000 -h4 font Vera.ttf 14 -h4 color #000000 -h5 font Vera.ttf 12 -h5 color #000000 -h6 font Vera.ttf 10 -h6 color #000000 - -ul font Vera.ttf 16 -ul color #000000 -ol font Vera.ttf 16 -ol color #000000 -li font Vera.ttf 16 -li color #000000 -li padding_left 32 - -pre font mono 16 -pre color #000000 -code font mono 16 -code color #000000 - -checkbox off checkbox.off.normal.tga -checkbox on checkbox.on.normal.tga -checkbox:hover off checkbox.off.hover.tga -checkbox:hover on checkbox.on.hover.tga -checkbox:down off checkbox.off.hover.tga -checkbox:down on checkbox.on.hover.tga - -switch off checkbox.off.normal.tga -switch on checkbox.on.normal.tga -switch:hover off checkbox.off.hover.tga -switch:hover on checkbox.on.hover.tga -switch:down off checkbox.off.hover.tga -switch:down on checkbox.on.hover.tga - -radio off radio.off.normal.tga -radio on radio.on.normal.tga -radio:hover off radio.off.hover.tga -radio:hover on radio.on.hover.tga -radio:down off radio.off.hover.tga -radio:down on radio.on.hover.tga - -button background button.normal.tga -button:hover background button.hover.tga -button:down background button.down.tga -button padding_left 8 -button padding_right 8 -button padding_top 1 -button padding_bottom 1 -button.label font Vera.ttf 16 -button.label color #000000 - -slider background slider.tga -slider bar slider.bar.normal.tga -slider:hover bar slider.bar.hover.tga -slider width 16 -slider height 16 - -hslider background hslider.tga -hslider bar hslider.bar.normal.tga -hslider:hover bar hslider.bar.hover.tga -hslider:down bar hslider.bar.hover.tga -hslider width 16 -hslider height 16 - -vslider background vslider.tga -vslider bar vslider.bar.normal.tga -vslider:hover bar vslider.bar.hover.tga -vslider:down bar vslider.bar.hover.tga -vslider width 16 -vslider height 16 - -xhscrollbar height 16 -xhscrollbar background scroller.slide.h.tga -xhscrollbar bar scroller.slide.bar.normal.tga -xhscrollbar:hover bar scroller.slide.bar.hover.tga - -xvscrollbar width 16 -xvscrollbar background scroller.slide.v.tga -xvscrollbar bar scroller.slide.bar.normal.tga -xvscrollbar:hover bar scroller.slide.bar.hover.tga - -hscrollbar.slider background hslider.tga -hscrollbar.slider bar hslider.bar.normal.tga -hscrollbar.slider:hover bar hslider.bar.hover.tga -hscrollbar.slider:down bar hslider.bar.hover.tga -hscrollbar.slider width 16 -hscrollbar.slider height 16 -hscrollbar minus hslider.left.tga -hscrollbar plus hslider.right.tga - -vscrollbar.slider background vslider.tga -vscrollbar.slider bar vslider.bar.normal.tga -vscrollbar.slider:hover bar vslider.bar.hover.tga -vscrollbar.slider:down bar vslider.bar.hover.tga -vscrollbar.slider width 16 -vscrollbar.slider height 16 -vscrollbar minus vslider.up.tga -vscrollbar plus vslider.down.tga - - -select.selected background select.selected.normal.tga -select.selected:hover background select.selected.hover.tga -select.selected:down background select.selected.down.tga -select.selected padding_left 4 -select.selected padding_right 4 -select.selected padding_top 1 -select.selected padding_bottom 1 -select.arrow background select.arrow.normal.tga -select.arrow:hover background select.arrow.hover.tga -select.arrow:down background select.arrow.down.tga -select.arrow padding_left 1 -select.arrow padding_right 1 - -select.options background select.options.png -select.option background select.option.normal.png -select.option:hover background select.option.hover.png -select.option:down background select.option.hover.png -select.option padding_left 4 -select.option padding_right 4 -select.option padding_top 1 -select.option padding_bottom 1 -#select.option border_top 1 -#select.option border_right 1 -#select.option border_bottom 1 -#select.option border_left 1 - -select.option.label font Vera.ttf 16 -select.option.label color #000000 -select.options padding_left 1 -select.options padding_right 1 -select.options padding_top 1 -select.options padding_bottom 1 -select arrow select.arrow.png - - -dialog background dialog.bar.png -xdialog.bar background dialog.bar.png -dialog.bar padding_left 8 -dialog.bar padding_right 8 -dialog.bar padding_top 2 -dialog.bar padding_bottom 1 -dialog.bar.close image dialog.close.normal.tga -dialog.bar.close:hover image dialog.close.hover.tga -dialog.bar.close:down image dialog.close.down.tga -dialog.main background dialog.png -dialog.main padding_left 8 -dialog.main padding_right 8 -dialog.main padding_top 4 -dialog.main padding_bottom 4 - -keysym font Vera.ttf 16 -keysym background input.normal.png -keysym color #000000 -keysym:focus background input.focus.png -keysym padding_left 6 -keysym padding_right 6 -keysym padding_top 3 -keysym padding_bottom 3 - -tool background tool.normal.tga -tool:hover background tool.hover.tga -tool:down background tool.down.tga -tool padding_left 4 -tool padding_right 4 -tool padding_top 1 -tool padding_bottom 1 -tool.label font Vera.ttf 16 -tool.label color #000000 - -menu background menu.normal.tga -menu:hover background menu.hover.tga -menu:down background menu.down.tga -menu padding_left 6 -menu padding_right 6 -menu padding_top 3 -menu padding_bottom 3 -menu.label font Vera.ttf 16 -menu.label color #000000 - -menu-open background menu.down.tga -menu-open:hover background menu.down.tga -menu-open:down background menu.down.tga -menu-open padding_left 6 -menu-open padding_right 6 -menu-open padding_top 3 -menu-open padding_bottom 3 - -menu.options background select.options.png -menu.option background select.option.normal.png -menu.option:hover background select.option.hover.png -menu.option:down background select.option.hover.png -menu.option padding_left 6 -menu.option padding_right 6 -menu.option padding_top 1 -menu.option padding_bottom 1 -menu.option.label font Vera.ttf 16 -menu.option.label color #000000 -menu.options padding_left 1 -menu.options padding_right 1 -menu.options padding_top 1 -menu.options padding_bottom 1 -menu arrow select.arrow.tga - - -scrollarea.content background #ffffff -scrollarea.content padding_left 1 -scrollarea.content padding_right 1 -scrollarea.content padding_top 1 -scrollarea.content padding_bottom 1 - - -list.item background list.item.normal.png -list.item:hover background list.item.down.png -list.item:down background list.item.down.png -list.item padding_left 4 -list.item padding_right 4 -list.item padding_top 2 -list.item padding_bottom 2 -list.item margin_bottom 1 -list.item align -1 -list.item.label font Vera.ttf 14 -list.item.label color #000000 - -list background list.png -list padding_left 1 -list padding_right 1 -list padding_top 1 -list padding_bottom 1 -list.content background #eeeeee -list.content padding_left 1 -list.content padding_right 1 -list.content padding_top 1 -list.content padding_bottom 1 - -filedialog.folder image filebrowser.folder.png -filedialog.label font Vera.ttf 14 -filedialog.label color #000000 -filedialog.title.label font Vera.ttf 16 -filedialog.title.label color #000000 -filedialog.input font Vera.ttf 14 -filedialog.input background input.normal.png -filedialog.input color #000000 -filedialog.input:focus background input.focus.png -filedialog.input padding_left 6 -filedialog.input padding_right 6 -filedialog.input padding_top 3 -filedialog.input padding_bottom 3 - -dialog.title.label font Vera.ttf 16 -dialog.title.label color #000000 - - -progressbar background progressbar.tga -progressbar bar progressbar.bar.tga -progressbar width 16 -progressbar height 16 diff --git a/src/data/themes/default/console.input.focus.png b/src/data/themes/default/console.input.focus.png deleted file mode 100644 index 819d835..0000000 Binary files a/src/data/themes/default/console.input.focus.png and /dev/null differ diff --git a/src/data/themes/default/console.input.normal.png b/src/data/themes/default/console.input.normal.png deleted file mode 100644 index a14e329..0000000 Binary files a/src/data/themes/default/console.input.normal.png and /dev/null differ diff --git a/src/data/themes/default/console.png b/src/data/themes/default/console.png deleted file mode 100644 index a14e329..0000000 Binary files a/src/data/themes/default/console.png and /dev/null differ diff --git a/src/data/themes/default/desktop.png b/src/data/themes/default/desktop.png deleted file mode 100644 index c83f5cd..0000000 Binary files a/src/data/themes/default/desktop.png and /dev/null differ diff --git a/src/data/themes/default/desktop.xcf b/src/data/themes/default/desktop.xcf deleted file mode 100644 index 2c504ab..0000000 Binary files a/src/data/themes/default/desktop.xcf and /dev/null differ diff --git a/src/data/themes/default/dialog.bar.png b/src/data/themes/default/dialog.bar.png deleted file mode 100644 index e014e04..0000000 Binary files a/src/data/themes/default/dialog.bar.png and /dev/null differ diff --git a/src/data/themes/default/dialog.close.down.tga b/src/data/themes/default/dialog.close.down.tga deleted file mode 100644 index ade4813..0000000 Binary files a/src/data/themes/default/dialog.close.down.tga and /dev/null differ diff --git a/src/data/themes/default/dialog.close.hover.tga b/src/data/themes/default/dialog.close.hover.tga deleted file mode 100644 index 9f36bb7..0000000 Binary files a/src/data/themes/default/dialog.close.hover.tga and /dev/null differ diff --git a/src/data/themes/default/dialog.close.normal.tga b/src/data/themes/default/dialog.close.normal.tga deleted file mode 100644 index ee3a5d4..0000000 Binary files a/src/data/themes/default/dialog.close.normal.tga and /dev/null differ diff --git a/src/data/themes/default/dialog.png b/src/data/themes/default/dialog.png deleted file mode 100644 index 26ae2a6..0000000 Binary files a/src/data/themes/default/dialog.png and /dev/null differ diff --git a/src/data/themes/default/dot.down.png b/src/data/themes/default/dot.down.png deleted file mode 100644 index ab117a7..0000000 Binary files a/src/data/themes/default/dot.down.png and /dev/null differ diff --git a/src/data/themes/default/dot.hover.png b/src/data/themes/default/dot.hover.png deleted file mode 100644 index 090f07d..0000000 Binary files a/src/data/themes/default/dot.hover.png and /dev/null differ diff --git a/src/data/themes/default/dot.normal.png b/src/data/themes/default/dot.normal.png deleted file mode 100644 index 55bd736..0000000 Binary files a/src/data/themes/default/dot.normal.png and /dev/null differ diff --git a/src/data/themes/default/dot.xcf b/src/data/themes/default/dot.xcf deleted file mode 100644 index 3100750..0000000 Binary files a/src/data/themes/default/dot.xcf and /dev/null differ diff --git a/src/data/themes/default/down.png b/src/data/themes/default/down.png deleted file mode 100644 index 7532249..0000000 Binary files a/src/data/themes/default/down.png and /dev/null differ diff --git a/src/data/themes/default/filebrowser.folder.png b/src/data/themes/default/filebrowser.folder.png deleted file mode 100644 index 4a3bd2c..0000000 Binary files a/src/data/themes/default/filebrowser.folder.png and /dev/null differ diff --git a/src/data/themes/default/generate.py b/src/data/themes/default/generate.py deleted file mode 100644 index a161556..0000000 --- a/src/data/themes/default/generate.py +++ /dev/null @@ -1,98 +0,0 @@ -import pygame -from pygame.locals import * -pygame.display.init() -pygame.display.set_mode((80,80),32) - -def prep(name): - fname = name+".png" - img = pygame.image.load(fname) - w,h = img.get_width()/2,img.get_height()/2 - - out = pygame.Surface((w*3,h*3),SWSURFACE|SRCALPHA,32) - out.fill((0,0,0,0)) - out.blit(img.subsurface(0,0,w,h),(0,0)) - out.blit(img.subsurface(w,0,w,h),(w*2,0)) - out.blit(img.subsurface(0,h,w,h),(0,h*2)) - out.blit(img.subsurface(w,h,w,h),(w*2,h*2)) - for i in range(0,w): - img = out.subsurface((w-1,0,1,h*3)).convert_alpha() - out.blit(img,(w+i,0)) - for i in range(0,h): - img = out.subsurface((0,h-1,w*3,1)).convert_alpha() - out.blit(img,(0,h+i)) - - return out,w,h - -todo = [ - ('button.normal','dot.normal',None,3,3,'789456123'), - ('button.hover','dot.hover',None,3,3,'789456123'), - ('button.down','dot.down',None,3,3,'789456123'), - - ('checkbox.off.normal','box.normal',None,2,2,'7913'), - ('checkbox.on.normal','box.down','check',2,2,'7913'), - ('checkbox.off.hover','box.hover',None,2,2,'7913'), - ('checkbox.on.hover','box.hover','check',2,2,'7913'), - - ('radio.off.normal','dot.normal',None,2,2,'7913'), - ('radio.on.normal','dot.down','radio',2,2,'7913'), - ('radio.off.hover','dot.hover',None,2,2,'7913'), - ('radio.on.hover','dot.hover','radio',2,2,'7913'), - - ('tool.normal','box.normal',None,3,3,'789456123'), - ('tool.hover','box.hover',None,3,3,'789456123'), - ('tool.down','box.down',None,3,3,'789456123'), - - ('hslider','idot.normal',None,3,3,'789456123'), - ('hslider.bar.normal','dot.normal',None,3,3,'789456123'), - ('hslider.bar.hover','dot.hover',None,3,3,'789456123'), - ('hslider.left','sbox.normal','left',2,2,'7913'), - ('hslider.right','sbox.normal','right',2,2,'7913'), - - - ('vslider','idot.normal',None,3,3,'789456123'), - ('vslider.bar.normal','vdot.normal',None,3,3,'789456123'), - ('vslider.bar.hover','vdot.hover',None,3,3,'789456123'), - ('vslider.up','vsbox.normal','up',2,2,'7913'), - ('vslider.down','vsbox.normal','down',2,2,'7913'), - - ('dialog.close.normal','rdot.hover',None,2,2,'7913'), - ('dialog.close.hover','rdot.hover','x',2,2,'7913'), - ('dialog.close.down','rdot.down','x',2,2,'7913'), - - ('menu.normal','desktop',None,1,1,'7'), - ('menu.hover','box.normal',None,3,3,'789456123'), - ('menu.down','box.down',None,3,3,'789456123'), - - ('select.selected.normal','box.normal',None,3,3,'788455122'), - ('select.selected.hover','box.hover',None,3,3,'788455122'), - ('select.selected.down','box.down',None,3,3,'788455122'), - - ('select.arrow.normal','box.hover',None,3,3,'889556223'), - ('select.arrow.hover','box.hover',None,3,3,'889556223'), - ('select.arrow.down','box.down',None,3,3,'889556223'), - - ('progressbar','sbox.normal',None,3,3,'789456123'), - ('progressbar.bar','box.hover',None,3,3,'789456123'), - ] - -for fname,img,over,ww,hh,s in todo: - print fname - img,w,h = prep(img) - out = pygame.Surface((ww*w,hh*h),SWSURFACE|SRCALPHA,32) - out.fill((0,0,0,0)) - n = 0 - for y in range(0,hh): - for x in range(0,ww): - c = int(s[n]) - xx,yy = (c-1)%3,2-(c-1)/3 - out.blit(img.subsurface((xx*w,yy*h,w,h)),(x*w,y*h)) - n += 1 - if over != None: - over = pygame.image.load(over+".png") - out.blit(over,(0,0)) - pygame.image.save(out,fname+".tga") - - - - - diff --git a/src/data/themes/default/hslider.bar.hover.tga b/src/data/themes/default/hslider.bar.hover.tga deleted file mode 100644 index 5e5c53a..0000000 Binary files a/src/data/themes/default/hslider.bar.hover.tga and /dev/null differ diff --git a/src/data/themes/default/hslider.bar.normal.tga b/src/data/themes/default/hslider.bar.normal.tga deleted file mode 100644 index e9371c7..0000000 Binary files a/src/data/themes/default/hslider.bar.normal.tga and /dev/null differ diff --git a/src/data/themes/default/hslider.left.tga b/src/data/themes/default/hslider.left.tga deleted file mode 100644 index 2fe406c..0000000 Binary files a/src/data/themes/default/hslider.left.tga and /dev/null differ diff --git a/src/data/themes/default/hslider.right.tga b/src/data/themes/default/hslider.right.tga deleted file mode 100644 index 86a9ca5..0000000 Binary files a/src/data/themes/default/hslider.right.tga and /dev/null differ diff --git a/src/data/themes/default/hslider.tga b/src/data/themes/default/hslider.tga deleted file mode 100644 index ff3b4b2..0000000 Binary files a/src/data/themes/default/hslider.tga and /dev/null differ diff --git a/src/data/themes/default/idot.normal.png b/src/data/themes/default/idot.normal.png deleted file mode 100644 index 4e22195..0000000 Binary files a/src/data/themes/default/idot.normal.png and /dev/null differ diff --git a/src/data/themes/default/input.focus.png b/src/data/themes/default/input.focus.png deleted file mode 100644 index 477a826..0000000 Binary files a/src/data/themes/default/input.focus.png and /dev/null differ diff --git a/src/data/themes/default/input.normal.png b/src/data/themes/default/input.normal.png deleted file mode 100644 index 8519a98..0000000 Binary files a/src/data/themes/default/input.normal.png and /dev/null differ diff --git a/src/data/themes/default/left.png b/src/data/themes/default/left.png deleted file mode 100644 index b965666..0000000 Binary files a/src/data/themes/default/left.png and /dev/null differ diff --git a/src/data/themes/default/list.item.down.png b/src/data/themes/default/list.item.down.png deleted file mode 100644 index fd9dc21..0000000 Binary files a/src/data/themes/default/list.item.down.png and /dev/null differ diff --git a/src/data/themes/default/list.item.hover.png b/src/data/themes/default/list.item.hover.png deleted file mode 100644 index 627790d..0000000 Binary files a/src/data/themes/default/list.item.hover.png and /dev/null differ diff --git a/src/data/themes/default/list.item.normal.png b/src/data/themes/default/list.item.normal.png deleted file mode 100644 index 627790d..0000000 Binary files a/src/data/themes/default/list.item.normal.png and /dev/null differ diff --git a/src/data/themes/default/list.png b/src/data/themes/default/list.png deleted file mode 100644 index 99ad5bc..0000000 Binary files a/src/data/themes/default/list.png and /dev/null differ diff --git a/src/data/themes/default/listitem.down.tga b/src/data/themes/default/listitem.down.tga deleted file mode 100644 index 13e2e57..0000000 Binary files a/src/data/themes/default/listitem.down.tga and /dev/null differ diff --git a/src/data/themes/default/listitem.hover.tga b/src/data/themes/default/listitem.hover.tga deleted file mode 100644 index 8bdf60a..0000000 Binary files a/src/data/themes/default/listitem.hover.tga and /dev/null differ diff --git a/src/data/themes/default/listitem.normal.tga b/src/data/themes/default/listitem.normal.tga deleted file mode 100644 index a2994aa..0000000 Binary files a/src/data/themes/default/listitem.normal.tga and /dev/null differ diff --git a/src/data/themes/default/menu.down.tga b/src/data/themes/default/menu.down.tga deleted file mode 100644 index f89d4b4..0000000 Binary files a/src/data/themes/default/menu.down.tga and /dev/null differ diff --git a/src/data/themes/default/menu.hover.tga b/src/data/themes/default/menu.hover.tga deleted file mode 100644 index b304b87..0000000 Binary files a/src/data/themes/default/menu.hover.tga and /dev/null differ diff --git a/src/data/themes/default/menu.normal.tga b/src/data/themes/default/menu.normal.tga deleted file mode 100644 index d3eb2d0..0000000 Binary files a/src/data/themes/default/menu.normal.tga and /dev/null differ diff --git a/src/data/themes/default/notes.txt b/src/data/themes/default/notes.txt deleted file mode 100644 index f6541e4..0000000 --- a/src/data/themes/default/notes.txt +++ /dev/null @@ -1,8 +0,0 @@ -dot and box.xcf: - -color -170 - -.down -.hover +64 brightness -.normal, grayscale +127 brightness, +48 contrast - diff --git a/src/data/themes/default/out.tga b/src/data/themes/default/out.tga deleted file mode 100644 index 7ed46cc..0000000 Binary files a/src/data/themes/default/out.tga and /dev/null differ diff --git a/src/data/themes/default/progressbar.bar.tga b/src/data/themes/default/progressbar.bar.tga deleted file mode 100644 index 184ae9c..0000000 Binary files a/src/data/themes/default/progressbar.bar.tga and /dev/null differ diff --git a/src/data/themes/default/progressbar.tga b/src/data/themes/default/progressbar.tga deleted file mode 100644 index d459763..0000000 Binary files a/src/data/themes/default/progressbar.tga and /dev/null differ diff --git a/src/data/themes/default/radio.off.hover.tga b/src/data/themes/default/radio.off.hover.tga deleted file mode 100644 index 6b0f737..0000000 Binary files a/src/data/themes/default/radio.off.hover.tga and /dev/null differ diff --git a/src/data/themes/default/radio.off.normal.tga b/src/data/themes/default/radio.off.normal.tga deleted file mode 100644 index 3da51d8..0000000 Binary files a/src/data/themes/default/radio.off.normal.tga and /dev/null differ diff --git a/src/data/themes/default/radio.on.hover.tga b/src/data/themes/default/radio.on.hover.tga deleted file mode 100644 index d26764b..0000000 Binary files a/src/data/themes/default/radio.on.hover.tga and /dev/null differ diff --git a/src/data/themes/default/radio.on.normal.tga b/src/data/themes/default/radio.on.normal.tga deleted file mode 100644 index 42515fe..0000000 Binary files a/src/data/themes/default/radio.on.normal.tga and /dev/null differ diff --git a/src/data/themes/default/radio.png b/src/data/themes/default/radio.png deleted file mode 100644 index 7596f48..0000000 Binary files a/src/data/themes/default/radio.png and /dev/null differ diff --git a/src/data/themes/default/rdot.down.png b/src/data/themes/default/rdot.down.png deleted file mode 100644 index 35cd4fe..0000000 Binary files a/src/data/themes/default/rdot.down.png and /dev/null differ diff --git a/src/data/themes/default/rdot.hover.png b/src/data/themes/default/rdot.hover.png deleted file mode 100644 index 5cd77a2..0000000 Binary files a/src/data/themes/default/rdot.hover.png and /dev/null differ diff --git a/src/data/themes/default/rdot.normal.png b/src/data/themes/default/rdot.normal.png deleted file mode 100644 index 636a207..0000000 Binary files a/src/data/themes/default/rdot.normal.png and /dev/null differ diff --git a/src/data/themes/default/right.png b/src/data/themes/default/right.png deleted file mode 100644 index 613779e..0000000 Binary files a/src/data/themes/default/right.png and /dev/null differ diff --git a/src/data/themes/default/sbox.normal.png b/src/data/themes/default/sbox.normal.png deleted file mode 100644 index 00be882..0000000 Binary files a/src/data/themes/default/sbox.normal.png and /dev/null differ diff --git a/src/data/themes/default/scroller.slide.bar.hover.tga b/src/data/themes/default/scroller.slide.bar.hover.tga deleted file mode 100644 index d0b85a9..0000000 Binary files a/src/data/themes/default/scroller.slide.bar.hover.tga and /dev/null differ diff --git a/src/data/themes/default/scroller.slide.bar.normal.tga b/src/data/themes/default/scroller.slide.bar.normal.tga deleted file mode 100644 index 84ff6bb..0000000 Binary files a/src/data/themes/default/scroller.slide.bar.normal.tga and /dev/null differ diff --git a/src/data/themes/default/scroller.slide.h.tga b/src/data/themes/default/scroller.slide.h.tga deleted file mode 100644 index 0281567..0000000 Binary files a/src/data/themes/default/scroller.slide.h.tga and /dev/null differ diff --git a/src/data/themes/default/scroller.slide.v.tga b/src/data/themes/default/scroller.slide.v.tga deleted file mode 100644 index cbaa875..0000000 Binary files a/src/data/themes/default/scroller.slide.v.tga and /dev/null differ diff --git a/src/data/themes/default/select.arrow.down.tga b/src/data/themes/default/select.arrow.down.tga deleted file mode 100644 index d721002..0000000 Binary files a/src/data/themes/default/select.arrow.down.tga and /dev/null differ diff --git a/src/data/themes/default/select.arrow.hover.tga b/src/data/themes/default/select.arrow.hover.tga deleted file mode 100644 index 162d8e7..0000000 Binary files a/src/data/themes/default/select.arrow.hover.tga and /dev/null differ diff --git a/src/data/themes/default/select.arrow.normal.tga b/src/data/themes/default/select.arrow.normal.tga deleted file mode 100644 index 162d8e7..0000000 Binary files a/src/data/themes/default/select.arrow.normal.tga and /dev/null differ diff --git a/src/data/themes/default/select.arrow.png b/src/data/themes/default/select.arrow.png deleted file mode 100644 index 19de760..0000000 Binary files a/src/data/themes/default/select.arrow.png and /dev/null differ diff --git a/src/data/themes/default/select.option.hover.png b/src/data/themes/default/select.option.hover.png deleted file mode 100644 index fd9dc21..0000000 Binary files a/src/data/themes/default/select.option.hover.png and /dev/null differ diff --git a/src/data/themes/default/select.option.normal.png b/src/data/themes/default/select.option.normal.png deleted file mode 100644 index 627790d..0000000 Binary files a/src/data/themes/default/select.option.normal.png and /dev/null differ diff --git a/src/data/themes/default/select.options.png b/src/data/themes/default/select.options.png deleted file mode 100644 index 477a826..0000000 Binary files a/src/data/themes/default/select.options.png and /dev/null differ diff --git a/src/data/themes/default/select.selected.down.tga b/src/data/themes/default/select.selected.down.tga deleted file mode 100644 index 7d952a0..0000000 Binary files a/src/data/themes/default/select.selected.down.tga and /dev/null differ diff --git a/src/data/themes/default/select.selected.hover.tga b/src/data/themes/default/select.selected.hover.tga deleted file mode 100644 index 91dd794..0000000 Binary files a/src/data/themes/default/select.selected.hover.tga and /dev/null differ diff --git a/src/data/themes/default/select.selected.normal.tga b/src/data/themes/default/select.selected.normal.tga deleted file mode 100644 index 54b8927..0000000 Binary files a/src/data/themes/default/select.selected.normal.tga and /dev/null differ diff --git a/src/data/themes/default/slider.bar.hover.tga b/src/data/themes/default/slider.bar.hover.tga deleted file mode 100644 index 5e5c53a..0000000 Binary files a/src/data/themes/default/slider.bar.hover.tga and /dev/null differ diff --git a/src/data/themes/default/slider.bar.normal.tga b/src/data/themes/default/slider.bar.normal.tga deleted file mode 100644 index e9371c7..0000000 Binary files a/src/data/themes/default/slider.bar.normal.tga and /dev/null differ diff --git a/src/data/themes/default/slider.tga b/src/data/themes/default/slider.tga deleted file mode 100644 index ff3b4b2..0000000 Binary files a/src/data/themes/default/slider.tga and /dev/null differ diff --git a/src/data/themes/default/tool.down.tga b/src/data/themes/default/tool.down.tga deleted file mode 100644 index f89d4b4..0000000 Binary files a/src/data/themes/default/tool.down.tga and /dev/null differ diff --git a/src/data/themes/default/tool.hover.tga b/src/data/themes/default/tool.hover.tga deleted file mode 100644 index 184ae9c..0000000 Binary files a/src/data/themes/default/tool.hover.tga and /dev/null differ diff --git a/src/data/themes/default/tool.normal.tga b/src/data/themes/default/tool.normal.tga deleted file mode 100644 index b304b87..0000000 Binary files a/src/data/themes/default/tool.normal.tga and /dev/null differ diff --git a/src/data/themes/default/up.png b/src/data/themes/default/up.png deleted file mode 100644 index d42c324..0000000 Binary files a/src/data/themes/default/up.png and /dev/null differ diff --git a/src/data/themes/default/vbox.normal.png b/src/data/themes/default/vbox.normal.png deleted file mode 100644 index 9229c87..0000000 Binary files a/src/data/themes/default/vbox.normal.png and /dev/null differ diff --git a/src/data/themes/default/vdot.down.png b/src/data/themes/default/vdot.down.png deleted file mode 100644 index e9e781e..0000000 Binary files a/src/data/themes/default/vdot.down.png and /dev/null differ diff --git a/src/data/themes/default/vdot.hover.png b/src/data/themes/default/vdot.hover.png deleted file mode 100644 index 74e043b..0000000 Binary files a/src/data/themes/default/vdot.hover.png and /dev/null differ diff --git a/src/data/themes/default/vdot.normal.png b/src/data/themes/default/vdot.normal.png deleted file mode 100644 index f64089b..0000000 Binary files a/src/data/themes/default/vdot.normal.png and /dev/null differ diff --git a/src/data/themes/default/vsbox.normal.png b/src/data/themes/default/vsbox.normal.png deleted file mode 100644 index 2deca17..0000000 Binary files a/src/data/themes/default/vsbox.normal.png and /dev/null differ diff --git a/src/data/themes/default/vslider.bar.hover.tga b/src/data/themes/default/vslider.bar.hover.tga deleted file mode 100644 index 0a3f70a..0000000 Binary files a/src/data/themes/default/vslider.bar.hover.tga and /dev/null differ diff --git a/src/data/themes/default/vslider.bar.normal.tga b/src/data/themes/default/vslider.bar.normal.tga deleted file mode 100644 index 07ee06e..0000000 Binary files a/src/data/themes/default/vslider.bar.normal.tga and /dev/null differ diff --git a/src/data/themes/default/vslider.down.tga b/src/data/themes/default/vslider.down.tga deleted file mode 100644 index 61c75a6..0000000 Binary files a/src/data/themes/default/vslider.down.tga and /dev/null differ diff --git a/src/data/themes/default/vslider.tga b/src/data/themes/default/vslider.tga deleted file mode 100644 index ff3b4b2..0000000 Binary files a/src/data/themes/default/vslider.tga and /dev/null differ diff --git a/src/data/themes/default/vslider.up.tga b/src/data/themes/default/vslider.up.tga deleted file mode 100644 index ce73c30..0000000 Binary files a/src/data/themes/default/vslider.up.tga and /dev/null differ diff --git a/src/data/themes/default/x.png b/src/data/themes/default/x.png deleted file mode 100644 index d00f36b..0000000 Binary files a/src/data/themes/default/x.png and /dev/null differ diff --git a/src/data/themes/gray/Vera.ttf b/src/data/themes/gray/Vera.ttf deleted file mode 100644 index 58cd6b5..0000000 Binary files a/src/data/themes/gray/Vera.ttf and /dev/null differ diff --git a/src/data/themes/gray/box.down.png b/src/data/themes/gray/box.down.png deleted file mode 100644 index 0009fe7..0000000 Binary files a/src/data/themes/gray/box.down.png and /dev/null differ diff --git a/src/data/themes/gray/box.normal.png b/src/data/themes/gray/box.normal.png deleted file mode 100644 index e4599d9..0000000 Binary files a/src/data/themes/gray/box.normal.png and /dev/null differ diff --git a/src/data/themes/gray/button.down.png b/src/data/themes/gray/button.down.png deleted file mode 100644 index efb67bc..0000000 Binary files a/src/data/themes/gray/button.down.png and /dev/null differ diff --git a/src/data/themes/gray/button.normal.png b/src/data/themes/gray/button.normal.png deleted file mode 100644 index 7393150..0000000 Binary files a/src/data/themes/gray/button.normal.png and /dev/null differ diff --git a/src/data/themes/gray/checkbox.off.down.png b/src/data/themes/gray/checkbox.off.down.png deleted file mode 100644 index 656f779..0000000 Binary files a/src/data/themes/gray/checkbox.off.down.png and /dev/null differ diff --git a/src/data/themes/gray/checkbox.off.normal.png b/src/data/themes/gray/checkbox.off.normal.png deleted file mode 100644 index 70943f1..0000000 Binary files a/src/data/themes/gray/checkbox.off.normal.png and /dev/null differ diff --git a/src/data/themes/gray/checkbox.on.down.png b/src/data/themes/gray/checkbox.on.down.png deleted file mode 100644 index fa61a2b..0000000 Binary files a/src/data/themes/gray/checkbox.on.down.png and /dev/null differ diff --git a/src/data/themes/gray/checkbox.on.normal.png b/src/data/themes/gray/checkbox.on.normal.png deleted file mode 100644 index 5ee17b1..0000000 Binary files a/src/data/themes/gray/checkbox.on.normal.png and /dev/null differ diff --git a/src/data/themes/gray/config.txt b/src/data/themes/gray/config.txt deleted file mode 100644 index 0ea2006..0000000 --- a/src/data/themes/gray/config.txt +++ /dev/null @@ -1,244 +0,0 @@ -desktop background desktop.png - -input font Vera.ttf 16 -input background input.normal.png -input color #000000 -input:focus background input.focus.png -input padding_left 6 -input padding_right 6 -input padding_top 3 -input padding_bottom 3 - -label font Vera.ttf 16 -label color #000000 - -document font Vera.ttf 16 -document color #000000 -div font Vera.ttf 16 -div color #000000 - -td font Vera.ttf 16 -td color #000000 -th font Vera.ttf 16 -th color #000000 - -h1 font Vera.ttf 24 -h1 color #000000 -h2 font Vera.ttf 20 -h2 color #000000 -h3 font Vera.ttf 16 -h3 color #000000 -h4 font Vera.ttf 14 -h4 color #000000 -h5 font Vera.ttf 12 -h5 color #000000 -h6 font Vera.ttf 10 -h6 color #000000 - -ul font Vera.ttf 16 -ul color #000000 -ol font Vera.ttf 16 -ol color #000000 -li font Vera.ttf 16 -li color #000000 -li padding_left 32 - -pre font mono 16 -pre color #000000 -code font mono 16 -code color #000000 - -checkbox off checkbox.off.normal.png -checkbox on checkbox.on.normal.png -checkbox:down off checkbox.off.down.png -checkbox:down on checkbox.on.down.png - -switch off checkbox.off.normal.png -switch on checkbox.on.normal.png -switch:down off checkbox.off.down.png -switch:down on checkbox.on.down.png - -radio off radio.off.normal.png -radio on radio.on.normal.png -radio:down off radio.off.down.png -radio:down on radio.on.down.png - -button background button.normal.png -button:down background button.down.png -button padding_left 8 -button padding_right 8 -button padding_top 1 -button padding_bottom 1 -button.label font Vera.ttf 16 -button.label color #000000 - -slider background slider.png -slider bar slider.bar.normal.png -slider:down bar slider.bar.down.png -slider width 16 -slider height 16 - -hslider background slider.png -hslider bar slider.bar.normal.png -hslider:down bar slider.bar.down.png -hslider width 16 -hslider height 16 - -vslider background slider.png -vslider bar slider.bar.normal.png -vslider:down bar slider.bar.down.png -vslider width 16 -vslider height 16 - -select.selected background select.selected.normal.png -#select.selected:down background select.selected.down.png -select.selected padding_left 4 -select.selected padding_right 4 -select.selected padding_top 1 -select.selected padding_bottom 1 -select.arrow background select.arrow.normal.png -select.arrow:down background select.arrow.down.png -select.arrow padding_left 1 -select.arrow padding_right 1 - -select.options background select.options.png -select.option background select.option.normal.png -#select.option:hover background select.option.hover.png -select.option padding_left 4 -select.option padding_right 4 -select.option padding_top 1 -select.option padding_bottom 1 -#select.option border_top 1 -#select.option border_right 1 -#select.option border_bottom 1 -#select.option border_left 1 - -select.option.label font Vera.ttf 16 -select.option.label color #000000 -select.options padding_left 1 -select.options padding_right 1 -select.options padding_top 1 -select.options padding_bottom 1 -select arrow select.arrow.png - - -dialog.bar background dialog.bar.png -dialog.bar padding_left 8 -dialog.bar padding_right 8 -dialog.bar padding_top 2 -dialog.bar padding_bottom 1 -dialog.bar.close image dialog.close.normal.png -dialog.bar.close:down image dialog.close.down.png -dialog.main background dialog.png -dialog.main padding_left 8 -dialog.main padding_right 8 -dialog.main padding_top 4 -dialog.main padding_bottom 4 - -keysym font helvetica 16 -keysym background input.normal.png -keysym color #000000 -keysym:focus background input.focus.png -keysym padding_left 6 -keysym padding_right 6 -keysym padding_top 3 -keysym padding_bottom 3 - -tool background tool.normal.png -tool:down background tool.down.png -tool padding_left 4 -tool padding_right 4 -tool padding_top 1 -tool padding_bottom 1 -tool.label font Vera.ttf 16 -tool.label color #000000 - -menu background menu.normal.png -menu:hover background menu.hover.png -menu:down background menu.down.png -menu padding_left 6 -menu padding_right 6 -menu padding_top 3 -menu padding_bottom 3 -menu.label font Vera.ttf 16 -menu.label color #000000 - -menu-open background menu.down.png -menu-open:down background menu.down.png -menu-open padding_left 6 -menu-open padding_right 6 -menu-open padding_top 3 -menu-open padding_bottom 3 - -menu.options background select.options.png -menu.option background menu.option.normal.png -menu.option:hover background menu.option.hover.png -#menu.option.label color #FF0000 -menu.option padding_left 6 -menu.option padding_right 6 -menu.option padding_top 1 -menu.option padding_bottom 1 -menu.option.label font Vera.ttf 16 -menu.option.label color #000000 -menu.options padding_left 1 -menu.options padding_right 1 -menu.options padding_top 1 -menu.options padding_bottom 1 -menu arrow select.arrow.png - - -scrollarea.content background #ffffff -scrollarea.content padding_left 1 -scrollarea.content padding_right 1 -scrollarea.content padding_top 1 -scrollarea.content padding_bottom 1 -hscrollbar height 15 -##hscrollbar background scroller.slide.h.png -hscrollbar background slider.png -##hscrollbar bar scroller.slide.bar.normal.png -hscrollbar bar slider.bar.normal.png -##hscrollbar:down bar scroller.slide.bar.down.png -vscrollbar width 15 -##vscrollbar background scroller.slide.v.png -vscrollbar background slider.png -##vscrollbar bar scroller.slide.bar.normal.png -vscrollbar bar slider.bar.normal.png -##vscrollbar:down bar scroller.slide.bar.down.png - -list.item background list.item.normal.png -#list.item:down background list.item.down.png -list.item padding_left 4 -list.item padding_right 4 -list.item padding_top 2 -list.item padding_bottom 2 -list.item margin_bottom 1 -list.item align -1 -list.item.label font Vera.ttf 14 -list.item.label color #000000 - -list background list.png -list padding_left 1 -list padding_right 1 -list padding_top 1 -list padding_bottom 1 -list.content background #eeeeee -list.content padding_left 1 -list.content padding_right 1 -list.content padding_top 1 -list.content padding_bottom 1 - -filedialog.folder image filebrowser.folder.png -filedialog.label font Vera.ttf 14 -filedialog.label color #000000 -filedialog.title.label font Vera.ttf 16 -filedialog.title.label color #000000 -filedialog.input font Vera.ttf 14 -filedialog.input background input.normal.png -filedialog.input color #000000 -filedialog.input:focus background input.focus.png -filedialog.input padding_left 6 -filedialog.input padding_right 6 -filedialog.input padding_top 3 -filedialog.input padding_bottom 3 - - diff --git a/src/data/themes/gray/console.input.focus.png b/src/data/themes/gray/console.input.focus.png deleted file mode 100644 index 819d835..0000000 Binary files a/src/data/themes/gray/console.input.focus.png and /dev/null differ diff --git a/src/data/themes/gray/console.input.normal.png b/src/data/themes/gray/console.input.normal.png deleted file mode 100644 index a14e329..0000000 Binary files a/src/data/themes/gray/console.input.normal.png and /dev/null differ diff --git a/src/data/themes/gray/console.png b/src/data/themes/gray/console.png deleted file mode 100644 index a14e329..0000000 Binary files a/src/data/themes/gray/console.png and /dev/null differ diff --git a/src/data/themes/gray/desktop.png b/src/data/themes/gray/desktop.png deleted file mode 100644 index 73ac803..0000000 Binary files a/src/data/themes/gray/desktop.png and /dev/null differ diff --git a/src/data/themes/gray/dialog.bar.png b/src/data/themes/gray/dialog.bar.png deleted file mode 100644 index ffac15d..0000000 Binary files a/src/data/themes/gray/dialog.bar.png and /dev/null differ diff --git a/src/data/themes/gray/dialog.close.down.png b/src/data/themes/gray/dialog.close.down.png deleted file mode 100644 index cde6e96..0000000 Binary files a/src/data/themes/gray/dialog.close.down.png and /dev/null differ diff --git a/src/data/themes/gray/dialog.close.normal.png b/src/data/themes/gray/dialog.close.normal.png deleted file mode 100644 index 73dc9e4..0000000 Binary files a/src/data/themes/gray/dialog.close.normal.png and /dev/null differ diff --git a/src/data/themes/gray/dialog.png b/src/data/themes/gray/dialog.png deleted file mode 100644 index 1308b9c..0000000 Binary files a/src/data/themes/gray/dialog.png and /dev/null differ diff --git a/src/data/themes/gray/filebrowser.folder.png b/src/data/themes/gray/filebrowser.folder.png deleted file mode 100644 index 4a3bd2c..0000000 Binary files a/src/data/themes/gray/filebrowser.folder.png and /dev/null differ diff --git a/src/data/themes/gray/input.focus.png b/src/data/themes/gray/input.focus.png deleted file mode 100644 index 477a826..0000000 Binary files a/src/data/themes/gray/input.focus.png and /dev/null differ diff --git a/src/data/themes/gray/input.normal.png b/src/data/themes/gray/input.normal.png deleted file mode 100644 index 8519a98..0000000 Binary files a/src/data/themes/gray/input.normal.png and /dev/null differ diff --git a/src/data/themes/gray/list.item.normal.png b/src/data/themes/gray/list.item.normal.png deleted file mode 100644 index 627790d..0000000 Binary files a/src/data/themes/gray/list.item.normal.png and /dev/null differ diff --git a/src/data/themes/gray/list.png b/src/data/themes/gray/list.png deleted file mode 100644 index 99ad5bc..0000000 Binary files a/src/data/themes/gray/list.png and /dev/null differ diff --git a/src/data/themes/gray/menu.down.png b/src/data/themes/gray/menu.down.png deleted file mode 100644 index 3555053..0000000 Binary files a/src/data/themes/gray/menu.down.png and /dev/null differ diff --git a/src/data/themes/gray/menu.hover.png b/src/data/themes/gray/menu.hover.png deleted file mode 100644 index f4b2a6a..0000000 Binary files a/src/data/themes/gray/menu.hover.png and /dev/null differ diff --git a/src/data/themes/gray/menu.normal.png b/src/data/themes/gray/menu.normal.png deleted file mode 100644 index 9a7aca6..0000000 Binary files a/src/data/themes/gray/menu.normal.png and /dev/null differ diff --git a/src/data/themes/gray/menu.option.hover.png b/src/data/themes/gray/menu.option.hover.png deleted file mode 100644 index 8ae05f3..0000000 Binary files a/src/data/themes/gray/menu.option.hover.png and /dev/null differ diff --git a/src/data/themes/gray/menu.option.normal.png b/src/data/themes/gray/menu.option.normal.png deleted file mode 100644 index 394200b..0000000 Binary files a/src/data/themes/gray/menu.option.normal.png and /dev/null differ diff --git a/src/data/themes/gray/radio.off.down.png b/src/data/themes/gray/radio.off.down.png deleted file mode 100644 index 5a6e9a3..0000000 Binary files a/src/data/themes/gray/radio.off.down.png and /dev/null differ diff --git a/src/data/themes/gray/radio.off.normal.png b/src/data/themes/gray/radio.off.normal.png deleted file mode 100644 index 4a57f1f..0000000 Binary files a/src/data/themes/gray/radio.off.normal.png and /dev/null differ diff --git a/src/data/themes/gray/radio.on.down.png b/src/data/themes/gray/radio.on.down.png deleted file mode 100644 index 483bd66..0000000 Binary files a/src/data/themes/gray/radio.on.down.png and /dev/null differ diff --git a/src/data/themes/gray/radio.on.normal.png b/src/data/themes/gray/radio.on.normal.png deleted file mode 100644 index 43b380b..0000000 Binary files a/src/data/themes/gray/radio.on.normal.png and /dev/null differ diff --git a/src/data/themes/gray/select.arrow.down.png b/src/data/themes/gray/select.arrow.down.png deleted file mode 100644 index 9ef850e..0000000 Binary files a/src/data/themes/gray/select.arrow.down.png and /dev/null differ diff --git a/src/data/themes/gray/select.arrow.normal.png b/src/data/themes/gray/select.arrow.normal.png deleted file mode 100644 index fde6e42..0000000 Binary files a/src/data/themes/gray/select.arrow.normal.png and /dev/null differ diff --git a/src/data/themes/gray/select.arrow.png b/src/data/themes/gray/select.arrow.png deleted file mode 100644 index 19de760..0000000 Binary files a/src/data/themes/gray/select.arrow.png and /dev/null differ diff --git a/src/data/themes/gray/select.option.normal.png b/src/data/themes/gray/select.option.normal.png deleted file mode 100644 index 627790d..0000000 Binary files a/src/data/themes/gray/select.option.normal.png and /dev/null differ diff --git a/src/data/themes/gray/select.options.png b/src/data/themes/gray/select.options.png deleted file mode 100644 index 477a826..0000000 Binary files a/src/data/themes/gray/select.options.png and /dev/null differ diff --git a/src/data/themes/gray/select.selected.normal.png b/src/data/themes/gray/select.selected.normal.png deleted file mode 100644 index e1463f8..0000000 Binary files a/src/data/themes/gray/select.selected.normal.png and /dev/null differ diff --git a/src/data/themes/gray/slider.bar.normal.png b/src/data/themes/gray/slider.bar.normal.png deleted file mode 100644 index b335bda..0000000 Binary files a/src/data/themes/gray/slider.bar.normal.png and /dev/null differ diff --git a/src/data/themes/gray/slider.png b/src/data/themes/gray/slider.png deleted file mode 100644 index 0ed9619..0000000 Binary files a/src/data/themes/gray/slider.png and /dev/null differ diff --git a/src/data/themes/gray/tool.down.png b/src/data/themes/gray/tool.down.png deleted file mode 100644 index 760e666..0000000 Binary files a/src/data/themes/gray/tool.down.png and /dev/null differ diff --git a/src/data/themes/gray/tool.normal.png b/src/data/themes/gray/tool.normal.png deleted file mode 100644 index 17b344d..0000000 Binary files a/src/data/themes/gray/tool.normal.png and /dev/null differ diff --git a/src/data/themes/tools/config.txt b/src/data/themes/tools/config.txt deleted file mode 100644 index b663eb0..0000000 --- a/src/data/themes/tools/config.txt +++ /dev/null @@ -1,11 +0,0 @@ -tool.draw image icons48.draw.tga -tool.pixel image icons48.pixel.tga -tool.line image icons48.line.tga -tool.fill image icons48.fill.tga - -tool.select image icons48.select.tga -tool.eraser image icons48.eraser.tga - -tool.tile image icons48.tile.tga -tool.code image icons48.code.tga -tool.bkgr image icons48.bkgr.tga diff --git a/src/data/themes/tools/icons48.bkgr.tga b/src/data/themes/tools/icons48.bkgr.tga deleted file mode 100644 index 67a614b..0000000 Binary files a/src/data/themes/tools/icons48.bkgr.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.code.tga b/src/data/themes/tools/icons48.code.tga deleted file mode 100644 index bfe9615..0000000 Binary files a/src/data/themes/tools/icons48.code.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.draw.tga b/src/data/themes/tools/icons48.draw.tga deleted file mode 100644 index 0eec5ff..0000000 Binary files a/src/data/themes/tools/icons48.draw.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.eraser.tga b/src/data/themes/tools/icons48.eraser.tga deleted file mode 100644 index a7f4d42..0000000 Binary files a/src/data/themes/tools/icons48.eraser.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.fill.tga b/src/data/themes/tools/icons48.fill.tga deleted file mode 100644 index cb7be71..0000000 Binary files a/src/data/themes/tools/icons48.fill.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.line.tga b/src/data/themes/tools/icons48.line.tga deleted file mode 100644 index 19f9f9c..0000000 Binary files a/src/data/themes/tools/icons48.line.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.pixel.tga b/src/data/themes/tools/icons48.pixel.tga deleted file mode 100644 index 976b66a..0000000 Binary files a/src/data/themes/tools/icons48.pixel.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.select.tga b/src/data/themes/tools/icons48.select.tga deleted file mode 100644 index 09ee631..0000000 Binary files a/src/data/themes/tools/icons48.select.tga and /dev/null differ diff --git a/src/data/themes/tools/icons48.tile.tga b/src/data/themes/tools/icons48.tile.tga deleted file mode 100644 index 8ca8bae..0000000 Binary files a/src/data/themes/tools/icons48.tile.tga and /dev/null differ diff --git a/src/dataTools/__init__.py b/src/dataTools/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/dataTools/odict.py b/src/dataTools/odict.py deleted file mode 100644 index 2c8391d..0000000 --- a/src/dataTools/odict.py +++ /dev/null @@ -1,1399 +0,0 @@ -# odict.py -# An Ordered Dictionary object -# Copyright (C) 2005 Nicola Larosa, Michael Foord -# E-mail: nico AT tekNico DOT net, fuzzyman AT voidspace DOT org DOT uk - -# This software is licensed under the terms of the BSD license. -# http://www.voidspace.org.uk/python/license.shtml -# Basically you're free to copy, modify, distribute and relicense it, -# So long as you keep a copy of the license with it. - -# Documentation at http://www.voidspace.org.uk/python/odict.html -# For information about bugfixes, updates and support, please join the -# Pythonutils mailing list: -# http://groups.google.com/group/pythonutils/ -# Comments, suggestions and bug reports welcome. - -"""A dict that keeps keys in insertion order""" -from __future__ import generators - -__author__ = ('Nicola Larosa ,' - 'Michael Foord ') - -__docformat__ = "restructuredtext en" - -__revision__ = '$Id: odict.py 129 2005-09-12 18:15:28Z teknico $' - -__version__ = '0.2.2' - -__all__ = ['OrderedDict', 'SequenceOrderedDict'] - -import sys -INTP_VER = sys.version_info[:2] -if INTP_VER < (2, 2): - raise RuntimeError("Python v.2.2 or later required") - -import types, warnings - -class OrderedDict(dict): - """ - A class of dictionary that keeps the insertion order of keys. - - All appropriate methods return keys, items, or values in an ordered way. - - All normal dictionary methods are available. Update and comparison is - restricted to other OrderedDict objects. - - Various sequence methods are available, including the ability to explicitly - mutate the key ordering. - - __contains__ tests: - - >>> d = OrderedDict(((1, 3),)) - >>> 1 in d - 1 - >>> 4 in d - 0 - - __getitem__ tests: - - >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[2] - 1 - >>> OrderedDict(((1, 3), (3, 2), (2, 1)))[4] - Traceback (most recent call last): - KeyError: 4 - - __len__ tests: - - >>> len(OrderedDict()) - 0 - >>> len(OrderedDict(((1, 3), (3, 2), (2, 1)))) - 3 - - get tests: - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.get(1) - 3 - >>> d.get(4) is None - 1 - >>> d.get(4, 5) - 5 - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1)]) - - has_key tests: - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.has_key(1) - 1 - >>> d.has_key(4) - 0 - """ - - def __init__(self, init_val=(), strict=False): - """ - Create a new ordered dictionary. Cannot init from a normal dict, - nor from kwargs, since items order is undefined in those cases. - - If the ``strict`` keyword argument is ``True`` (``False`` is the - default) then when doing slice assignment - the ``OrderedDict`` you are - assigning from *must not* contain any keys in the remaining dict. - - >>> OrderedDict() - OrderedDict([]) - >>> OrderedDict({1: 1}) - Traceback (most recent call last): - TypeError: undefined order, cannot get items from dict - >>> OrderedDict({1: 1}.items()) - OrderedDict([(1, 1)]) - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1)]) - >>> OrderedDict(d) - OrderedDict([(1, 3), (3, 2), (2, 1)]) - """ - self.strict = strict - dict.__init__(self) - if isinstance(init_val, OrderedDict): - self._sequence = init_val.keys() - dict.update(self, init_val) - elif isinstance(init_val, dict): - # we lose compatibility with other ordered dict types this way - raise TypeError('undefined order, cannot get items from dict') - else: - self._sequence = [] - self.update(init_val) - -### Special methods ### - - def __delitem__(self, key): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> del d[3] - >>> d - OrderedDict([(1, 3), (2, 1)]) - >>> del d[3] - Traceback (most recent call last): - KeyError: 3 - >>> d[3] = 2 - >>> d - OrderedDict([(1, 3), (2, 1), (3, 2)]) - >>> del d[0:1] - >>> d - OrderedDict([(2, 1), (3, 2)]) - """ - if isinstance(key, types.SliceType): - # FIXME: efficiency? - keys = self._sequence[key] - for entry in keys: - dict.__delitem__(self, entry) - del self._sequence[key] - else: - # do the dict.__delitem__ *first* as it raises - # the more appropriate error - dict.__delitem__(self, key) - self._sequence.remove(key) - - def __eq__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d == OrderedDict(d) - True - >>> d == OrderedDict(((1, 3), (2, 1), (3, 2))) - False - >>> d == OrderedDict(((1, 0), (3, 2), (2, 1))) - False - >>> d == OrderedDict(((0, 3), (3, 2), (2, 1))) - False - >>> d == dict(d) - False - >>> d == False - False - """ - if isinstance(other, OrderedDict): - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() == other.items()) - else: - return False - - def __lt__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> c < d - True - >>> d < c - False - >>> d < dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() < other.items()) - - def __le__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> e = OrderedDict(d) - >>> c <= d - True - >>> d <= c - False - >>> d <= dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - >>> d <= e - True - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() <= other.items()) - - def __ne__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d != OrderedDict(d) - False - >>> d != OrderedDict(((1, 3), (2, 1), (3, 2))) - True - >>> d != OrderedDict(((1, 0), (3, 2), (2, 1))) - True - >>> d == OrderedDict(((0, 3), (3, 2), (2, 1))) - False - >>> d != dict(d) - True - >>> d != False - True - """ - if isinstance(other, OrderedDict): - # FIXME: efficiency? - # Generate both item lists for each compare - return not (self.items() == other.items()) - else: - return True - - def __gt__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> d > c - True - >>> c > d - False - >>> d > dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() > other.items()) - - def __ge__(self, other): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> c = OrderedDict(((0, 3), (3, 2), (2, 1))) - >>> e = OrderedDict(d) - >>> c >= d - False - >>> d >= c - True - >>> d >= dict(c) - Traceback (most recent call last): - TypeError: Can only compare with other OrderedDicts - >>> e >= d - True - """ - if not isinstance(other, OrderedDict): - raise TypeError('Can only compare with other OrderedDicts') - # FIXME: efficiency? - # Generate both item lists for each compare - return (self.items() >= other.items()) - - def __repr__(self): - """ - Used for __repr__ and __str__ - - >>> r1 = repr(OrderedDict((('a', 'b'), ('c', 'd'), ('e', 'f')))) - >>> r1 - "OrderedDict([('a', 'b'), ('c', 'd'), ('e', 'f')])" - >>> r2 = repr(OrderedDict((('a', 'b'), ('e', 'f'), ('c', 'd')))) - >>> r2 - "OrderedDict([('a', 'b'), ('e', 'f'), ('c', 'd')])" - >>> r1 == str(OrderedDict((('a', 'b'), ('c', 'd'), ('e', 'f')))) - True - >>> r2 == str(OrderedDict((('a', 'b'), ('e', 'f'), ('c', 'd')))) - True - """ - return '%s([%s])' % (self.__class__.__name__, ', '.join( - ['(%r, %r)' % (key, self[key]) for key in self._sequence])) - - def __setitem__(self, key, val): - """ - Allows slice assignment, so long as the slice is an OrderedDict - >>> d = OrderedDict() - >>> d['a'] = 'b' - >>> d['b'] = 'a' - >>> d[3] = 12 - >>> d - OrderedDict([('a', 'b'), ('b', 'a'), (3, 12)]) - >>> d[:] = OrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - OrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d[::2] = OrderedDict(((7, 8), (9, 10))) - >>> d - OrderedDict([(7, 8), (2, 3), (9, 10)]) - >>> d = OrderedDict(((0, 1), (1, 2), (2, 3), (3, 4))) - >>> d[1:3] = OrderedDict(((1, 2), (5, 6), (7, 8))) - >>> d - OrderedDict([(0, 1), (1, 2), (5, 6), (7, 8), (3, 4)]) - >>> d = OrderedDict(((0, 1), (1, 2), (2, 3), (3, 4)), strict=True) - >>> d[1:3] = OrderedDict(((1, 2), (5, 6), (7, 8))) - >>> d - OrderedDict([(0, 1), (1, 2), (5, 6), (7, 8), (3, 4)]) - - >>> a = OrderedDict(((0, 1), (1, 2), (2, 3)), strict=True) - >>> a[3] = 4 - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[:2] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]) - Traceback (most recent call last): - ValueError: slice assignment must be from unique keys - >>> a = OrderedDict(((0, 1), (1, 2), (2, 3))) - >>> a[3] = 4 - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[:2] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a[::-1] = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> a - OrderedDict([(3, 4), (2, 3), (1, 2), (0, 1)]) - - >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> d[:1] = 3 - Traceback (most recent call last): - TypeError: slice assignment requires an OrderedDict - - >>> d = OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)]) - >>> d[:1] = OrderedDict([(9, 8)]) - >>> d - OrderedDict([(9, 8), (1, 2), (2, 3), (3, 4)]) - """ - if isinstance(key, types.SliceType): - if not isinstance(val, OrderedDict): - # FIXME: allow a list of tuples? - raise TypeError('slice assignment requires an OrderedDict') - keys = self._sequence[key] - # NOTE: Could use ``range(*key.indices(len(self._sequence)))`` - indexes = range(len(self._sequence))[key] - if key.step is None: - # NOTE: new slice may not be the same size as the one being - # overwritten ! - # NOTE: What is the algorithm for an impossible slice? - # e.g. d[5:3] - pos = key.start or 0 - del self[key] - newkeys = val.keys() - for k in newkeys: - if k in self: - if self.strict: - raise ValueError('slice assignment must be from ' - 'unique keys') - else: - # NOTE: This removes duplicate keys *first* - # so start position might have changed? - del self[k] - self._sequence = (self._sequence[:pos] + newkeys + - self._sequence[pos:]) - dict.update(self, val) - else: - # extended slice - length of new slice must be the same - # as the one being replaced - if len(keys) != len(val): - raise ValueError('attempt to assign sequence of size %s ' - 'to extended slice of size %s' % (len(val), len(keys))) - # FIXME: efficiency? - del self[key] - item_list = zip(indexes, val.items()) - # smallest indexes first - higher indexes not guaranteed to - # exist - item_list.sort() - for pos, (newkey, newval) in item_list: - if self.strict and newkey in self: - raise ValueError('slice assignment must be from unique' - ' keys') - self.insert(pos, newkey, newval) - else: - if key not in self: - self._sequence.append(key) - dict.__setitem__(self, key, val) - - def __getitem__(self, key): - """ - Allows slicing. Returns an OrderedDict if you slice. - >>> b = OrderedDict([(7, 0), (6, 1), (5, 2), (4, 3), (3, 4), (2, 5), (1, 6)]) - >>> b[::-1] - OrderedDict([(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1), (7, 0)]) - >>> b[2:5] - OrderedDict([(5, 2), (4, 3), (3, 4)]) - >>> type(b[2:4]) - - """ - if isinstance(key, types.SliceType): - # FIXME: does this raise the error we want? - keys = self._sequence[key] - # FIXME: efficiency? - return OrderedDict([(entry, self[entry]) for entry in keys]) - else: - return dict.__getitem__(self, key) - - __str__ = __repr__ - - def __setattr__(self, name, value): - """ - Implemented so that accesses to ``sequence`` raise a warning and are - diverted to the new ``setkeys`` method. - """ - if name == 'sequence': - warnings.warn('Use of the sequence attribute is deprecated.' - ' Use the keys method instead.', DeprecationWarning) - # NOTE: doesn't return anything - self.setkeys(value) - else: - # FIXME: do we want to allow arbitrary setting of attributes? - # Or do we want to manage it? - object.__setattr__(self, name, value) - - def __getattr__(self, name): - """ - Implemented so that access to ``sequence`` raises a warning. - - >>> d = OrderedDict() - >>> d.sequence - [] - """ - if name == 'sequence': - warnings.warn('Use of the sequence attribute is deprecated.' - ' Use the keys method instead.', DeprecationWarning) - # NOTE: Still (currently) returns a direct reference. Need to - # because code that uses sequence will expect to be able to - # mutate it in place. - return self._sequence - else: - # raise the appropriate error - raise AttributeError("OrderedDict has no '%s' attribute" % name) - - def __deepcopy__(self, memo): - """ - To allow deepcopy to work with OrderedDict. - - >>> from copy import deepcopy - >>> a = OrderedDict([(1, 1), (2, 2), (3, 3)]) - >>> a['test'] = {} - >>> b = deepcopy(a) - >>> b == a - True - >>> b is a - False - >>> a['test'] is b['test'] - False - """ - from copy import deepcopy - return self.__class__(deepcopy(self.items(), memo), self.strict) - - -### Read-only methods ### - - def copy(self): - """ - >>> OrderedDict(((1, 3), (3, 2), (2, 1))).copy() - OrderedDict([(1, 3), (3, 2), (2, 1)]) - """ - return OrderedDict(self) - - def items(self): - """ - ``items`` returns a list of tuples representing all the - ``(key, value)`` pairs in the dictionary. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.items() - [(1, 3), (3, 2), (2, 1)] - >>> d.clear() - >>> d.items() - [] - """ - return zip(self._sequence, self.values()) - - def keys(self): - """ - Return a list of keys in the ``OrderedDict``. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.keys() - [1, 3, 2] - """ - return self._sequence[:] - - def values(self, values=None): - """ - Return a list of all the values in the OrderedDict. - - Optionally you can pass in a list of values, which will replace the - current list. The value list must be the same len as the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.values() - [3, 2, 1] - """ - return [self[key] for key in self._sequence] - - def iteritems(self): - """ - >>> ii = OrderedDict(((1, 3), (3, 2), (2, 1))).iteritems() - >>> ii.next() - (1, 3) - >>> ii.next() - (3, 2) - >>> ii.next() - (2, 1) - >>> ii.next() - Traceback (most recent call last): - StopIteration - """ - def make_iter(self=self): - keys = self.iterkeys() - while True: - key = keys.next() - yield (key, self[key]) - return make_iter() - - def iterkeys(self): - """ - >>> ii = OrderedDict(((1, 3), (3, 2), (2, 1))).iterkeys() - >>> ii.next() - 1 - >>> ii.next() - 3 - >>> ii.next() - 2 - >>> ii.next() - Traceback (most recent call last): - StopIteration - """ - return iter(self._sequence) - - __iter__ = iterkeys - - def itervalues(self): - """ - >>> iv = OrderedDict(((1, 3), (3, 2), (2, 1))).itervalues() - >>> iv.next() - 3 - >>> iv.next() - 2 - >>> iv.next() - 1 - >>> iv.next() - Traceback (most recent call last): - StopIteration - """ - def make_iter(self=self): - keys = self.iterkeys() - while True: - yield self[keys.next()] - return make_iter() - -### Read-write methods ### - - def clear(self): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.clear() - >>> d - OrderedDict([]) - """ - dict.clear(self) - self._sequence = [] - - def pop(self, key, *args): - """ - No dict.pop in Python 2.2, gotta reimplement it - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.pop(3) - 2 - >>> d - OrderedDict([(1, 3), (2, 1)]) - >>> d.pop(4) - Traceback (most recent call last): - KeyError: 4 - >>> d.pop(4, 0) - 0 - >>> d.pop(4, 0, 1) - Traceback (most recent call last): - TypeError: pop expected at most 2 arguments, got 3 - """ - if len(args) > 1: - raise TypeError, ('pop expected at most 2 arguments, got %s' % - (len(args) + 1)) - if key in self: - val = self[key] - del self[key] - else: - try: - val = args[0] - except IndexError: - raise KeyError(key) - return val - - def popitem(self, i=-1): - """ - Delete and return an item specified by index, not a random one as in - dict. The index is -1 by default (the last item). - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.popitem() - (2, 1) - >>> d - OrderedDict([(1, 3), (3, 2)]) - >>> d.popitem(0) - (1, 3) - >>> OrderedDict().popitem() - Traceback (most recent call last): - KeyError: 'popitem(): dictionary is empty' - >>> d.popitem(2) - Traceback (most recent call last): - IndexError: popitem(): index 2 not valid - """ - if not self._sequence: - raise KeyError('popitem(): dictionary is empty') - try: - key = self._sequence[i] - except IndexError: - raise IndexError('popitem(): index %s not valid' % i) - return (key, self.pop(key)) - - def setdefault(self, key, defval = None): - """ - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.setdefault(1) - 3 - >>> d.setdefault(4) is None - True - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1), (4, None)]) - >>> d.setdefault(5, 0) - 0 - >>> d - OrderedDict([(1, 3), (3, 2), (2, 1), (4, None), (5, 0)]) - """ - if key in self: - return self[key] - else: - self[key] = defval - return defval - - def update(self, from_od): - """ - Update from another OrderedDict or sequence of (key, value) pairs - - >>> d = OrderedDict(((1, 0), (0, 1))) - >>> d.update(OrderedDict(((1, 3), (3, 2), (2, 1)))) - >>> d - OrderedDict([(1, 3), (0, 1), (3, 2), (2, 1)]) - >>> d.update({4: 4}) - Traceback (most recent call last): - TypeError: undefined order, cannot get items from dict - >>> d.update((4, 4)) - Traceback (most recent call last): - TypeError: cannot convert dictionary update sequence element "4" to a 2-item sequence - """ - if isinstance(from_od, OrderedDict): - for key, val in from_od.items(): - self[key] = val - elif isinstance(from_od, dict): - # we lose compatibility with other ordered dict types this way - raise TypeError('undefined order, cannot get items from dict') - else: - # FIXME: efficiency? - # sequence of 2-item sequences, or error - for item in from_od: - try: - key, val = item - except TypeError: - raise TypeError('cannot convert dictionary update' - ' sequence element "%s" to a 2-item sequence' % item) - self[key] = val - - def rename(self, old_key, new_key): - """ - Rename the key for a given value, without modifying sequence order. - - For the case where new_key already exists this raise an exception, - since if new_key exists, it is ambiguous as to what happens to the - associated values, and the position of new_key in the sequence. - - >>> od = OrderedDict() - >>> od['a'] = 1 - >>> od['b'] = 2 - >>> od.items() - [('a', 1), ('b', 2)] - >>> od.rename('b', 'c') - >>> od.items() - [('a', 1), ('c', 2)] - >>> od.rename('c', 'a') - Traceback (most recent call last): - ValueError: New key already exists: 'a' - >>> od.rename('d', 'b') - Traceback (most recent call last): - KeyError: 'd' - """ - if new_key == old_key: - # no-op - return - if new_key in self: - raise ValueError("New key already exists: %r" % new_key) - # rename sequence entry - value = self[old_key] - old_idx = self._sequence.index(old_key) - self._sequence[old_idx] = new_key - # rename internal dict entry - dict.__delitem__(self, old_key) - dict.__setitem__(self, new_key, value) - - def setitems(self, items): - """ - This method allows you to set the items in the dict. - - It takes a list of tuples - of the same sort returned by the ``items`` - method. - - >>> d = OrderedDict() - >>> d.setitems(((3, 1), (2, 3), (1, 2))) - >>> d - OrderedDict([(3, 1), (2, 3), (1, 2)]) - """ - self.clear() - # FIXME: this allows you to pass in an OrderedDict as well :-) - self.update(items) - - def setkeys(self, keys): - """ - ``setkeys`` all ows you to pass in a new list of keys which will - replace the current set. This must contain the same set of keys, but - need not be in the same order. - - If you pass in new keys that don't match, a ``KeyError`` will be - raised. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.keys() - [1, 3, 2] - >>> d.setkeys((1, 2, 3)) - >>> d - OrderedDict([(1, 3), (2, 1), (3, 2)]) - >>> d.setkeys(['a', 'b', 'c']) - Traceback (most recent call last): - KeyError: 'Keylist is not the same as current keylist.' - """ - # FIXME: Efficiency? (use set for Python 2.4 :-) - # NOTE: list(keys) rather than keys[:] because keys[:] returns - # a tuple, if keys is a tuple. - kcopy = list(keys) - kcopy.sort() - self._sequence.sort() - if kcopy != self._sequence: - raise KeyError('Keylist is not the same as current keylist.') - # NOTE: This makes the _sequence attribute a new object, instead - # of changing it in place. - # FIXME: efficiency? - self._sequence = list(keys) - - def setvalues(self, values): - """ - You can pass in a list of values, which will replace the - current list. The value list must be the same len as the OrderedDict. - - (Or a ``ValueError`` is raised.) - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.setvalues((1, 2, 3)) - >>> d - OrderedDict([(1, 1), (3, 2), (2, 3)]) - >>> d.setvalues([6]) - Traceback (most recent call last): - ValueError: Value list is not the same length as the OrderedDict. - """ - if len(values) != len(self): - # FIXME: correct error to raise? - raise ValueError('Value list is not the same length as the ' - 'OrderedDict.') - self.update(zip(self, values)) - -### Sequence Methods ### - - def index(self, key): - """ - Return the position of the specified key in the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.index(3) - 1 - >>> d.index(4) - Traceback (most recent call last): - ValueError: list.index(x): x not in list - """ - return self._sequence.index(key) - - def insert(self, index, key, value): - """ - Takes ``index``, ``key``, and ``value`` as arguments. - - Sets ``key`` to ``value``, so that ``key`` is at position ``index`` in - the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.insert(0, 4, 0) - >>> d - OrderedDict([(4, 0), (1, 3), (3, 2), (2, 1)]) - >>> d.insert(0, 2, 1) - >>> d - OrderedDict([(2, 1), (4, 0), (1, 3), (3, 2)]) - >>> d.insert(8, 8, 1) - >>> d - OrderedDict([(2, 1), (4, 0), (1, 3), (3, 2), (8, 1)]) - """ - if key in self: - # FIXME: efficiency? - del self[key] - self._sequence.insert(index, key) - dict.__setitem__(self, key, value) - - def reverse(self): - """ - Reverse the order of the OrderedDict. - - >>> d = OrderedDict(((1, 3), (3, 2), (2, 1))) - >>> d.reverse() - >>> d - OrderedDict([(2, 1), (3, 2), (1, 3)]) - """ - self._sequence.reverse() - - def sort(self, *args, **kwargs): - """ - Sort the key order in the OrderedDict. - - This method takes the same arguments as the ``list.sort`` method on - your version of Python. - - >>> d = OrderedDict(((4, 1), (2, 2), (3, 3), (1, 4))) - >>> d.sort() - >>> d - OrderedDict([(1, 4), (2, 2), (3, 3), (4, 1)]) - """ - self._sequence.sort(*args, **kwargs) - -class Keys(object): - # FIXME: should this object be a subclass of list? - """ - Custom object for accessing the keys of an OrderedDict. - - Can be called like the normal ``OrderedDict.keys`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the keys method.""" - return self._main._keys() - - def __getitem__(self, index): - """Fetch the key at position i.""" - # NOTE: this automatically supports slicing :-) - return self._main._sequence[index] - - def __setitem__(self, index, name): - """ - You cannot assign to keys, but you can do slice assignment to re-order - them. - - You can only do slice assignment if the new set of keys is a reordering - of the original set. - """ - if isinstance(index, types.SliceType): - # FIXME: efficiency? - # check length is the same - indexes = range(len(self._main._sequence))[index] - if len(indexes) != len(name): - raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(name), len(indexes))) - # check they are the same keys - # FIXME: Use set - old_keys = self._main._sequence[index] - new_keys = list(name) - old_keys.sort() - new_keys.sort() - if old_keys != new_keys: - raise KeyError('Keylist is not the same as current keylist.') - orig_vals = [self._main[k] for k in name] - del self._main[index] - vals = zip(indexes, name, orig_vals) - vals.sort() - for i, k, v in vals: - if self._main.strict and k in self._main: - raise ValueError('slice assignment must be from ' - 'unique keys') - self._main.insert(i, k, v) - else: - raise ValueError('Cannot assign to keys') - - ### following methods pinched from UserList and adapted ### - def __repr__(self): return repr(self._main._sequence) - - # FIXME: do we need to check if we are comparing with another ``Keys`` - # object? (like the __cast method of UserList) - def __lt__(self, other): return self._main._sequence < other - def __le__(self, other): return self._main._sequence <= other - def __eq__(self, other): return self._main._sequence == other - def __ne__(self, other): return self._main._sequence != other - def __gt__(self, other): return self._main._sequence > other - def __ge__(self, other): return self._main._sequence >= other - # FIXME: do we need __cmp__ as well as rich comparisons? - def __cmp__(self, other): return cmp(self._main._sequence, other) - - def __contains__(self, item): return item in self._main._sequence - def __len__(self): return len(self._main._sequence) - def __iter__(self): return self._main.iterkeys() - def count(self, item): return self._main._sequence.count(item) - def index(self, item, *args): return self._main._sequence.index(item, *args) - def reverse(self): self._main._sequence.reverse() - def sort(self, *args, **kwds): self._main._sequence.sort(*args, **kwds) - def __mul__(self, n): return self._main._sequence*n - __rmul__ = __mul__ - def __add__(self, other): return self._main._sequence + other - def __radd__(self, other): return other + self._main._sequence - - ## following methods not implemented for keys ## - def __delitem__(self, i): raise TypeError('Can\'t delete items from keys') - def __iadd__(self, other): raise TypeError('Can\'t add in place to keys') - def __imul__(self, n): raise TypeError('Can\'t multiply keys in place') - def append(self, item): raise TypeError('Can\'t append items to keys') - def insert(self, i, item): raise TypeError('Can\'t insert items into keys') - def pop(self, i=-1): raise TypeError('Can\'t pop items from keys') - def remove(self, item): raise TypeError('Can\'t remove items from keys') - def extend(self, other): raise TypeError('Can\'t extend keys') - -class Items(object): - """ - Custom object for accessing the items of an OrderedDict. - - Can be called like the normal ``OrderedDict.items`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the items method.""" - return self._main._items() - - def __getitem__(self, index): - """Fetch the item at position i.""" - if isinstance(index, types.SliceType): - # fetching a slice returns an OrderedDict - return self._main[index].items() - key = self._main._sequence[index] - return (key, self._main[key]) - - def __setitem__(self, index, item): - """Set item at position i to item.""" - if isinstance(index, types.SliceType): - # NOTE: item must be an iterable (list of tuples) - self._main[index] = OrderedDict(item) - else: - # FIXME: Does this raise a sensible error? - orig = self._main.keys[index] - key, value = item - if self._main.strict and key in self and (key != orig): - raise ValueError('slice assignment must be from ' - 'unique keys') - # delete the current one - del self._main[self._main._sequence[index]] - self._main.insert(index, key, value) - - def __delitem__(self, i): - """Delete the item at position i.""" - key = self._main._sequence[i] - if isinstance(i, types.SliceType): - for k in key: - # FIXME: efficiency? - del self._main[k] - else: - del self._main[key] - - ### following methods pinched from UserList and adapted ### - def __repr__(self): return repr(self._main.items()) - - # FIXME: do we need to check if we are comparing with another ``Items`` - # object? (like the __cast method of UserList) - def __lt__(self, other): return self._main.items() < other - def __le__(self, other): return self._main.items() <= other - def __eq__(self, other): return self._main.items() == other - def __ne__(self, other): return self._main.items() != other - def __gt__(self, other): return self._main.items() > other - def __ge__(self, other): return self._main.items() >= other - def __cmp__(self, other): return cmp(self._main.items(), other) - - def __contains__(self, item): return item in self._main.items() - def __len__(self): return len(self._main._sequence) # easier :-) - def __iter__(self): return self._main.iteritems() - def count(self, item): return self._main.items().count(item) - def index(self, item, *args): return self._main.items().index(item, *args) - def reverse(self): self._main.reverse() - def sort(self, *args, **kwds): self._main.sort(*args, **kwds) - def __mul__(self, n): return self._main.items()*n - __rmul__ = __mul__ - def __add__(self, other): return self._main.items() + other - def __radd__(self, other): return other + self._main.items() - - def append(self, item): - """Add an item to the end.""" - # FIXME: this is only append if the key isn't already present - key, value = item - self._main[key] = value - - def insert(self, i, item): - key, value = item - self._main.insert(i, key, value) - - def pop(self, i=-1): - key = self._main._sequence[i] - return (key, self._main.pop(key)) - - def remove(self, item): - key, value = item - try: - assert value == self._main[key] - except (KeyError, AssertionError): - raise ValueError('ValueError: list.remove(x): x not in list') - else: - del self._main[key] - - def extend(self, other): - # FIXME: is only a true extend if none of the keys already present - for item in other: - key, value = item - self._main[key] = value - - def __iadd__(self, other): - self.extend(other) - - ## following methods not implemented for items ## - - def __imul__(self, n): raise TypeError('Can\'t multiply items in place') - -class Values(object): - """ - Custom object for accessing the values of an OrderedDict. - - Can be called like the normal ``OrderedDict.values`` method, but also - supports indexing and sequence methods. - """ - - def __init__(self, main): - self._main = main - - def __call__(self): - """Pretend to be the values method.""" - return self._main._values() - - def __getitem__(self, index): - """Fetch the value at position i.""" - if isinstance(index, types.SliceType): - return [self._main[key] for key in self._main._sequence[index]] - else: - return self._main[self._main._sequence[index]] - - def __setitem__(self, index, value): - """ - Set the value at position i to value. - - You can only do slice assignment to values if you supply a sequence of - equal length to the slice you are replacing. - """ - if isinstance(index, types.SliceType): - keys = self._main._sequence[index] - if len(keys) != len(value): - raise ValueError('attempt to assign sequence of size %s ' - 'to slice of size %s' % (len(name), len(keys))) - # FIXME: efficiency? Would be better to calculate the indexes - # directly from the slice object - # NOTE: the new keys can collide with existing keys (or even - # contain duplicates) - these will overwrite - for key, val in zip(keys, value): - self._main[key] = val - else: - self._main[self._main._sequence[index]] = value - - ### following methods pinched from UserList and adapted ### - def __repr__(self): return repr(self._main.values()) - - # FIXME: do we need to check if we are comparing with another ``Values`` - # object? (like the __cast method of UserList) - def __lt__(self, other): return self._main.values() < other - def __le__(self, other): return self._main.values() <= other - def __eq__(self, other): return self._main.values() == other - def __ne__(self, other): return self._main.values() != other - def __gt__(self, other): return self._main.values() > other - def __ge__(self, other): return self._main.values() >= other - def __cmp__(self, other): return cmp(self._main.values(), other) - - def __contains__(self, item): return item in self._main.values() - def __len__(self): return len(self._main._sequence) # easier :-) - def __iter__(self): return self._main.itervalues() - def count(self, item): return self._main.values().count(item) - def index(self, item, *args): return self._main.values().index(item, *args) - - def reverse(self): - """Reverse the values""" - vals = self._main.values() - vals.reverse() - # FIXME: efficiency - self[:] = vals - - def sort(self, *args, **kwds): - """Sort the values.""" - vals = self._main.values() - vals.sort(*args, **kwds) - self[:] = vals - - def __mul__(self, n): return self._main.values()*n - __rmul__ = __mul__ - def __add__(self, other): return self._main.values() + other - def __radd__(self, other): return other + self._main.values() - - ## following methods not implemented for values ## - def __delitem__(self, i): raise TypeError('Can\'t delete items from values') - def __iadd__(self, other): raise TypeError('Can\'t add in place to values') - def __imul__(self, n): raise TypeError('Can\'t multiply values in place') - def append(self, item): raise TypeError('Can\'t append items to values') - def insert(self, i, item): raise TypeError('Can\'t insert items into values') - def pop(self, i=-1): raise TypeError('Can\'t pop items from values') - def remove(self, item): raise TypeError('Can\'t remove items from values') - def extend(self, other): raise TypeError('Can\'t extend values') - -class SequenceOrderedDict(OrderedDict): - """ - Experimental version of OrderedDict that has a custom object for ``keys``, - ``values``, and ``items``. - - These are callable sequence objects that work as methods, or can be - manipulated directly as sequences. - - Test for ``keys``, ``items`` and ``values``. - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.keys - [1, 2, 3] - >>> d.keys() - [1, 2, 3] - >>> d.setkeys((3, 2, 1)) - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.setkeys((1, 2, 3)) - >>> d.keys[0] - 1 - >>> d.keys[:] - [1, 2, 3] - >>> d.keys[-1] - 3 - >>> d.keys[-2] - 2 - >>> d.keys[0:2] = [2, 1] - >>> d - SequenceOrderedDict([(2, 3), (1, 2), (3, 4)]) - >>> d.keys.reverse() - >>> d.keys - [3, 1, 2] - >>> d.keys = [1, 2, 3] - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.keys = [3, 1, 2] - >>> d - SequenceOrderedDict([(3, 4), (1, 2), (2, 3)]) - >>> a = SequenceOrderedDict() - >>> b = SequenceOrderedDict() - >>> a.keys == b.keys - 1 - >>> a['a'] = 3 - >>> a.keys == b.keys - 0 - >>> b['a'] = 3 - >>> a.keys == b.keys - 1 - >>> b['b'] = 3 - >>> a.keys == b.keys - 0 - >>> a.keys > b.keys - 0 - >>> a.keys < b.keys - 1 - >>> 'a' in a.keys - 1 - >>> len(b.keys) - 2 - >>> 'c' in d.keys - 0 - >>> 1 in d.keys - 1 - >>> [v for v in d.keys] - [3, 1, 2] - >>> d.keys.sort() - >>> d.keys - [1, 2, 3] - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4)), strict=True) - >>> d.keys[::-1] = [1, 2, 3] - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.keys[:2] - [3, 2] - >>> d.keys[:2] = [1, 3] - Traceback (most recent call last): - KeyError: 'Keylist is not the same as current keylist.' - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.values - [2, 3, 4] - >>> d.values() - [2, 3, 4] - >>> d.setvalues((4, 3, 2)) - >>> d - SequenceOrderedDict([(1, 4), (2, 3), (3, 2)]) - >>> d.values[::-1] - [2, 3, 4] - >>> d.values[0] - 4 - >>> d.values[-2] - 3 - >>> del d.values[0] - Traceback (most recent call last): - TypeError: Can't delete items from values - >>> d.values[::2] = [2, 4] - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> 7 in d.values - 0 - >>> len(d.values) - 3 - >>> [val for val in d.values] - [2, 3, 4] - >>> d.values[-1] = 2 - >>> d.values.count(2) - 2 - >>> d.values.index(2) - 0 - >>> d.values[-1] = 7 - >>> d.values - [2, 3, 7] - >>> d.values.reverse() - >>> d.values - [7, 3, 2] - >>> d.values.sort() - >>> d.values - [2, 3, 7] - >>> d.values.append('anything') - Traceback (most recent call last): - TypeError: Can't append items to values - >>> d.values = (1, 2, 3) - >>> d - SequenceOrderedDict([(1, 1), (2, 2), (3, 3)]) - - >>> d = SequenceOrderedDict(((1, 2), (2, 3), (3, 4))) - >>> d - SequenceOrderedDict([(1, 2), (2, 3), (3, 4)]) - >>> d.items() - [(1, 2), (2, 3), (3, 4)] - >>> d.setitems([(3, 4), (2 ,3), (1, 2)]) - >>> d - SequenceOrderedDict([(3, 4), (2, 3), (1, 2)]) - >>> d.items[0] - (3, 4) - >>> d.items[:-1] - [(3, 4), (2, 3)] - >>> d.items[1] = (6, 3) - >>> d.items - [(3, 4), (6, 3), (1, 2)] - >>> d.items[1:2] = [(9, 9)] - >>> d - SequenceOrderedDict([(3, 4), (9, 9), (1, 2)]) - >>> del d.items[1:2] - >>> d - SequenceOrderedDict([(3, 4), (1, 2)]) - >>> (3, 4) in d.items - 1 - >>> (4, 3) in d.items - 0 - >>> len(d.items) - 2 - >>> [v for v in d.items] - [(3, 4), (1, 2)] - >>> d.items.count((3, 4)) - 1 - >>> d.items.index((1, 2)) - 1 - >>> d.items.index((2, 1)) - Traceback (most recent call last): - ValueError: list.index(x): x not in list - >>> d.items.reverse() - >>> d.items - [(1, 2), (3, 4)] - >>> d.items.reverse() - >>> d.items.sort() - >>> d.items - [(1, 2), (3, 4)] - >>> d.items.append((5, 6)) - >>> d.items - [(1, 2), (3, 4), (5, 6)] - >>> d.items.insert(0, (0, 0)) - >>> d.items - [(0, 0), (1, 2), (3, 4), (5, 6)] - >>> d.items.insert(-1, (7, 8)) - >>> d.items - [(0, 0), (1, 2), (3, 4), (7, 8), (5, 6)] - >>> d.items.pop() - (5, 6) - >>> d.items - [(0, 0), (1, 2), (3, 4), (7, 8)] - >>> d.items.remove((1, 2)) - >>> d.items - [(0, 0), (3, 4), (7, 8)] - >>> d.items.extend([(1, 2), (5, 6)]) - >>> d.items - [(0, 0), (3, 4), (7, 8), (1, 2), (5, 6)] - """ - - def __init__(self, init_val=(), strict=True): - OrderedDict.__init__(self, init_val, strict=strict) - self._keys = self.keys - self._values = self.values - self._items = self.items - self.keys = Keys(self) - self.values = Values(self) - self.items = Items(self) - self._att_dict = { - 'keys': self.setkeys, - 'items': self.setitems, - 'values': self.setvalues, - } - - def __setattr__(self, name, value): - """Protect keys, items, and values.""" - if not '_att_dict' in self.__dict__: - object.__setattr__(self, name, value) - else: - try: - fun = self._att_dict[name] - except KeyError: - OrderedDict.__setattr__(self, name, value) - else: - fun(value) - -if __name__ == '__main__': - if INTP_VER < (2, 3): - raise RuntimeError("Tests require Python v.2.3 or later") - # turn off warnings for tests - warnings.filterwarnings('ignore') - # run the code tests in doctest format - import doctest - m = sys.modules.get('__main__') - globs = m.__dict__.copy() - globs.update({ - 'INTP_VER': INTP_VER, - }) - doctest.testmod(m, globs=globs) - diff --git a/src/gradients/__init__.py b/src/gradients/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/gradients/gradients.py b/src/gradients/gradients.py deleted file mode 100755 index cac1f2e..0000000 --- a/src/gradients/gradients.py +++ /dev/null @@ -1,576 +0,0 @@ -#Copyright 2006 DR0ID http://mypage.bluewin.ch/DR0ID -# -# -# -""" -Allow to draw some gradients relatively easy. -""" - -__author__ = "$Author: DR0ID $" -__version__= "$Revision: 109 $" -__date__ = "$Date: 2007-08-09 20:33:32 +0200 (Do, 09 Aug 2007) $" - -import pygame -import math - -BLEND_MODES_AVAILABLE = False -vernum = pygame.vernum -if vernum[0]>=1 and vernum[1]>=8: - BLEND_MODES_AVAILABLE = True - - -class ColorInterpolator(object): - ''' - ColorInterpolator(distance, color1, color2, rfunc, gfunc, bfunc, afunc) - - interpolates a color over the distance using different functions for r,g,b,a - separately (a= alpha). - ''' - def __init__(self, distance, color1, color2, rfunc, gfunc, bfunc, afunc): - object.__init__(self) - - self.rInterpolator = FunctionInterpolator(color1[0], color2[0], distance, rfunc) - self.gInterpolator = FunctionInterpolator(color1[1], color2[1], distance, gfunc) - self.bInterpolator = FunctionInterpolator(color1[2], color2[2], distance, bfunc) - if len(color1)==4 and len(color2)==4: - self.aInterpolator = FunctionInterpolator(color1[3], color2[3], distance, afunc) - else: - self.aInterpolator = FunctionInterpolator(255, 255, distance, afunc) - - def eval(self, x): - ''' - eval(x) -> color - - returns the color at the position 0<=x<=d (actually not bound to this interval). - ''' -## print "colorInterp x", x, self.rInterpolator.eval(x), self.gInterpolator.eval(x), self.bInterpolator.eval(x) - return [self.rInterpolator.eval(x), - self.gInterpolator.eval(x), - self.bInterpolator.eval(x), - self.aInterpolator.eval(x)] - - - -class FunctionInterpolator(object): - ''' - FunctionINterpolator(startvalue, endvalue, trange, func) - - interpolates a function y=f(x) in the range trange with - startvalue = f(0) - endvalue = f(trange) - using the function func - ''' - def __init__(self, startvalue, endvalue, trange, func): - object.__init__(self) - # function - self.func = func - # y-scaling - self.a = endvalue-startvalue - if self.a == 0: - self.a = 1. - # x-scaling - if trange!=0: - self.b = 1./abs(trange) - else: - self.b = 1. - # x-displacement - self.c = 0 - # y-displacement - self.d = min(max(startvalue,0),255) - - def eval(self, x): - ''' - eval(x)->float - - return value at position x - ''' - # make sure that the returned value is in [0,255] -## return int(round(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255))) - return int(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255)) - - - -##def gradient(surface, -## startpoint, -## endpoint, -## startcolor, -## endcolor, -## Rfunc = (lambda x:x), -## Gfunc = (lambda x:x), -## Bfunc = (lambda x:x), -## Afunc = (lambda x:1), -## type = "line", -## mode = None ): -## ''' -## surface : surface to draw on -## startpoint: (x,y) point on surface -## endpoint : (x,y) point on surface -## startcolor: (r,g,b,a) color at startpoint -## endcolor : (r,g,b,a) color at endpoint -## Rfunc : function y = f(x) with startcolor =f(0) and endcolor = f(1) where 0 is at startpoint and 1 at endpoint -## Gfunc : --- " --- -## Bfunc : --- " --- -## Afunc : --- " --- -## these functions are evaluated in the range 0 <= x <= 1 and 0<= y=f(x) <= 1 -## type : "line", "circle" or "rect" -## mode : "+", "-", "*", None (how the pixels are drawen) -## -## returns : surface with the color characteristics w,h = (d, 256) and d = length of endpoint-startpoint -## -## ''' -## dx = endpoint[0]-startpoint[0] -## dy = endpoint[1]-startpoint[1] -## d = int(round(math.hypot(dx, dy))) -## angle = math.degrees( math.atan2(dy, dx) ) -## -## color = ColorInterpolator(d, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) -## -## if type=="line": -## h = int(2.*math.hypot(*surface.get_size())) -### bigSurf = pygame.Surface((d, h)).convert_alpha() -## bigSurf = pygame.Surface((d, h), pygame.SRCALPHA)#.convert_alpha() -### bigSurf = pygame.Surface((d, 1), pygame.SRCALPHA)#.convert_alpha() -## bigSurf.lock() -## bigSurf.fill((0,0,0,0)) -## bigSurf.set_colorkey((0,0,0,0)) -## for x in range(d): -## pygame.draw.line(bigSurf, color.eval(x), (x,0), (x,h), 1) -### for x in range(d): -### bigSurf.set_at((x, 0), color.eval(x)) -### bigSurf = pygame.transform.scale(bigSurf, (d, h)) -## -## bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1) -## bigSurf.set_colorkey((0,0,0, 0)) -## rect = bigSurf.get_rect() -## srect = pygame.Rect(rect) -## dx = d/2. * math.cos(math.radians(angle)) -## dy = d/2. * math.sin(math.radians(angle)) -## rect.center = startpoint -## rect.move_ip(dx, dy) -## bigSurf.unlock() -## -## elif type=="circle": -## bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha() -## bigSurf.fill((0,0,0,0)) -## bigSurf.lock() -## for x in range(d, 0, -1): -## pygame.draw.circle(bigSurf, color.eval(x), (d,d), x) -## bigSurf.unlock() -## rect = bigSurf.get_rect() -## srect = pygame.Rect(rect) -## rect.center = (startpoint[0], startpoint[1]) -## -## elif type=="rect": -## bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha() -## bigSurf.fill((0,0,0,0)) -## c = bigSurf.get_rect().center -## bigSurf.lock() -## for x in range(d,-1,-1): -## r = pygame.Rect(0,0,2*x,2*x) -## r.center = c -## pygame.draw.rect(bigSurf, color.eval(x), r) -## bigSurf.unlock() -## bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) -## bigSurf.set_colorkey((0,0,0, 0)) -## -## rect = bigSurf.get_rect() -## srect = pygame.Rect(rect) -## rect.center = startpoint -## else: -## raise NameError("type must be one of \"line\",\"circle\" or \"rect\"") -## -## if mode is None: -## surface.blit(bigSurf, rect, srect) -## else: -## if mode=="+": -## cf = pygame.color.add -## elif mode=="*": -## cf = pygame.color.multiply -## elif mode=="-": -## cf = pygame.color.subtract -## else: -## raise NameError("type must be one of \"+\", \"*\", \"-\" or None") -## irect = surface.get_clip().clip(rect) -## surface.lock() -## for x in range(irect.left, irect.left+irect.width): -## for y in range(irect.top, irect.top+irect.height): -## surface.set_at((x,y), cf(surface.get_at((x,y)), bigSurf.get_at((x-rect.left, y-rect.top)) ) ) -## surface.unlock() -## -## del bigSurf -## char = pygame.Surface((d+1, 257)) -### char.fill((0,0,0)) -### ox = 0 -### oldcol = color.eval(0) -### for x in range(d): -### col = color.eval(x) -### pygame.draw.line(char, (255,0,0), (x, 256-col[0]), (ox, 256-oldcol[0])) -### pygame.draw.line(char, (0,255,0), (x, 256-col[1]), (ox, 256-oldcol[1])) -### pygame.draw.line(char, (0,0,255), (x, 256-col[2]), (ox, 256-oldcol[2])) -### pygame.draw.line(char, (255,255,255), (x, 256-col[3]), (ox, 256-oldcol[3])) -### ox = x -### oldcol = col -### -## return char - - - - -def vertical(size, startcolor, endcolor): - """ - Draws a vertical linear gradient filling the entire surface. Returns a - surface filled with the gradient (numeric is only 2-3 times faster). - """ - height = size[1] - bigSurf = pygame.Surface((1,height)).convert_alpha() - dd = 1.0/height - sr, sg, sb, sa = startcolor - er, eg, eb, ea = endcolor - rm = (er-sr)*dd - gm = (eg-sg)*dd - bm = (eb-sb)*dd - am = (ea-sa)*dd - for y in range(height): - bigSurf.set_at((0,y), - (int(sr + rm*y), - int(sg + gm*y), - int(sb + bm*y), - int(sa + am*y)) - ) - return pygame.transform.scale(bigSurf, size) - - -def horizontal(size, startcolor, endcolor): - """ - Draws a horizontal linear gradient filling the entire surface. Returns a - surface filled with the gradient (numeric is only 2-3 times faster). - """ - width = size[0] - bigSurf = pygame.Surface((width, 1)).convert_alpha() - dd = 1.0/width - sr, sg, sb, sa = startcolor - er, eg, eb, ea = endcolor - rm = (er-sr)*dd - gm = (eg-sg)*dd - bm = (eb-sb)*dd - am = (ea-sa)*dd - for y in range(width): - bigSurf.set_at((y,0), - (int(sr + rm*y), - int(sg + gm*y), - int(sb + bm*y), - int(sa + am*y)) - ) - return pygame.transform.scale(bigSurf, size) - - -def radial(radius, startcolor, endcolor): - """ - Draws a linear raidal gradient on a square sized surface and returns - that surface. - """ - bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha() - bigSurf.fill((0,0,0,0)) - dd = -1.0/radius - sr, sg, sb, sa = endcolor - er, eg, eb, ea = startcolor - rm = (er-sr)*dd - gm = (eg-sg)*dd - bm = (eb-sb)*dd - am = (ea-sa)*dd - - draw_circle = pygame.draw.circle - for rad in range(radius, 0, -1): - draw_circle(bigSurf, (er + int(rm*rad), - eg + int(gm*rad), - eb + int(bm*rad), - ea + int(am*rad)), (radius, radius), rad) - return bigSurf - -def squared(width, startcolor, endcolor): - """ - Draws a linear sqared gradient on a square sized surface and returns - that surface. - """ - bigSurf = pygame.Surface((width, width)).convert_alpha() - bigSurf.fill((0,0,0,0)) - dd = -1.0/(width/2) - sr, sg, sb, sa = endcolor - er, eg, eb, ea = startcolor - rm = (er-sr)*dd - gm = (eg-sg)*dd - bm = (eb-sb)*dd - am = (ea-sa)*dd - - draw_rect = pygame.draw.rect - for currentw in range((width/2), 0, -1): - pos = (width/2)-currentw - draw_rect(bigSurf, (er + int(rm*currentw), - eg + int(gm*currentw), - eb + int(bm*currentw), - ea + int(am*currentw)), pygame.Rect(pos, pos, 2*currentw, 2*currentw )) - return bigSurf - - -def vertical_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)): - """ - Draws a vertical linear gradient filling the entire surface. Returns a - surface filled with the gradient (numeric is only 2x faster). - Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define - how the color changes. - """ - height = size[1] - bigSurf = pygame.Surface((1,height)).convert_alpha() - color = ColorInterpolator(height, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - for y in range(0, height): - bigSurf.set_at((0,y), color.eval(y+0.1)) - return pygame.transform.scale(bigSurf, size) - - -def horizontal_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)): - """ - Draws a horizontal linear gradient filling the entire surface. Returns a - surface filled with the gradient (numeric is only 2x faster). - Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define - how the color changes. - """ - width = size[0] - bigSurf = pygame.Surface((width, 1)).convert_alpha() - color = ColorInterpolator(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - for y in range(0, width): - bigSurf.set_at((y, 0), color.eval(y+0.1)) - return pygame.transform.scale(bigSurf, size) - -def radial_func(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0)): - """ - Draws a linear raidal gradient on a square sized surface and returns - that surface. - """ - bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha() - if len(colorkey)==3: - colorkey += (0,) - bigSurf.fill(colorkey) - color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - draw_circle = pygame.draw.circle - for rad in range(radius, 0, -1): - draw_circle(bigSurf, color.eval(rad), (radius, radius), rad) - return bigSurf - -def radial_func_offset(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0), offset=(0,0)): - """ - Draws a linear raidal gradient on a square sized surface and returns - that surface. - offset is the amount the center of the gradient is displaced of the center of the image. - Unfotunately this function ignores alpha. - """ - bigSurf = pygame.Surface((2*radius, 2*radius))#.convert_alpha() - - mask = pygame.Surface((2*radius, 2*radius), pygame.SRCALPHA)#.convert_alpha() - mask.fill(colorkey) - mask.set_colorkey((255,0,255)) - pygame.draw.circle(mask, (255,0,255), (radius, radius), radius) - - if len(colorkey)==3: - colorkey += (0,) - bigSurf.fill(colorkey) - - color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - draw_circle = pygame.draw.circle - radi = radius + int(math.hypot(offset[0], offset[1])+1) - for rad in range(radi, 0, -1): - draw_circle(bigSurf, color.eval(rad), (radius+offset[0], radius+offset[1]), rad) - - bigSurf.blit(mask, (0,0)) - bigSurf.set_colorkey(colorkey) - return bigSurf - - -def squared_func(width, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), offset=(0,0)): - """ - Draws a linear sqared gradient on a square sized surface and returns - that surface. - """ - bigSurf = pygame.Surface((width, width)).convert_alpha() - bigSurf.fill((0,0,0,0)) - color = ColorInterpolator(width/2, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - draw_rect = pygame.draw.rect - widthh = width+2*int(max(abs(offset[0]),abs(offset[1]))) - for currentw in range((widthh/2), 0, -1): -## pos = (width/2)-currentw - rect = pygame.Rect(0, 0, 2*currentw, 2*currentw ) - rect.center = (width/2+offset[0], width/2+offset[1]) - draw_rect(bigSurf, color.eval(currentw), rect) - return bigSurf - -def draw_gradient(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): - """ - Instead of returning an Surface, this function draw it directy onto the - given Surface and returns the rect. - """ - dx = endpoint[0]-startpoint[0] - dy = endpoint[1]-startpoint[1] - d = int(round(math.hypot(dx, dy))) - angle = math.degrees( math.atan2(dy, dx) ) - - h = int(2.*math.hypot(*surface.get_size())) - - bigSurf = horizontal_func((d,h), startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - -## bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1) - bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) -## bigSurf.set_colorkey((0,0,0, 0)) - rect = bigSurf.get_rect() - srect = pygame.Rect(rect) - dx = d/2. * math.cos(math.radians(angle)) - dy = d/2. * math.sin(math.radians(angle)) - rect.center = startpoint - rect.move_ip(dx, dy) - if BLEND_MODES_AVAILABLE: - return surface.blit(bigSurf, rect, None, mode) - else: - return surface.blit(bigSurf, rect) - - -def draw_circle(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): - """ - Instead of returning an Surface, this function draw it directy onto the - given Surface and returns the rect. - """ - dx = endpoint[0]-startpoint[0] - dy = endpoint[1]-startpoint[1] - radius = int(round(math.hypot(dx, dy))) - pos = (startpoint[0]-radius, startpoint[1]-radius) - if BLEND_MODES_AVAILABLE: - return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos, None, mode) - else: - return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos) - -def draw_squared(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): - """ - Instead of returning an Surface, this function draw it directy onto the - given Surface and returns the rect. - """ - dx = endpoint[0]-startpoint[0] - dy = endpoint[1]-startpoint[1] - angle = math.degrees( math.atan2(dy, dx) ) - width = 2*int(round(math.hypot(dx, dy))) - - bigSurf = squared_func(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - - bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) -## bigSurf.set_colorkey((0,0,0, 0)) - rect = bigSurf.get_rect() - rect.center = startpoint - if BLEND_MODES_AVAILABLE: - return surface.blit(bigSurf, rect, None, mode) - else: - return surface.blit(bigSurf, rect) - - -def chart(startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), scale=None): - """ - This returns a Surface where the change of the colors over the distance - (the width of the image) is showen as a line. - scale: a float, 1 is not scaling - """ - dx = endpoint[0]-startpoint[0] - dy = endpoint[1]-startpoint[1] - distance = int(round(math.hypot(dx, dy))) - color = ColorInterpolator(distance, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) - bigSurf = pygame.Surface((distance, 256)) - bigSurf.fill((0,)*3) - oldcol = color.eval(0) - for x in range(distance): - r, g, b, a = color.eval(x) - pygame.draw.line(bigSurf, (255, 0, 0, 128), (x-1, oldcol[0]), (x, r)) - pygame.draw.line(bigSurf, (0, 255, 0, 128), (x-1, oldcol[1]), (x, g)) - pygame.draw.line(bigSurf, (0, 0, 255, 128), (x-1, oldcol[2]), (x, b)) - pygame.draw.line(bigSurf, (255, 255, 255, 128), (x-1, oldcol[3]), (x, a)) - oldcol = (r,g,b,a) - if scale: -## return pygame.transform.scale(bigSurf, size) - return pygame.transform.rotozoom(bigSurf, 0, scale) - return pygame.transform.flip(bigSurf, 0, 1) -#------------------------------------------------------------------------------ - - - - -def genericFxyGradient(surf, clip, color1, color2, func, intx, yint, zint=None): - """ - genericFxyGradient(size, color1, color2,func, intx, yint, zint=None) - - some sort of highfield drawer :-) - - surf : surface to draw - clip : rect on surf to draw in - color1 : start color - color2 : end color - func : function z = func(x,y) - xint : interval in x direction where the function is evaluated - yint : interval in y direction where the function is evaluated - zint : if not none same as yint or xint, if None then the max and min value - of func is taken as z-interval - - color = a*func(b*(x+c), d*(y+e))+f - """ - # make shure that x1 self.blinkLength: - self._blinkOffset -= self.blinkLength - self.blinkOn = not self.blinkOn - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] : - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].stopNote(self.notes[i]) - - def drawBackground(self): - self.savedScreen.fill((255,255,255)) - - if self.extendedScale : - self.scaleSize = self.longScaleSize - else: - self.scaleSize = self.shortScaleSize - - self.noteRects = [pygame.Rect(i * self.width / self.scaleSize+self.blitOrigin[0], self.blitOrigin[1], self.width / self.scaleSize + 1, self.height+1) for i in range(self.scaleSize)] - #inflate last noteRect to cover the far right pixels - self.noteRects[-1].width = self.noteRects[-1].width + 1 - - #create bounding rect - self.boundingRect = self.noteRects[0].unionall(self.noteRects) - - #fill the rectangles with a color gradient - #We start with blue - startingHue = 0.66666666666666663 - - for rectNumber in range(self.scaleSize): - colorRatio = float(rectNumber) / (self.scaleSize - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - if self.song != None: - if rectNumber + self.offset == self.highlightedNote: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - else: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.2, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.4, 1) - else: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[rectNumber].size, topColorRgb, bottomColorRgb), self.noteRects[rectNumber]) - - textBlitPoint = (self.noteRects[rectNumber].left+(self.noteRects[rectNumber].width-self.renderedNoteNames[rectNumber].get_width())/2, - self.noteRects[rectNumber].bottom-self.renderedNoteNames[rectNumber].get_height()) - - self.savedScreen.blit(self.renderedNoteNames[rectNumber], textBlitPoint) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[rectNumber], 2) - - - if self.song != None and self.blinkOn: - borderSize = self.borderSize - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 0), self.noteRects[self.highlightedNote-self.offset].inflate(borderSize/2,borderSize/2), borderSize) - - def initializeWiimotes(self): - for loop in self.wiimotes: - if loop.port == None : - loop.port = pygame.midi.Output(loop.portNumber) - self.notes.append(0) - self.buttonDown.append(False) - self.velocityLock.append(False) - - def updateCursorPositionFromJoy(self, joyEvent): - joyName = pygame.joystick.Joystick(joyEvent.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if correctedJoyId < len(self.cursorPositions): - if joyEvent.axis == 0 : - self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1]) - if joyEvent.axis == 1 : - self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) - - def heightToVelocity(self, pos, controllerNumber): - if self.song != None: - if self.boundingRect.collidepoint(pos) and (self.highlightedNote == self.notes[controllerNumber] or self.velocityLock[controllerNumber]): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - if self.easyMode: - velocity = None - else: - velocity = self.minimalVelocity/3 - else: - if self.boundingRect.collidepoint(pos): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - velocity = self.minimalVelocity - return(velocity) - - def widthToNote(self, pos): - nn = 0 - try : - while self.noteRects[nn].collidepoint(pos) == False: - nn = nn + 1 - return(nn + self.offset) - except(IndexError): - return(None) - - def input(self, event): - - if event.type == pygame.QUIT: - for loop in self.wiimotes: - del loop.port - pygame.midi.quit() - sys.exit(0) - - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_q: - self.done = True - - if event.key == pygame.K_i: - self.backToInstrumentChoice = True - self.done = True - - if event.type == pygame.JOYAXISMOTION: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.updateCursorPositionFromJoy(event) - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade: - n = self.widthToNote(pos) - if n != self.notes[correctedJoyId]: - wiimote.stopNote(self.notes[correctedJoyId]) - self.notes[correctedJoyId] = n - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - else: - self.velocityLock[correctedJoyId] = False - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - - if event.type == pygame.JOYBUTTONDOWN : - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if not self.buttonDown[correctedJoyId]: - savedNote = self.notes[correctedJoyId] - self.notes[correctedJoyId] = self.widthToNote(pos) - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - - velocity = self.heightToVelocity(pos, correctedJoyId) - - if velocity != None : - if self.easyMode : - wiimote.stopNote(savedNote) - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.buttonDown[correctedJoyId] = True - - if event.type == pygame.JOYBUTTONUP: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.buttonDown[correctedJoyId] = False - wiimote = self.wiimotes[correctedJoyId] - if not self.easyMode: - wiimote.stopNote(self.notes[correctedJoyId]) - self.velocityLock[correctedJoyId] = False - - if event.type == pygame.MOUSEMOTION: - - self.updateCursorPositionFromMouse(event) - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade: - n = self.widthToNote(pos) - if n != self.notes[correctedJoyId]: - wiimote.stopNote(self.notes[correctedJoyId]) - self.notes[correctedJoyId] = n - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - else: - self.velocityLock[correctedJoyId] = False - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - - if event.type == pygame.MOUSEBUTTONDOWN: - - if event.button == 1: - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if not self.buttonDown[correctedJoyId]: - self.notes[correctedJoyId] = self.widthToNote(pos) - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.buttonDown[correctedJoyId] = True - - if event.button == 2: - - self.done = True - - if event.type == pygame.MOUSEBUTTONUP: - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - wiimote.stopNote(self.notes[correctedJoyId]) - self.buttonDown[correctedJoyId] = False - self.velocityLock[correctedJoyId] = False - - def hasChanged(self): - changed = False - if self.song != None: - if self.blinkOn != self.savedBlinkOn or self.highlightedNote != self.savedHighlightedNote: - self.savedBlinkOn = self.blinkOn - self.savedHighlightedNote = self.highlightedNote - changed = True - return(changed) - - def updateCursorPositionFromMouse(self, mouseEvent): - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - self.cursorPositions[correctedJoyId] = mouseEvent.pos - - def moveToNextNote(self): - while True: - if self.song == None: - yield(None) - else: - for note in self.song: - yield note diff --git a/src/gui/SongFamiliarizer.py b/src/gui/SongFamiliarizer.py deleted file mode 100644 index 69ab03c..0000000 --- a/src/gui/SongFamiliarizer.py +++ /dev/null @@ -1,583 +0,0 @@ -''' -Created on 23 juil. 2009 - -@author: Samuel Benveniste -''' -from math import floor, ceil -import pygame -import sys -import colorsys -import constants -from gradients import gradients -from logging.PickleableEvent import PickleableEvent -from logging.EventLog import EventLog - - -class SongFamiliarizer: - ''' - The screen on which the game is played - - wiimotes: - The wiimotes used in this session - window: - The main display window - screen: - The main display surface - clock: - The clock used to animate the screen - savedScreen: - The background that is painted every time - playerScreen: - The buffer for painting everything before bliting - width: - The width of the window in pixels - height: - The height of the window in pixels - extendScale : - True if the scale is G to C instead of C to C - cascade: - True if crossing from note to note with a button pressed triggers a new note - scaleSize: - The size of the scale used - cursorPositions: - The positions of the cursors on the screen, in pixels - ''' - - - - def __init__(self, wiimotes, window, screen, clock, joys, portOffset, song, activeWiimotes, cascade=False, extendedScale=False, easyMode = False, replay = False, eventLog = None, defaultInstrumentChannel = 16, defaultNote = 60): - ''' - Constructor - ''' - self.firstClickTime = None - self.firstClickInTime = None - self.duration = None - self.clicks = 0 - self.clicksIn = 0 - - pygame.font.init() - self.font = pygame.font.Font(None,60) - self.congratulations = ["Bien !","Tres Bien !","Bravo !","Excellent !","Felicitations !"] - self.renderedCongratulations = [self.font.render(congratulation,False,(0,0,0)) for congratulation in self.congratulations] - self.congratulationCount = None - self.isCongratulating = False - self.congratulationTimer = 0 - self.congratulationLength = 2000 - self.congratulationPos = None - - self.blinkLength = 200 - self.minimalVelocity = 90 - self.shortScaleSize = 8 - self.longScaleSize = 11 - if not extendedScale: - self.offset = self.longScaleSize - self.shortScaleSize - else: - self.offset = 0 - self.borderSize = 5 - self.highlightedNote = 0 - self.highlightedNoteNumber = 0 - self.syllabus = None - self.savedHighlightedNote = 0 - self.scaleFactor = 1 - self.level = 3 - - self.wiimotes = wiimotes - self.activeWiimotes = activeWiimotes - self.window = window - self.screen = screen - self.width = int(floor(screen.get_width()*self.scaleFactor)) - self.height = int(floor(screen.get_height()*self.scaleFactor)) - self.blitOrigin = ((self.screen.get_width()-self.width)/2,(self.screen.get_height()-self.height)/2) - self.joys = joys - self.clock = clock - self.cursorPositions = [] - self.savedScreen = pygame.Surface(self.screen.get_size()) - self.savedScreen.fill((255,255,255)) - self.playerScreen = pygame.Surface(self.savedScreen.get_size()) - self.playerScreen.blit(self.savedScreen, (0, 0)) - self.extendedScale = extendedScale - self.cascade = cascade - self.portOffset =portOffset - self.eventLog = eventLog - self.song = song - self.songIterator = self.song.getSongIterator() - self.midiNoteNumbers = self.song.scale - self.replay = replay - self.quarterNoteLength = 800 - self.cascadeLockLengthMultiplier = 1 - self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier - - self.defaultInstrumentChannel = defaultInstrumentChannel - self.defaultNote = defaultNote - - self.done = False - self.backToInstrumentChoice = False - self.easyMode = easyMode - - if eventLog == None: - self.eventLog = EventLog() - self.replay = False - else: - self.eventLog = eventLog - self.replay = replay - - #Initializes the highlightedNote and highlightedNoteNumber etc... - self.moveToNextNote() - - self.blinkOn = False - self.savedBlinkOn = False - ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two - ##i.e. it guarantees that there will be an attack between two identical consecutive notes - self.highlightIsFree = True - - self.noteRects = [] - self.boundingRect = None - self.notes = [] - - self.buttonDown = [] - self.velocityLock = [] - - self._blinkOffset = 0 - self._cascadeLockTimer = 0 - self.cascadeIsFree = True - - self.font = pygame.font.Font(None,50) - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers] - - self.drawBackground() - self.initializeWiimotes() - - events = pygame.event.get() - - #The main loop - while not self.done : - - #Clear the cursors from the screen - if self.hasChanged(): - self.drawBackground() - self.playerScreen.blit(self.savedScreen, (0, 0)) - - # Limit frame speed to 50 FPS - # - timePassed = self.clock.tick(10000) - - self._blinkOffset += timePassed - if self.buttonDown and not self.cascadeIsFree : - self._cascadeLockTimer += timePassed - if self._cascadeLockTimer > self.cascadeLockLength : - self.cascadeIsFree = True - - - if self._blinkOffset > self.blinkLength: - self._blinkOffset -= self.blinkLength - self.blinkOn = not self.blinkOn - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - if self.isCongratulating : - self.congratulationTimer += timePassed - if self.congratulationTimer < self.congratulationLength : - self.blitCongratulation() - else : - self.isCongratulating = False - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] : - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]]) - if self.replay : - self.duration = self.eventLog.getCurrentTime() - - def drawBackground(self): - self.savedScreen.fill((255,255,255)) - - if self.extendedScale : - self.scaleSize = self.longScaleSize - else: - self.scaleSize = self.shortScaleSize - - self.noteRects = [pygame.Rect(i * self.width / self.scaleSize+self.blitOrigin[0], self.blitOrigin[1], self.width / self.scaleSize + 1, self.height+1) for i in range(self.scaleSize)] - #inflate last noteRect to cover the far right pixels - self.noteRects[-1].width = self.noteRects[-1].width + 1 - - self.noteRects[self.highlightedNote-self.offset].inflate_ip(self.noteRects[self.highlightedNote-self.offset].width*2,0) - - #create bounding rect - self.boundingRect = self.noteRects[0].unionall(self.noteRects) - - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers] - - #fill the rectangles with a color gradient - #We start with blue - startingHue = 0.66666666666666663 - -# for rectNumber in range(self.scaleSize): -# colorRatio = float(rectNumber) / (self.scaleSize - 1) -# #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up -# hue = startingHue * (1 - colorRatio) -# if rectNumber + self.offset != self.highlightedNote: -# #The color of the bottom of the rectangle in hls coordinates -# bottomColorHls = (hue, 0.1, 1) -# #The color of the top of the rectangle in hls coordinates -# topColorHls = (hue, 0.1, 1) -# -# #convert to rgb ranging from 0 to 255 -# bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] -# topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] -# #add transparency -# bottomColorRgb.append(255) -# topColorRgb.append(255) -# #convert to tuple -# bottomColorRgb = tuple(bottomColorRgb) -# topColorRgb = tuple(topColorRgb) -# -# self.savedScreen.blit(gradients.vertical(self.noteRects[rectNumber].size, topColorRgb, bottomColorRgb), self.noteRects[rectNumber]) -# -# noteNameBlitPoint = (self.noteRects[rectNumber].left+(self.noteRects[rectNumber].width-self.renderedNoteNames[rectNumber].get_width())/2, -# self.noteRects[rectNumber].bottom-self.renderedNoteNames[rectNumber].get_height()) -# -# self.savedScreen.blit(self.renderedNoteNames[rectNumber], noteNameBlitPoint) -# -# pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[rectNumber], 2) - - colorRatio = float(self.highlightedNote-self.offset) / (self.scaleSize - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[self.highlightedNote-self.offset].size, topColorRgb, bottomColorRgb), self.noteRects[self.highlightedNote-self.offset]) - -# noteNameBlitPoint = (self.noteRects[self.highlightedNote-self.offset].left+(self.noteRects[self.highlightedNote-self.offset].width-self.renderedNoteNames[self.highlightedNote-self.offset].get_width())/2, -# self.noteRects[self.highlightedNote-self.offset].bottom-self.renderedNoteNames[self.highlightedNote-self.offset].get_height()) -# -# self.savedScreen.blit(self.renderedNoteNames[self.highlightedNote-self.offset], noteNameBlitPoint) -# -# if self.syllabus : -# renderedSyllabus = self.font.render(self.syllabus,False,(0,0,0)) -# -# syllabusBlitPoint = (self.noteRects[self.highlightedNote-self.offset].left+(self.noteRects[self.highlightedNote-self.offset].width-renderedSyllabus.get_width())/2, -# self.noteRects[self.highlightedNote-self.offset].centery-renderedSyllabus.get_height()/2) -# -# self.savedScreen.blit(renderedSyllabus, syllabusBlitPoint) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[self.highlightedNote-self.offset], 2) - -# if self.song != None and self.blinkOn: -# borderSize = self.borderSize -# pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 0), self.noteRects[self.highlightedNote-self.offset].inflate(borderSize/2,borderSize/2), borderSize) - - def initializeWiimotes(self): - for loop in self.wiimotes: - if loop.port == None : - loop.port = pygame.midi.Output(loop.portNumber) - self.notes.append(0) - self.cursorPositions.append(loop.cursor.centerPosition) - self.buttonDown.append(False) - self.velocityLock.append(False) - - def updateCursorPositionFromJoy(self, joyEvent): - joyName = pygame.joystick.Joystick(joyEvent.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if correctedJoyId < len(self.cursorPositions): - if joyEvent.axis == 0 : - self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1]) - if joyEvent.axis == 1 : - self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) - - def heightToVelocity(self, pos, controllerNumber): - if self.song != None: - if self.boundingRect.collidepoint(pos) and (self.highlightedNote == self.notes[controllerNumber] or self.velocityLock[controllerNumber]): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - if self.easyMode: - velocity = None - else: - velocity = 60 - else: - if self.boundingRect.collidepoint(pos): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - velocity = self.minimalVelocity - return(velocity) - - def widthToNote(self, pos): - nn = 0 - try : - if self.noteRects[self.highlightedNote-self.offset].collidepoint(pos) : - return self.highlightedNote - else : - while self.noteRects[nn].collidepoint(pos) == False: - nn = nn + 1 - return(nn + self.offset) - except(IndexError): - return(None) - - def congratulate(self,targetRect,posy): - if self.congratulationCount != None : - if self.congratulationCount < len(self.congratulations)-1: - self.congratulationCount += 1 - else : - self.congratulationCount = 0 - self.congratulationTimer = 0 - self.congratulationPos = (targetRect.left+(targetRect.width-self.renderedCongratulations[self.congratulationCount].get_width())/2,posy) - self.isCongratulating = True - - def resetCongratulation(self): - self.congratulationCount = None - self.congratulationPos = None - self.isCongratulating = False - - def blitCongratulation(self): - self.playerScreen.blit(self.renderedCongratulations[self.congratulationCount],self.congratulationPos) - - def input(self, event): - - if event.type == pygame.QUIT: - for loop in self.wiimotes: - del loop.port - pygame.midi.quit() - sys.exit(0) - - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_q: - self.nextLevel = None - self.done = True - - if event.key == pygame.K_w: - self.nextLevel = 0 - self.done = True - - if event.key == pygame.K_e: - self.nextLevel = 1 - self.done = True - - if event.key == pygame.K_r: - self.nextLevel = 2 - self.done = True - - if event.key == pygame.K_t: - self.nextLevel = 3 - self.done = True - - if event.type == pygame.JOYAXISMOTION: - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.updateCursorPositionFromJoy(event) - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade and self.cascadeIsFree : - n = self.widthToNote(pos) - if self.highlightedNote == n: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.moveToNextNote() - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - - if event.type == pygame.JOYBUTTONDOWN : - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - self.wiimotes[correctedJoyId].cursor.flash() - if self.replay: - self.clicks += 1 - if self.firstClickTime == None : - self.firstClickTime = self.eventLog.getCurrentTime() - - if not self.buttonDown[correctedJoyId]: - n = self.widthToNote(pos) - if self.highlightedNote == n: - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - if self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.congratulate(self.noteRects[self.notes[correctedJoyId]],pos[1]) - if self.replay: - self.clicksIn += 1 - if self.firstClickInTime == None : - self.firstClickInTime = self.eventLog.getCurrentTime() - - self.moveToNextNote() - else : - self.resetCongratulation() - if not self.easyMode : - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.buttonDown[correctedJoyId] = True - - if event.type == pygame.JOYBUTTONUP: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.buttonDown[correctedJoyId] = False - wiimote = self.wiimotes[correctedJoyId] - if not self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.velocityLock[correctedJoyId] = False - - if event.type == pygame.MOUSEMOTION: - - self.updateCursorPositionFromMouse(event) - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - self.wiimotes[correctedJoyId].cursor.flash() - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade and self.cascadeIsFree : - n = self.widthToNote(pos) - if self.highlightedNote == n: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.moveToNextNote() - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - - if event.type == pygame.MOUSEBUTTONDOWN: - - if event.button == 1: - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - self.wiimotes[correctedJoyId].cursor.flash() - if self.replay: - self.clicks += 1 - if self.firstClickTime == None : - self.firstClickTime = self.eventLog.getCurrentTime() - - if not self.buttonDown[correctedJoyId]: - n = self.widthToNote(pos) - if self.highlightedNote == n: - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - if self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.congratulate(self.noteRects[self.notes[correctedJoyId]],pos[1]) - if self.replay: - self.clicksIn += 1 - if self.firstClickInTime == None : - self.firstClickInTime = self.eventLog.getCurrentTime() - - self.moveToNextNote() - else : - self.resetCongratulation() - if not self.easyMode : - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.buttonDown[correctedJoyId] = True - - if event.button == 2: - - self.done = True - - if event.type == pygame.MOUSEBUTTONUP: - if event.button == 1 : - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - self.buttonDown[correctedJoyId] = False - if not self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.velocityLock[correctedJoyId] = False - - def hasChanged(self): - changed = False - if self.song != None: - if self.blinkOn != self.savedBlinkOn or self.highlightedNote != self.savedHighlightedNote: - self.savedBlinkOn = self.blinkOn - self.savedHighlightedNote = self.highlightedNote - changed = True - return(changed) - - def updateCursorPositionFromMouse(self, mouseEvent): - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - self.cursorPositions[correctedJoyId] = mouseEvent.pos - - def moveToNextNote(self): - self.savedMidiNoteNumbers = self.midiNoteNumbers[:] - self.highlightedNote, self.highlightedNoteNumber, self.syllabus, self.cascadeLockLengthMultiplier = self.songIterator.next() - self.midiNoteNumbers[self.highlightedNote] = self.highlightedNoteNumber diff --git a/src/gui/SongPlayingScreen.py b/src/gui/SongPlayingScreen.py deleted file mode 100644 index a64adb6..0000000 --- a/src/gui/SongPlayingScreen.py +++ /dev/null @@ -1,736 +0,0 @@ -''' -Created on 23 juil. 2009 - -@author: Samuel Benveniste -''' -from math import floor, ceil -import pygame -import sys -import colorsys -import constants -from gradients import gradients -from logging.PickleableEvent import PickleableEvent -from songs.Song import Song -from songs.musicxmltosong import Part - - -class SongPlayingScreen: - ''' - The screen on which the game is played - - wiimotes: - The wiimotes used in this session - window: - The main display window - screen: - The main display surface - clock: - The clock used to animate the screen - savedScreen: - The background that is painted every time - playerScreen: - The buffer for painting everything before bliting - width: - The width of the window in pixels - height: - The height of the window in pixels - extendScale : - True if the scale is G to C instead of C to C - cascade: - True if crossing from note to note with a button pressed triggers a new note - scaleSize: - The size of the scale used - cursorPositions: - The positions of the cursors on the screen, in pixels - ''' - - - - def __init__(self, instrumentChoice, pguconf):# song, cascade=False, extendedScale=False, easyMode = False, alwaysDown = False, eventLog = None, replay = None, defaultInstrumentChannel = 16, defaultNote = 60): - ''' - Constructor - ''' - song = pguconf.song - cascade = pguconf.cascade - extendedScale = song.requiresExtendedScale - easyMode = pguconf.easyMode - alwaysDown = pguconf.alwaysDown - eventLog = instrumentChoice.eventLog - replay = instrumentChoice.replay - defaultInstrumentChannel = 16 - defaultNote = 60 - - if isinstance(song, Song) : - self.songDurations = [] - self.totalDuration = None - self.clicks = [0] - self.clicksIn = [0] - self.clicksPerMinute = [0] - self.clicksInPerMinute = [0] - self.meanTimeBetweenNotes = [] - self.firstClick = None - self.firstClickIn = None - - self.blinkLength = 200 - self.minimalVelocity = 90 - self.shortScaleSize = 8 - self.longScaleSize = 11 - if not extendedScale: - self.offset = self.longScaleSize - self.shortScaleSize - else: - self.offset = 0 - self.borderSize = 5 - self.highlightedNote = 0 - self.highlightedNoteNumber = 0 - self.syllabus = None - self.savedHighlightedNote = 0 - self.alwaysDown = alwaysDown - self.nextLevel = None - - self.wiimotes = instrumentChoice.wiimotes - self.activeWiimotes = instrumentChoice.activeWiimotes - self.window = instrumentChoice.window - self.screen = instrumentChoice.screen - self.blitOrigin = instrumentChoice.blitOrigin - self.clock = instrumentChoice.clock - self.width = instrumentChoice.width - self.height = instrumentChoice.height - self.cursorPositions = instrumentChoice.cursorPositions - self.savedScreen = instrumentChoice.savedScreen - self.playerScreen = instrumentChoice.playerScreen - self.extendedScale = extendedScale - self.cascade = cascade - self.joys = instrumentChoice.joys - self.portOffset = instrumentChoice.portOffset - if eventLog == None : - self.eventLog = instrumentChoice.eventLog - else : - self.eventLog = eventLog - self.cursorPositions = instrumentChoice.cursorPositions - self.song = song - self.songIterator = self.song.getSongIterator() - self.midiNoteNumbers = self.song.scale - if replay == None : - self.replay = instrumentChoice.replay - else : - self.replay = replay - self.quarterNoteLength = song.quarterNoteLength - self.cascadeLockLengthMultiplier = 1 - self.nextCascadeLockLengthMultiplier = 1 - self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier - - self.defaultInstrumentChannel = defaultInstrumentChannel - self.defaultNote = defaultNote - - self.done = False - self.backToInstrumentChoice = False - self.easyMode = easyMode - - #Initializes the highlightedNote and highlightedNoteNumber etc... - self.moveToNextNote() - self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier - - self.blinkOn = False - self.savedBlinkOn = False - ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two - ##i.e. it guarantees that there will be an attack between two identical consecutive notes - self.highlightIsFree = True - - self.noteRects = [] - self.boundingRect = None - self.notes = [] - - self.buttonDown = [] - self.velocityLock = [] - - self._blinkOffset = 0 - self._cascadeLockTimer = 0 - self.cascadeIsFree = True - - self.font = pygame.font.Font(None,80) - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers] - - self.drawBackground() - self.initializeWiimotes() - - self.songStartTime = self.eventLog.getCurrentTime() - - #The main loop - while not self.done : - - #Clear the cursors from the screen - if self.hasChanged(): - self.drawBackground() - self.playerScreen.blit(self.savedScreen, (0, 0)) - - # Limit frame speed to 50 FPS - # - timePassed = self.clock.tick(10000) - - self._blinkOffset += timePassed - if (self.buttonDown or self.alwaysDown) and not self.cascadeIsFree : - self._cascadeLockTimer += timePassed - if self._cascadeLockTimer > self.cascadeLockLengthMultiplier*self.quarterNoteLength : - self.cascadeIsFree = True - self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier - - - if self._blinkOffset > self.blinkLength: - self._blinkOffset -= self.blinkLength - self.blinkOn = not self.blinkOn - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] or self.alwaysDown: - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]]) - if self.replay : - self.totalDuration = self.eventLog.getCurrentTime() - - elif isinstance(song, Part) : - self.songDurations = [] - self.totalDuration = None - self.clicks = [0] - self.clicksIn = [0] - self.clicksPerMinute = [0] - self.clicksInPerMinute = [0] - self.meanTimeBetweenNotes = [] - self.firstClick = None - self.firstClickIn = None - - self.blinkLength = 200 - self.minimalVelocity = 90 - self.shortScaleSize = 8 - self.longScaleSize = 11 - if not extendedScale: - self.offset = self.longScaleSize - self.shortScaleSize - else: - self.offset = 0 - self.borderSize = 5 - self.highlightedNote = 0 - self.highlightedNoteNumber = 0 - self.syllabus = None - self.savedHighlightedNote = 0 - self.alwaysDown = alwaysDown - self.nextLevel = None - - self.wiimotes = instrumentChoice.wiimotes - self.activeWiimotes = instrumentChoice.activeWiimotes - self.window = instrumentChoice.window - self.screen = instrumentChoice.screen - self.blitOrigin = instrumentChoice.blitOrigin - self.clock = instrumentChoice.clock - self.width = instrumentChoice.width - self.height = instrumentChoice.height - self.cursorPositions = instrumentChoice.cursorPositions - self.savedScreen = instrumentChoice.savedScreen - self.playerScreen = instrumentChoice.playerScreen - self.extendedScale = extendedScale - self.cascade = cascade - self.joys = instrumentChoice.joys - self.portOffset = instrumentChoice.portOffset - if eventLog == None : - self.eventLog = instrumentChoice.eventLog - else : - self.eventLog = eventLog - self.cursorPositions = instrumentChoice.cursorPositions - self.song = song - self.songIterator = self.song.iterNotes() - self.midiNoteNumbers = self.song.scale - if replay == None : - self.replay = instrumentChoice.replay - else : - self.replay = replay - self.quarterNoteLength = song.quarterNoteLength - self.cascadeLockLengthMultiplier = 1 - self.nextCascadeLockLengthMultiplier = 1 - self.cascadeLockLength = self.quarterNoteLength * self.cascadeLockLengthMultiplier - - self.defaultInstrumentChannel = defaultInstrumentChannel - self.defaultNote = defaultNote - - self.done = False - self.backToInstrumentChoice = False - self.easyMode = easyMode - - #Initializes the highlightedNote and highlightedNoteNumber etc... - self.moveToNextNote() - self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier - - self.blinkOn = False - self.savedBlinkOn = False - ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two - ##i.e. it guarantees that there will be an attack between two identical consecutive notes - self.highlightIsFree = True - - self.noteRects = [] - self.boundingRect = None - self.notes = [] - - self.buttonDown = [] - self.velocityLock = [] - - self._blinkOffset = 0 - self._cascadeLockTimer = 0 - self.cascadeIsFree = True - - self.font = pygame.font.Font(None,80) - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers] - - self.drawBackground() - self.initializeWiimotes() - - self.songStartTime = self.eventLog.getCurrentTime() - - #The main loop - while not self.done : - - #Clear the cursors from the screen - if self.hasChanged(): - self.drawBackground() - self.playerScreen.blit(self.savedScreen, (0, 0)) - - # Limit frame speed to 50 FPS - # - timePassed = self.clock.tick(10000) - - self._blinkOffset += timePassed - if (self.buttonDown or self.alwaysDown) and not self.cascadeIsFree : - self._cascadeLockTimer += timePassed - if self._cascadeLockTimer > self.cascadeLockLengthMultiplier*self.quarterNoteLength : - self.cascadeIsFree = True - self.cascadeLockLengthMultiplier = self.nextCascadeLockLengthMultiplier - - - if self._blinkOffset > self.blinkLength: - self._blinkOffset -= self.blinkLength - self.blinkOn = not self.blinkOn - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] or self.alwaysDown: - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].stopNoteByNoteNumber(self.midiNoteNumbers[self.notes[i]]) - if self.replay : - self.totalDuration = self.eventLog.getCurrentTime() - - def drawBackground(self): - self.savedScreen.fill((255,255,255)) - - if self.extendedScale : - self.scaleSize = self.longScaleSize - else: - self.scaleSize = self.shortScaleSize - - self.noteRects = [pygame.Rect(i * self.width / self.scaleSize+self.blitOrigin[0], self.blitOrigin[1], self.width / self.scaleSize + 1, self.height+1) for i in range(self.scaleSize)] - #inflate last noteRect to cover the far right pixels - self.noteRects[-1].width = self.noteRects[-1].width + 1 - - self.noteRects[self.highlightedNote-self.offset].inflate_ip(self.noteRects[self.highlightedNote-self.offset].width*2,0) - - #create bounding rect - self.boundingRect = self.noteRects[0].unionall(self.noteRects) - - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.midiNoteNumbers] - - #fill the rectangles with a color gradient - #We start with blue - startingHue = 0.66666666666666663 - - for rectNumber in range(self.scaleSize): - colorRatio = float(rectNumber) / (self.scaleSize - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - if rectNumber + self.offset != self.highlightedNote: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.1, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.1, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[rectNumber].size, topColorRgb, bottomColorRgb), self.noteRects[rectNumber]) - - noteNameBlitPoint = (self.noteRects[rectNumber].left+(self.noteRects[rectNumber].width-self.renderedNoteNames[rectNumber+self.offset].get_width())/2, - self.noteRects[rectNumber].bottom-self.renderedNoteNames[rectNumber+self.offset].get_height()) - - self.savedScreen.blit(self.renderedNoteNames[rectNumber+self.offset], noteNameBlitPoint) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[rectNumber], 2) - - colorRatio = float(self.highlightedNote-self.offset) / (self.scaleSize - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[self.highlightedNote-self.offset].size, topColorRgb, bottomColorRgb), self.noteRects[self.highlightedNote-self.offset]) - - noteNameBlitPoint = (self.noteRects[self.highlightedNote-self.offset].left+(self.noteRects[self.highlightedNote-self.offset].width-self.renderedNoteNames[self.highlightedNote].get_width())/2, - self.noteRects[self.highlightedNote-self.offset].bottom-self.renderedNoteNames[self.highlightedNote].get_height()) - - self.savedScreen.blit(self.renderedNoteNames[self.highlightedNote], noteNameBlitPoint) - - if self.syllabus : - renderedSyllabus = self.font.render(self.syllabus,False,(0,0,0)) - - syllabusBlitPoint = (self.noteRects[self.highlightedNote-self.offset].left+(self.noteRects[self.highlightedNote-self.offset].width-renderedSyllabus.get_width())/2, - self.noteRects[self.highlightedNote-self.offset].centery-renderedSyllabus.get_height()/2) - - self.savedScreen.blit(renderedSyllabus, syllabusBlitPoint) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[self.highlightedNote-self.offset], 2) - - if self.song != None and self.blinkOn: - borderSize = self.borderSize - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 0), self.noteRects[self.highlightedNote-self.offset].inflate(borderSize/2,borderSize/2), borderSize) - - def initializeWiimotes(self): - for loop in self.wiimotes: - if loop.port == None : - loop.port = pygame.midi.Output(loop.portNumber) - self.notes.append(0) - self.buttonDown.append(False) - self.velocityLock.append(False) - - def updateCursorPositionFromJoy(self, joyEvent): - joyName = pygame.joystick.Joystick(joyEvent.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if correctedJoyId < len(self.cursorPositions): - if joyEvent.axis == 0 : - self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1]) - if joyEvent.axis == 1 : - self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) - - def heightToVelocity(self, pos, controllerNumber): - if self.song != None: - if self.boundingRect.collidepoint(pos) and (self.highlightedNote == self.notes[controllerNumber] or self.velocityLock[controllerNumber]): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - if self.easyMode: - velocity = None - else: - velocity = 60 - else: - if self.boundingRect.collidepoint(pos): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - velocity = self.minimalVelocity - return(velocity) - - def widthToNote(self, pos): - nn = 0 - try : - if self.noteRects[self.highlightedNote-self.offset].collidepoint(pos) : - return self.highlightedNote - else : - while self.noteRects[nn].collidepoint(pos) == False: - nn = nn + 1 - return(nn + self.offset) - except(IndexError): - return(None) - - def logClick(self): - self.clicks[-1] += 1 - if self.firstClick == None : - self.firstClick = self.eventLog.getCurrentTime() - minute = int(floor((self.eventLog.getCurrentTime()-self.songStartTime)/60000)) - if minute > len(self.clicksPerMinute)-1: - self.clicksPerMinute.append(0) - self.clicksPerMinute[-1] += 1 - - def logClickIn(self): - self.clicksIn[-1] += 1 - if self.clicksIn[-1] > len(self.song.notes)-1 : - self.clicksIn.append(0) - self.clicks.append(0) - self.songDurations.append(self.eventLog.getCurrentTime()) - if self.firstClickIn == None : - self.firstClickIn = self.eventLog.getCurrentTime() - minute = int(floor((self.eventLog.getCurrentTime()-self.songStartTime)/60000)) - if minute > len(self.clicksInPerMinute)-1: - self.clicksInPerMinute.append(0) - self.clicksInPerMinute[-1]+=1 - - def input(self, event): - - if event.type == pygame.QUIT: - for loop in self.wiimotes: - del loop.port - pygame.midi.quit() - sys.exit(0) - - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_q: - self.nextLevel = None - self.done = True - - if event.key == pygame.K_i: - self.backToInstrumentChoice = True - self.done = True - - if event.key == pygame.K_w: - self.nextLevel = 0 - self.done = True - - if event.key == pygame.K_e: - self.nextLevel = 1 - self.done = True - - if event.key == pygame.K_r: - self.nextLevel = 2 - self.done = True - - if event.key == pygame.K_t: - self.nextLevel = 3 - self.done = True - - if event.type == pygame.JOYAXISMOTION: - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.updateCursorPositionFromJoy(event) - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if (self.buttonDown[correctedJoyId] or self.alwaysDown): - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade and self.cascadeIsFree : - n = self.widthToNote(pos) - if self.highlightedNote == n: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.moveToNextNote() - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - - if event.type == pygame.JOYBUTTONDOWN : - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - self.wiimotes[correctedJoyId].cursor.flash() - if self.replay: - self.logClick() - - if not (self.buttonDown[correctedJoyId] or self.alwaysDown): - n = self.widthToNote(pos) - if self.highlightedNote == n: - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - if self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - if self.replay : - self.logClickIn() - self.moveToNextNote() - else : - if not self.easyMode : - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None and self.notes[correctedJoyId] != None : - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.buttonDown[correctedJoyId] = True - - if event.type == pygame.JOYBUTTONUP: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.buttonDown[correctedJoyId] = False - wiimote = self.wiimotes[correctedJoyId] - if not self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.velocityLock[correctedJoyId] = False - - if event.type == pygame.MOUSEMOTION: - - self.updateCursorPositionFromMouse(event) - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if (self.buttonDown[correctedJoyId] or self.alwaysDown): - self.wiimotes[correctedJoyId].cursor.flash() - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None : - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade and self.cascadeIsFree : - n = self.widthToNote(pos) - if self.highlightedNote == n: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.moveToNextNote() - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - - if event.type == pygame.MOUSEBUTTONDOWN: - - if event.button == 1: - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - self.wiimotes[correctedJoyId].cursor.flash() - if self.replay: - self.logClick() - - if not (self.buttonDown[correctedJoyId] or self.alwaysDown): - n = self.widthToNote(pos) - if self.highlightedNote == n: - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - if self.easyMode: - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - self.velocityLock[correctedJoyId] = True - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - if self.replay : - self.logClickIn() - self.moveToNextNote() - else : - if not self.easyMode : - self._cascadeLockTimer = 0 - self.cascadeIsFree = False - self.notes[correctedJoyId] = n - velocity = self.heightToVelocity(pos, correctedJoyId) - if velocity != None and self.notes[correctedJoyId] != None : - wiimote.playNoteByNoteNumber(self.midiNoteNumbers[self.notes[correctedJoyId]],velocity) - self.buttonDown[correctedJoyId] = True - - if event.button == 2: - - self.done = True - - if event.type == pygame.MOUSEBUTTONUP: - if event.button == 1 : - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - self.buttonDown[correctedJoyId] = False - if not self.easyMode: - if self.notes[correctedJoyId] != None : - wiimote.stopNoteByNoteNumber(self.savedMidiNoteNumbers[self.notes[correctedJoyId]]) - self.velocityLock[correctedJoyId] = False - - def hasChanged(self): - changed = False - if self.song != None: - if self.blinkOn != self.savedBlinkOn or self.highlightedNote != self.savedHighlightedNote: - self.savedBlinkOn = self.blinkOn - self.savedHighlightedNote = self.highlightedNote - changed = True - return(changed) - - def updateCursorPositionFromMouse(self, mouseEvent): - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - self.cursorPositions[correctedJoyId] = mouseEvent.pos - - def moveToNextNote(self): - self.savedMidiNoteNumbers = self.midiNoteNumbers[:] - note, lyricIndex = self.songIterator.next() - self.highlightedNote = note.column - self.highlightedNoteNumber = note.midi - self.syllabus = note.lyrics[lyricIndex].syllabus('iso-8859-1') - self.nextCascadeLockLengthMultiplier = note.duration - self.midiNoteNumbers[self.highlightedNote] = self.highlightedNoteNumber - - #self.highlightedNote, self.highlightedNoteNumber, self.syllabus, self.nextCascadeLockLengthMultiplier = self.songIterator.next() - #self.midiNoteNumbers[self.highlightedNote] = self.highlightedNoteNumber diff --git a/src/gui/StaticFamiliarizer.py b/src/gui/StaticFamiliarizer.py deleted file mode 100644 index 0e095c8..0000000 --- a/src/gui/StaticFamiliarizer.py +++ /dev/null @@ -1,457 +0,0 @@ -''' -Created on 23 juil. 2009 - -@author: Samuel Benveniste -''' -from math import floor, ceil -import pygame -import pygame.midi -import sys -import colorsys -import constants -from gradients import gradients -from logging.PickleableEvent import PickleableEvent -from instruments.Instrument import Instrument -from cursor.WarpingCursor import * -from controllers.Wiimote import Wiimote -from logging.EventLog import EventLog - - -class StaticFamiliarizer: - ''' - The screen on which the game is played - - wiimotes: - The wiimotes used in this session - window: - The main display window - screen: - The main display surface - clock: - The clock used to animate the screen - savedScreen: - The background that is painted every time - playerScreen: - The buffer for painting everything before bliting - width: - The width of the window in pixels - height: - The height of the window in pixels - extendScale : - True if the scale is G to C instead of C to C - cascade: - True if crossing from note to note with a button pressed triggers a new note - scaleSize: - The size of the scale used - cursorPositions: - The positions of the cursors on the screen, in pixels - ''' - - - - def __init__(self, wiimotes, window, screen, clock, joys, portOffset,activeWiimotes,replay = False, level = 0, defaultInstrumentChannel = 16, defaultNote = 60, eventLog = None): - ''' - Constructor - ''' - self.firstClickTime = None - self.firstClickInTime = None - self.duration = None - self.clicks = 0 - self.clicksIn = 0 - - pygame.font.init() - self.font = pygame.font.Font(None,60) - self.congratulations = ["Bien !","Tres Bien !","Bravo !","Excellent !","Felicitations !"] - self.renderedCongratulations = [self.font.render(congratulation,False,(0,0,0)) for congratulation in self.congratulations] - self.congratulationCount = None - self.isCongratulating = False - self.congratulationTimer = 0 - self.congratulationLength = 2000 - self.congratulationPos = None - - self.blinkLength = 200 - self.minimalVelocity = 64 - self.shortScaleSize = 8 - self.longScaleSize = 11 - self.borderSize = 5 - self.savedHighlightedNote = 0 - self.scaleFactor = 1 - self.wiimotes = wiimotes - self.window = window - self.screen = screen - self.clock = clock - self.width = int(floor(screen.get_width()*self.scaleFactor)) - self.height = int(floor(screen.get_height()*self.scaleFactor)) - self.blitOrigin = ((self.screen.get_width()-self.width)/2,(self.screen.get_height()-self.height)/2) - self.joys = joys - self.portOffset = portOffset - self.savedScreen = pygame.Surface(self.screen.get_size()) - self.savedScreen.fill((255,255,255)) - self.playerScreen = pygame.Surface(self.savedScreen.get_size()) - self.playerScreen.blit(self.savedScreen, (0, 0)) - self.cursorPositions = [] - self.level = level - self.nextLevel = None - self.activeWiimotes = activeWiimotes - - for i in range(len(self.wiimotes)): - #Set the screen for the cursors (it can't be set before) - self.wiimotes[i].cursor.screen = self.playerScreen - self.cursorPositions.append(self.wiimotes[i].cursor.centerPosition) - - if eventLog == None: - self.eventLog = EventLog() - self.replay = False - else: - self.eventLog = eventLog - self.replay = replay - - self.defaultInstrumentChannel = defaultInstrumentChannel - self.defaultNote = defaultNote - - self.done = False - self.backToInstrumentChoice = False - self.easyMode = False - - self.noteRects = [] - self.boundingRect = None - self.notes = [] - self.buttonDown = [] - self.velocityLock = [] - - self.drawBackground() - self.initializeWiimotes() - events = pygame.event.get() - - #The main loop - while not self.done : - - self.playerScreen.blit(self.savedScreen, (0, 0)) - - # Limit frame speed to 50 FPS - # - timePassed = self.clock.tick(10000) - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - if self.isCongratulating : - self.congratulationTimer += timePassed - if self.congratulationTimer < self.congratulationLength : - self.blitCongratulation() - else : - self.isCongratulating = False - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] : - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - if self.notes[i] != None : - self.wiimotes[i].stopNote(self.notes[i]) - if self.replay : - self.duration = self.eventLog.getCurrentTime() - - def drawBackground(self): - self.savedScreen.fill((255,255,255)) - if self.level == 0 : - A = [4] - else : - A = [1,7] - - self.noteRects = [pygame.Rect(i * self.width / 11+self.blitOrigin[0], self.blitOrigin[1], (self.width / 11 + 1)*3, self.height+1) for i in A] - - #create bounding rect - self.boundingRect = self.noteRects[0].unionall(self.noteRects) - - #fill the rectangles with a color gradient - #We start with blue - startingHue = 0.66666666666666663 - - for rectNumber in range(len(self.noteRects)) : - colorRatio = float(A[rectNumber]) / (11 - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[rectNumber].size, topColorRgb, bottomColorRgb), self.noteRects[rectNumber]) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[rectNumber], 2) - - def initializeWiimotes(self): - for loop in self.wiimotes: - if loop.port == None : - loop.port = pygame.midi.Output(loop.portNumber) - self.notes.append(0) - self.buttonDown.append(False) - self.velocityLock.append(False) - - def updateCursorPositionFromJoy(self, joyEvent): - joyName = pygame.joystick.Joystick(joyEvent.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if correctedJoyId < len(self.cursorPositions): - if joyEvent.axis == 0 : - self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1]) - if joyEvent.axis == 1 : - self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) - - def heightToVelocity(self, pos, controllerNumber): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - return(velocity) - - def widthToNote(self, pos): - nn = 0 - try : - while self.noteRects[nn].collidepoint(pos) == False: - nn = nn + 1 - return(nn) - except(IndexError): - return(None) - - def congratulate(self,targetRect,posy): - if self.congratulationCount != None : - if self.congratulationCount < len(self.congratulations)-1: - self.congratulationCount += 1 - else : - self.congratulationCount = 0 - self.congratulationTimer = 0 - self.congratulationPos = (targetRect.left+(targetRect.width-self.renderedCongratulations[self.congratulationCount].get_width())/2,posy) - self.isCongratulating = True - - def resetCongratulation(self): - self.congratulationCount = None - self.congratulationPos = None - self.isCongratulating = False - - def blitCongratulation(self): - self.playerScreen.blit(self.renderedCongratulations[self.congratulationCount],self.congratulationPos) - - def input(self, event): - - print event - - if event.type == pygame.QUIT: - for loop in self.wiimotes: - del loop.port - pygame.midi.quit() - sys.exit(0) - - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_q: - self.nextLevel = None - self.done = True - - if event.key == pygame.K_w: - self.nextLevel = 0 - self.done = True - - if event.key == pygame.K_e: - self.nextLevel = 1 - self.done = True - - if event.key == pygame.K_r: - self.nextLevel = 2 - self.done = True - - if event.key == pygame.K_t: - self.nextLevel = 3 - self.done = True - - if event.type == pygame.JOYAXISMOTION: - - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.updateCursorPositionFromJoy(event) - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - wiimote.cursor.flash() - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - - if event.type == pygame.JOYBUTTONDOWN : - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - wiimote.cursor.flash() - if self.replay : - self.clicks += 1 - if self.firstClickTime == None : - self.firstClickTime = self.eventLog.getCurrentTime() - - if not self.buttonDown[correctedJoyId]: - self.notes[correctedJoyId] = self.widthToNote(pos) - - velocity = self.heightToVelocity(pos, correctedJoyId) - - if self.notes[correctedJoyId] != None : - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.congratulate(self.noteRects[self.notes[correctedJoyId]],pos[1]) - if self.replay : - self.clicksIn += 1 - if self.firstClickInTime == None : - self.firstClickInTime = self.eventLog.getCurrentTime() - else : - self.resetCongratulation() - - self.buttonDown[correctedJoyId] = True - - if event.type == pygame.JOYBUTTONUP: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - wiimote.stopNote(self.notes[correctedJoyId]) - self.buttonDown[correctedJoyId] = False - self.velocityLock[correctedJoyId] = False - - if event.type == pygame.MOUSEMOTION: - - self.updateCursorPositionFromMouse(event) - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - wiimote.cursor.flash() - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - - if event.type == pygame.MOUSEBUTTONDOWN: - - if event.button == 1: - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - wiimote.cursor.flash() - if self.replay : - self.clicks += 1 - if self.firstClickTime == None : - self.firstClickTime = self.eventLog.getCurrentTime() - - if not self.buttonDown[correctedJoyId]: - self.notes[correctedJoyId] = self.widthToNote(pos) - - velocity = self.heightToVelocity(pos, correctedJoyId) - - if self.notes[correctedJoyId] != None : - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.congratulate(self.noteRects[self.notes[correctedJoyId]],pos[1]) - if self.replay : - self.clicksIn += 1 - if self.firstClickInTime == None : - self.firstClickInTime = self.eventLog.getCurrentTime() - else : - self.resetCongratulation() - - self.buttonDown[correctedJoyId] = True - - if event.button == 2: - - self.done = True - - if event.type == pygame.MOUSEBUTTONUP: - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - wiimote.stopNote(self.notes[correctedJoyId]) - self.buttonDown[correctedJoyId] = False - self.velocityLock[correctedJoyId] = False - - def hasChanged(self): - return(True) - - def updateCursorPositionFromMouse(self, mouseEvent): - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - self.cursorPositions[correctedJoyId] = mouseEvent.pos - -if __name__ == "__main__" : - pygame.init() - modeResolution = (1024,768) - window = pygame.display.set_mode(modeResolution,pygame.FULLSCREEN) - pygame.font.init() - - pygame.midi.init() - instruments = [Instrument(constants.scaleDict["majorScale"], i + 1, "".join(["../instruments/instrumentImages/", constants.instrumentImagePathList[i], ".jpg"]), constants.octaves[i]) for i in range(9)] - - joys = [[id,pygame.joystick.Joystick(id).get_name()] for id in range(pygame.joystick.get_count())] - for joy in joys: - if joy[1] in constants.joyNames: - pygame.joystick.Joystick(joy[0]).init() - - ports = [pygame.midi.get_device_info(id)[1] for id in range(pygame.midi.get_count())] - portOffset = ports.index(constants.portNames[0]) - print(portOffset) - - events = pygame.event.get() - - screen = pygame.display.get_surface() - clock = pygame.time.Clock() - cursorImages = [createImageListFromPath('../cursor/cursorImages/black', 11),createImageListFromPath('../cursor/cursorImages/red', 11)] - durations = [75 for i in range(len(cursorImages[0]))] - - wiimoteCount = 1 - cursors = [WarpingCursor(None, cursorImages[i], durations, (300 * i, 300 * i),flashImage = '../cursor/cursorImages/black/flash.png' ) for i in range(wiimoteCount)] - wiimotes = [Wiimote(i, i + portOffset, None, instruments[i], cursors[i]) for i in range(wiimoteCount)] - - fam = StaticFamiliarizer(instruments, wiimotes, window, screen, clock, joys, portOffset) - - for loop in fam.wiimotes: - del loop.port - - pygame.midi.quit() - - pygame.quit() diff --git a/src/gui/__init__.py b/src/gui/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/gui/constants.py b/src/gui/constants.py deleted file mode 100755 index f280b5f..0000000 --- a/src/gui/constants.py +++ /dev/null @@ -1,130 +0,0 @@ -from songs.Song import Song#,loadSongFromMidi -from dataTools.odict import OrderedDict - -joyNames = ["PPJoy Virtual joystick 1", "PPJoy Virtual joystick 2", "PPJoy Virtual joystick 3", "PPJoy Virtual joystick 4"] -portNames = ["Out To MIDI Yoke: 1","Out To MIDI Yoke: 2","Out To MIDI Yoke: 3","Out To MIDI Yoke: 4"] - -readabilityDict = OrderedDict([("majeure" , "majorScale"), - ("mineure naturelle" , "minorScale"), - ("majeure myxolydienne" , "myxolydianScale"), - ("mineure dorienne" , "dorianScale"), - ("phrygienne espagnole" , "spanishPhrygianScale"), - ("lydienne" , "lydianScale"), - ("phrygienne" , "phrygianScale"), - ("J'ai du bon tabac" , "jadbt"), - ("L'eau vive" , "eauvive"), - ("Le penitencier" , "penitencier"), - ("La foule" , "foule"), - ("Petit papa noel" , "papanoel"), - ("La marseillaise" , "marseillaise"), - ("A la claire fontaine" , "clairefontaine"), - ("Au clair de la lune" , "clairdelalune"), - ("Frere jacques" , "frerejacques"), - ("Le petit vin blanc" , "vinblanc"), - ("La vie en rose","vierose"), - ("Les feuilles mortes","feuillesmortes"), - ("Il pleut bergere","bergere"), - ("Le temps des cerises","cerises"), - ("La boheme","boheme"), - ("Chanson Test","test"), - ("Improvisation" , "none"), - ("Do/Do","C/C"), - ("Sol/Do","G/C"), - ("Oui","Yes"), - ("Non","No"), - ("Tres facile","veryEasy"), - ("Facile","easy"), - ("Normal","normal"), - ("Expert","expert")]) - -reversedReadabilityDict = dict(zip(readabilityDict.values(),readabilityDict.keys())) - -rangeDict = {"C/C":False,"G/C":True} - -cascadeDict = {"Yes":True,"No":False} - -modeDict = OrderedDict([("veryEasy",0),("easy",1),("normal",2),("expert",3)]) -print modeDict['veryEasy'] - -scaleDict = OrderedDict ([("majorScale" , [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]), - ("minorScale" , [55, 56, 58, 60, 62, 63, 65, 67, 68, 70, 72]), - ("myxolydianScale" , [55, 57, 58, 60, 62, 64, 65, 67, 69, 70, 72]), - ("dorianScale" , [55, 57, 58, 60, 62, 63, 65, 67, 69, 70, 72]), - ("spanishPhrygianScale" , [55,57,58,60,62,63,66,67,69,70,72]), - ("lydianScale" , [55, 57, 59, 60, 62, 64, 66, 67, 69, 71, 72]), - ("phrygianScale" , [55, 56, 58, 60, 61, 63, 65, 67, 68, 70, 72])]) - -songDict = OrderedDict([("jadbt" , Song(scaleDict["majorScale"],[3, 4, 5, 3, 4, 4, 5, 6, 6, 5, 5, 3, 4, 5, 3, 4, 4, 5, 6, 7, 3,7,7,6,5,4,5,6,7,4,7,7,6,5,4,5,6,7,4],False, - lyrics = ["J'ai","du","bon","ta-","-bac","dans","ma","ta-","-ba-","-tie-","-re","J'ai","du","bon","ta-","-bac","tu","n'en","au-","-ras","pas","j'en","ai","du","fin","et","du","bien","ra-","-pe","mais","ce","n'est","pas","pour","ton","vi-","-lain","nez"], - noteLengths = [1,1,1,1,2,1,1,2,2,2,2,1,1,1,1,2,1,1,2,2,4,2,1,1,2,1,1,2,2,4,2,1,1,2,1,1,2,2,4], - quarterNoteLength = 400)), - ("eauvive" , Song(scaleDict["majorScale"],[5,3,5,3,5,3,4,4,5,6,4,5,3,4,5,3,5,3,5,3,4,4,5,6,4,5,3,4,7,8,7,6,6,4,6,5,3,5,4,3,4,5,6,5,4,3,4,3,2,3], - True, - lyrics = ["Ma","pe-","-tite","est","co-","-mme","l'eau","elle","est","co-","-mme","l'eau","vi-","-ve","e-","-lle","court","comme","un","rui-","-sseau","que","les","en-","-fants","pour-","-sui-","-vent","ve-","-nez","ve-","-nez","mes","a-","-gneaux","mes","a-","-gne-","-lets","ja-","-mais","ja-","-mais","vous","ne","la","ra-","-ttra-","-pe-","-rez"], - noteLengths = [2,1,2,1,2,1,3,1,1,1,2,1,3,3,2,1,2,1,2,1,3,1,1,1,2,1,3,3,3,3,3,3,1,1,1,1,1,1,6,3,3,3,3,1,1,1,1,1,1,6], - quarterNoteLength = 300)), - ("penitencier" , - Song(scaleDict["dorianScale"],[3,3,3,5,7,6,3,3,10,10,10,9,7,6,7,10,10,10,3,5,6,7,6,3,5,3,3,3,3,2,2,3], - True, - alterationIndexes = [-2,-3], - alterations = [1,1], - lyrics = ["Les","por-","-tes","du","pe-","-ni-","-ten-","-cier","bien-","-tot","vont","se","re-","-fer-","-mer","et","c'est","la","que","je","fi-","-ni-","-rai","ma","vie","comme","d'au-","-tres","gars","l'ont","fi-","-nie"], - noteLengths =[1,5,1,5,1,1,6,4,1,5,1,4,1,1,10,1,1,5,1,4,1,1,5,1,5,1,1,1,4,5,1,12], - quarterNoteLength = 250)), - ("papanoel" , Song(scaleDict["myxolydianScale"],[3,6,6,6,7,6,6,7,8,8,8,9,8,7,6,6,6,6,5,4,3,3,3,6,6,6,7,7,6],False, - lyrics = ["pe-","-ti","Pa-","-pa","No-","-el","quand","tu","de-","-scen-","-dras","du","ciel","a-","-vec","tes","jou-","-ets","par","mi-","-lliers","n'ou-","-blie","pas","mes","pe-","-tits","sou-","-liers"], - noteLengths = [1,1,1,1,1,3,0.5,0.5,1,1,1,1,3,1,1.5,0.5,0.5,0.5,0.5,0.5,3,0.5,0.5,1,0.5,0.5,0.5,0.5,3], - quarterNoteLength = 500)), - ("foule" , Song(scaleDict["myxolydianScale"],[7,7,6,5,6,8,7,7,6,8,7,7,6,9,7,7,6,9,7,7,6,8,7,7,6,8,7,6,5,4,4,4,4,4,4,6,6,6,6,8,8,7,6,8,7,7,7,7,7,7,7,7,7,7,7,7,6,9,8,7,8,8,7,8,8,7,8,8,7,8,8,6,8,8,6,8,8,7],False,modulationIndexes = [28],modulationScales = [scaleDict["spanishPhrygianScale"]], - lyrics = ["Em-","-por-","-tes","par","la","fou-","-le","qui","nous","trai-","-ne","nous","en-","-trai-","-ne","e-","-cra-","-ses","l'un","con-","-tre","l'au-","-tre","nous","ne","for-","-mons","qu'un","seul","corps","et","le","flot","sans","e-","-ffort","nous","pousse","en-","-chai-","-nes","l'un","et","l'au-","-tre","et","nous","lai-","-sse","tous","deux","e-","-pa-","-nouis-","en-","-i-","-vres","et","heu-","-reux","ta-","-dam","ta","ta-","-dam","ta","ta-","-dam","ta","ta-","-dam","ta","ta-","-dam","ta","ta-","-dam","ta"], - noteLengths = [1,1.5,.5,.5,.5,1.5,.5,.5,.5,1.5,.5,.5,.5,1.5,.5,.5,.5,1.5,.5,.5,.5,1.5,.5,.5,.5,1.5,.5,.5,.5,3,.5,.5,.5,.5,.5,.5,.5,.5,.5,1,1,.5,.5,1.5,3,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,1,1,1.5,.5,1,1.5,.5,1,1.5,.5,1,1.5,.5,1,1.5,.5,1,1.5,.5,1,3], - quarterNoteLength = 400)), - ("clairefontaine" , Song(scaleDict["majorScale"], - [3,3,5,5,4,5,4,3,3,5,5,4,5,5,5,4,3,5,7,5,7,7,5,3,5,4,3,3,5,5,5,4,5,5,5,5,3,5,4,3], - False, - lyrics = ["A","la","clai-","-re","fon-","-tai-","-ne","m'en","a-","-llant","pro-","-me-","-ner","j'ai","trou-","-ve","l'eau","si","be-","-lle","que","je","m'y","suis","bai-","-gne","il","y-a","long-","-temps","que","je","t'aime","ja-","-mais","je","ne","t'ou-","-blie-","-rai"], - noteLengths = [2,1,1,1,1,1,1,2,1,1,1,1,2,2,1,1,1,1,1,1,2,1,1,1,1,2,2,1,1,1,0.5,0.5,2,2,1,0.5,0.5,1,1,4], - quarterNoteLength = 400)), - ("clairdelalune", Song(scaleDict["lydianScale"], [7,7,7,8,9,8,7,9,8,8,7,7,7,7,8,9,8,7,9,8,8,7,8,8,8,8,5,5,8,7,6,5,4,7,7,7,8,9,8,7,9,8,8,7],False, - lyrics = ["Au","clair","de","la","lu-","-ne","mon","a-","-mi","Pie-","-rrot","pre-","-te","moi","ta","plu-","-me","pour","e-","-crire","un","mot","ma","chan-","-delle","est","mor-","-te","je","n'ai","plus","de","feu","ou-","-vre","moi","ta","po-","-rte","pour","l'a-","-mour","de","Dieu"], - noteLengths = [1,1,1,1,2,2,1,1,1,1,4,1,1,1,1,2,2,1,1,1,1,4,1,1,1,1,2,2,1,1,1,1,4,1,1,1,1,2,2,1,1,1,1,4], - quarterNoteLength = 500)), - ("frerejacques" , - Song(scaleDict["majorScale"], - [3,4,5,3,3,4,5,3,5,6,7,5,6,7,7,8,7,6,5,3,7,8,7,6,5,3,3,0,3,3,0,3], - True, - lyrics = ["Fre-","-re","Ja-","-cques","fre-","-re","-Ja","-cques","dor-","-mez","vous","dor-","-mez","vous","so-","-nnez","les","ma-","-ti-","-nes","so-","-nnez","les","ma-","-ti-","-nes","ding","ding","dong","ding","ding","dong"], - noteLengths = [1,1,1,1,1,1,1,1,1,1,2,1,1,2,1.5,0.5,1,1,2,2,1.5,0.5,1,1,2,2,1,1,2,1,1,2], - quarterNoteLength = 600)), - ("marseillaise" , Song(scaleDict["majorScale"],[0, 0, 0, 3, 3, 4, 4, 7, 5, 3, 3, 5, 3, 1, 6, 4, 2, 3, 3, 4, 5, 5, 5, 6, 5, 5, 4, 4, 5, 6, 6, 6, 7, 6, 5, 7, 7, 7, 5, 3, 7, 5, 3, 0, 0, 0, 2, 4, 6, 4, 2, 4, 3, 2, 1, 3, 3, 3, 2, 3, 4, 4, 5, 5, 5, 5, 6, 7, 4, 5, 4, 3, 3, 3, 5, 4, 3, 3,2,7,7,7,5,3,4,7,7,7,5,3,4,0,3,4,5,6,7,8,4,8,7,5,6,4,3], True, modulationIndexes = [53,54,61,77], modulationScales = [scaleDict["dorianScale"],scaleDict["majorScale"],scaleDict["dorianScale"],scaleDict["majorScale"]], - lyrics = ["A-","-llons","en-","-fants","de","la","pa","tri-","-i-","-e","le","jour","de","gloire","est","a-","-rri-","-ve","con-","-tre","nous","de","la","ty-","-ra-","-nni-","-e","l'e-","-ten-","-dard","san-","-glant","est","le-","-ve","l'e-","-ten-","-dard","san-","-an-","-glant","est","le-","-ve","en-","-ten-","-dez","vous","dans","nos","cam-","-pa-","-gnes","mu-","-gir","ces","fe-","-ro-","-ces","sol-","-dats","qui","vie-","-nnent","ju-","-sque","dans","nos","bras","e-","-gor-","-ger","nos","fils","et","nos","com-","-pa-","-gnes","aux","ar-","-mes","ci-","-toy-","-yen","for-","-mez","vos","ba-","-ta-","-illons","mar-","-chons","mar-","-chons","qu'un","sang","im-","-pur","a-","-breu-","-ve","nos","si-","-illons","pon","pon","pon","pon"], - noteLengths = [1,2,1,3,3,3,3,5,1,2,1,2,1,3,6,2,1,9,2,1,3,3,3,2,1,3,6,2,1,3,3,3,2,1,6,2,1,3,2,1,3,2,1,6,1,2,1,6,3,2,1,3,3,6,3,2,1,3,2,1,6,3,5,1,2,1,2,1,6,2,1,5,1,2,1,2,1,6,5,1,7,1,2,1,8,1,7,1,2,1,8,3,9,3,9,6,3,3,9,3,8,1,2,1,2,1,2,1,8], - quarterNoteLength = 300)), - ("vinblanc" , - Song(scaleDict["phrygianScale"],[5, 5, 5, 3, 5, 6, 5, 5, 5, 3, 7, 6, 6, 6, 6, 4, 8, 7, 7, 7, 8, 9, 7, 5, 5, 5, 5, 3, 5, 6, 8, 9, 10, 9, 8, 10, 9, 8, 6, 6, 8, 7, 6, 8, 6, 5, 3, 5, 6, 3, 5, 6, 3, 5, 6, 3, 5, 6, 3, 5, 7, 6, 5, 7, 6, 5, 8], - False, - lyrics = ["Ah","le","pe-","-tit","vin","blanc","qu'on","boit","sous","les","to-","-nelles","quand","les","fi-","-lles","sont","belles","du","co-","-te","de","No-","-geant","et","puis","de","temps","en","temps","un","air","de","vie-","-lle","ro-","-man-","-ce","sem-","-ble","do-","-nner","la","ca-","-den-","-ce","pour","fau-","-ter","pour","fau-","-ter","dans","les","bois","dans","les","pres","du","co-","-te","du","co-","-te","de","No-","-geant"], - noteLengths = [1,1,1,2,1,6,1,1,1,2,1,6,1,1,1,2,1,6,1,1,1,2,1,6,1,1,1,2,1,6,1,1,1,1,1,1,3,3,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,6], - quarterNoteLength = 300)), - ("none" , None)]) - -instrumentImagePathList = ["piano", "guitare", "accordeon", "violon", "flute", "tuba", "orgue", "violoncelle", "celesta"] -octaves = [0, -1, 0, 1, 1, -2, 0, -1, 0] - -defaultInstrumentChannel = 16 -defaultInstrumentNote = 60 -defaultCCHexCode = 0xB0+defaultInstrumentChannel - 1 -defaultNoteOnHexCode = 0x90+defaultInstrumentChannel - 1 - -songScaleFactor = 0.99 - -fileName = "../../../saves/22-01-2009-coll1-v65-" - -def noteNumberToName(noteNumber): - names = ["Do","Do#","R\xe9","Mib","Mi","Fa","Fa#","Sol","Sol#","La","Sib","Si"] - return(names[noteNumber%12]) - -if __name__ == "__main__": - key = "papanoel" - if songDict[key] != None : - songDict[key].save("../songs/smwis/"+str(key)+".smwi") diff --git a/src/instruments/Instrument.py b/src/instruments/Instrument.py deleted file mode 100755 index fb54d3a..0000000 --- a/src/instruments/Instrument.py +++ /dev/null @@ -1,46 +0,0 @@ -''' -Created on 15 juil. 2009 - -@author: Samuel Benveniste -''' - -class Instrument: - ''' - Object representing an instrument. - - notes: - The MIDI numbers of the notes played by this instrument (usually a scale) - channel: - The channel corresponding to the instrument in the synthesizer - image: - The image for the instrument - ''' - - def __init__(self, notes, channel, image, octave = 0): - ''' - Constructor - - notes: - The MIDI numbers of the notes played by this instrument (usually a scale) - channel: - The channel corresponding to the instrument in the synthesizer - image: - The image for the instrument - ''' - - self.notes = [loop+12*octave for loop in notes] - self.octave = octave - self.channel = channel - self.image = image - - def getNote(self,noteNumber): - if noteNumber == None : - return(None) - else : - return(self.notes[noteNumber]) - - def getNoteByNoteNumber(self,baseMidiNoteNumber): - if baseMidiNoteNumber == None: - return(None) - else : - return(baseMidiNoteNumber+self.octave*12) \ No newline at end of file diff --git a/src/instruments/__init__.py b/src/instruments/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/instruments/instrumentImages/accordeon.jpg b/src/instruments/instrumentImages/accordeon.jpg deleted file mode 100755 index 015b1e0..0000000 Binary files a/src/instruments/instrumentImages/accordeon.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/accordeonOld.jpg b/src/instruments/instrumentImages/accordeonOld.jpg deleted file mode 100755 index 68ee03b..0000000 Binary files a/src/instruments/instrumentImages/accordeonOld.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/celesta.jpg b/src/instruments/instrumentImages/celesta.jpg deleted file mode 100755 index 2cb012b..0000000 Binary files a/src/instruments/instrumentImages/celesta.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/celestaOld.jpg b/src/instruments/instrumentImages/celestaOld.jpg deleted file mode 100755 index fdec154..0000000 Binary files a/src/instruments/instrumentImages/celestaOld.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/flute.jpg b/src/instruments/instrumentImages/flute.jpg deleted file mode 100755 index 5dbab3d..0000000 Binary files a/src/instruments/instrumentImages/flute.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/guitare.jpg b/src/instruments/instrumentImages/guitare.jpg deleted file mode 100755 index 33dcd50..0000000 Binary files a/src/instruments/instrumentImages/guitare.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/orgue.jpg b/src/instruments/instrumentImages/orgue.jpg deleted file mode 100755 index ea4e1b5..0000000 Binary files a/src/instruments/instrumentImages/orgue.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/piano.jpg b/src/instruments/instrumentImages/piano.jpg deleted file mode 100755 index ef109bc..0000000 Binary files a/src/instruments/instrumentImages/piano.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/tuba.jpg b/src/instruments/instrumentImages/tuba.jpg deleted file mode 100755 index 453d3bd..0000000 Binary files a/src/instruments/instrumentImages/tuba.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/violon.jpg b/src/instruments/instrumentImages/violon.jpg deleted file mode 100755 index 454e4f3..0000000 Binary files a/src/instruments/instrumentImages/violon.jpg and /dev/null differ diff --git a/src/instruments/instrumentImages/violoncelle.jpg b/src/instruments/instrumentImages/violoncelle.jpg deleted file mode 100755 index 9bcc42c..0000000 Binary files a/src/instruments/instrumentImages/violoncelle.jpg and /dev/null differ diff --git a/src/launcher/__init__.py b/src/launcher/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/logging.disabled/EventLog.py b/src/logging.disabled/EventLog.py deleted file mode 100755 index 55d778a..0000000 --- a/src/logging.disabled/EventLog.py +++ /dev/null @@ -1,69 +0,0 @@ -''' -Created on 21 aout 2009 - -@author: Samuel Benveniste -''' -import time - -class EventLog: - ''' - classdocs - ''' - - def __init__(self,eventGroups = [], times = []): - ''' - Constructor - ''' - self.eventGroups = eventGroups - self.times = times - self.rate = 1 - self.yielder = self.eventGroupYielder() - self.yieldPointer = 0 - - self._timeCounter = 0 - - def __getstate__(self): - d = [] - d.append(self.eventGroups) - d.append(self.times) - return d - - def __setstate__(self,d): - self.eventGroups = d[0] - self.times = d[1] - self.yielder = self.eventGroupYielder() - - self._timeCounter = 0 - - def appendEventGroup(self, eventGroup): - t = time.clock()*1000 - self.times.append(t) - self.eventGroups.append(eventGroup) - - def update(self,timePassed): - self._timeCounter += timePassed - - def setReplayRate(self,rate): - self.rate = rate - self.yielder = self.eventGroupYielder() - - def getPickledEvents(self): - return(self.yielder.next()) - - def getCurrentTime(self): - return(self.times[self.yieldPointer]) - - def eventGroupYielder(self): - ''' - Will return the next event to post if enough time has passed and [] otherwise - ''' - i = 0 - while i in range(len(self.eventGroups)): - print "rate is " + str(self.rate) - if self._timeCounter*self.rate>self.times[i]: - print str(self._timeCounter*self.rate)+" > "+ str(self.times[i]) - self.yieldPointer = i - yield self.eventGroups[i] - i += 1 - else: - yield [] diff --git a/src/logging.disabled/FamiliarizerLog.py b/src/logging.disabled/FamiliarizerLog.py deleted file mode 100644 index e84d1c2..0000000 --- a/src/logging.disabled/FamiliarizerLog.py +++ /dev/null @@ -1,100 +0,0 @@ -''' -Created on 28 aout 2009 - -@author: Samuel Benveniste -''' - -import os -import sys -import subprocess -import re - -import pygame -import pygame.midi -import pickle - -from gui.constants import * - -from gui.PlayingScreen import PlayingScreen -from gui.InstrumentChoice import InstrumentChoice -from instruments.Instrument import Instrument -from cursor.WarpingCursor import * -from controllers.Wiimote import Wiimote -from songs.Song import Song -from gui.StaticFamiliarizer import StaticFamiliarizer -from gui.SongFamiliarizer import SongFamiliarizer -from gui.SongPlayingScreen import SongPlayingScreen -from gui.DummyInstrumentChoice import DummyInstrumentChoice - -class FamiliarizerLog(): - ''' - classdocs - ''' - - def __init__(self,eventLog,level,activeWiimotes): - ''' - Constructor - ''' - self.eventLog = eventLog - self.level = level - self.activeWiimotes = activeWiimotes - self.scale = scaleDict["majorScale"] - -if __name__ == '__main__': - - f = file('../../../saves/19-01-2009-testcoll1-v65-1.fmwi', 'r') - unpickler = pickle.Unpickler(f) - log = unpickler.load() - f.close() - - pygame.init() - modeResolution = (1024,768) - window = pygame.display.set_mode(modeResolution,pygame.FULLSCREEN) - pygame.midi.init() - instruments = [Instrument(log.scale, i + 1, "".join(["../instruments/instrumentImages/", instrumentImagePathList[i], ".jpg"]), octaves[i]) for i in range(9)] - - joys = [[id,pygame.joystick.Joystick(id).get_name()] for id in range(pygame.joystick.get_count())] - for joy in joys: - if joy[1] in joyNames: - pygame.joystick.Joystick(joy[0]).init() - - ports = [pygame.midi.get_device_info(id)[1] for id in range(pygame.midi.get_count())] - portOffset = ports.index(portNames[0]) - print(portOffset) - - screen = pygame.display.get_surface() - clock = pygame.time.Clock() - cursorImages=[['../cursor/cursorImages/black/10.png'],['../cursor/cursorImages/red/10.png'],['../cursor/cursorImages/blue/10.png'],['../cursor/cursorImages/green/10.png']] - durations = [75 for i in range(len(cursorImages))] - - extsc = True - casc = False - easyMode = True - - song = Song(scaleDict["majorScale"],[3,9,6,4,1,8,5,7,2,10],True) - - wiimoteCount = 4 - - cursors = [WarpingCursor(None, cursorImages[i], durations, (300 * i, 300 * i),'../cursor/cursorImages/black/flash.png') for i in range(wiimoteCount)] - wiimotes = [Wiimote(i, i + portOffset, None, instruments[0], cursors[i]) for i in range(wiimoteCount)] - dummyInstrumentChoice = DummyInstrumentChoice(wiimotes, window, screen, clock, joys, portOffset, log.activeWiimotes) - if log.level < 2 : - familiarize = StaticFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes,level = log.level,eventLog = log.eventLog,replay = True) - elif log.level == 2 : - familiarize = SongFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,song,log.activeWiimotes,casc,extsc,easyMode,eventLog = log.eventLog,replay = True) - else : - familiarize = SongPlayingScreen(dummyInstrumentChoice,songDict["clairdelalune"],easyMode = True,eventLog = log.eventLog,replay = True) - - while familiarize.nextLevel != None : - if familiarize.nextLevel < 2 : - familiarize = StaticFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes,level = familiarize.nextLevel,eventLog = familiarize.eventLog,replay = True) - elif familiarize.nextLevel == 2 : - familiarize = SongFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,song,log.activeWiimotes,casc,extsc,easyMode,eventLog = familiarize.eventLog,replay = True) - else : - familiarize = SongPlayingScreen(dummyInstrumentChoice,songDict["clairdelalune"],easyMode = True,eventLog = familiarize.eventLog,replay = True) - - for wiimote in wiimotes: - del wiimote.port - - pygame.midi.quit() - pygame.quit() \ No newline at end of file diff --git a/src/logging.disabled/Log.py b/src/logging.disabled/Log.py deleted file mode 100755 index a658e8a..0000000 --- a/src/logging.disabled/Log.py +++ /dev/null @@ -1,135 +0,0 @@ -''' -Created on 28 aout 2009 - -@author: Samuel Benveniste -''' - -import os -import sys -import subprocess -import re - -import pygame -import pygame.midi -import pickle - -from gui.constants import * - -from gui.PlayingScreen import PlayingScreen -from gui.SongPlayingScreen import SongPlayingScreen -from gui.InstrumentChoice import InstrumentChoice -from instruments.Instrument import Instrument -from cursor.WarpingCursor import * -from controllers.Wiimote import Wiimote -from songs.Song import Song - - -class Log: - ''' - classdocs - ''' - - - def __init__(self,eventLog,scale,extendedScale,cascade,song,mode,activeWiimotes,easyMode = True): - ''' - Constructor - ''' - self.eventLog = eventLog - self.scale = scale - self.extendedScale = extendedScale - self.cascade = cascade - self.song = song - self.activeWiimotes = activeWiimotes - self.mode = mode - -if __name__ == '__main__': - - f = file('../../saves/4-12-2009-B1-v50-1.mwi', 'r') - unpickler = pickle.Unpickler(f) - log = unpickler.load() - f.close() - - pygame.init() - pygame.midi.init() - instruments = [Instrument(scaleDict["majorScale"], i + 1, "".join(["../instruments/instrumentImages/", instrumentImagePathList[i], ".jpg"]), octaves[i]) for i in range(9)] - - joys = [[id,pygame.joystick.Joystick(id).get_name()] for id in range(pygame.joystick.get_count())] - for joy in joys: - if joy[1] in joyNames: - pygame.joystick.Joystick(joy[0]).init() - - ports = [pygame.midi.get_device_info(id)[1] for id in range(pygame.midi.get_count())] - portOffset = ports.index(portNames[0]) - print(portOffset) - - modeResolution = (1024,768) - window = pygame.display.set_mode(modeResolution,pygame.FULLSCREEN) - screen = pygame.display.get_surface() - clock = pygame.time.Clock() - cursorImages=[['../cursor/cursorImages/black/10.png'],['../cursor/cursorImages/red/10.png'],['../cursor/cursorImages/blue/10.png'],['../cursor/cursorImages/green/10.png']] - durations = [75 for i in range(len(cursorImages[0]))] - - wiimoteCount = 4 - cursors = [WarpingCursor(None, cursorImages[i], durations, (300 * i, 300 * i),flashImage = '../cursor/cursorImages/black/flash.png' ) for i in range(wiimoteCount)] - wiimotes = [Wiimote(i, i + portOffset, None, None, cursors[i]) for i in range(wiimoteCount)] - - if log.song != None : - - if log.mode == 0 : - log.extendedScale = log.song.requiresExtendedScale - log.cascade = True - log.easyMode = True - elif log.mode == 1 : - log.extendedScale = log.song.requiresExtendedScale - log.cascade = True - log.easyMode = True - elif log.mode == 2: - log.extendedScale = log.song.requiresExtendedScale - log.cascade = False - log.easyMode = True - elif log.mode == 3: - log.extendedScale = True - log.cascade = False - log.easyMode = False - - choice = InstrumentChoice(instruments, wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes, eventLog = log.eventLog,scaleFactor = songScaleFactor,replay = True) - play = SongPlayingScreen(choice, log.song,log.cascade, log.extendedScale,log.easyMode) - - else: - - if log.mode == 0 : - log.extendedScale = False - log.cascade = False - elif log.mode == 1 : - log.extendedScale = True - log.cascade = False - elif log.mode == 2: - log.extendedScale = False - log.cascade = True - elif log.mode == 3: - log.extendedScale = True - log.cascade = True - - choice = InstrumentChoice(instruments, wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes,eventLog = log.eventLog,replay = True) - play = PlayingScreen(choice, None,log.cascade, log.extendedScale) - - while play.backToInstrumentChoice == True : - - for wiimote in wiimotes: - del wiimote.port - - wiimotes = [Wiimote(i, i + portOffset, None, None, cursors[i]) for i in range(wiimoteCount)] - previousEventLog = play.eventLog - - if log.song != None : - choice = InstrumentChoice(instruments, wiimotes,window, screen, clock, joys, portOffset, log.activeWiimotes,eventLog = previousEventLog, replay = True, scaleFactor = songScaleFactor) - play = SongPlayingScreen(choice, log.song, False, log.extendedScale,log.easyMode) - else: - choice = InstrumentChoice(instruments, wiimotes, log.window, screen, clock, joys, portOffset,log.activeWiimotes, eventLog = previousEventLog, replay = True) - play = PlayingScreen(choice, None, log.cascade, log.extendedScale) - - for wiimote in wiimotes: - del wiimote.port - - pygame.midi.quit() - pygame.quit() \ No newline at end of file diff --git a/src/logging.disabled/LogPGUAnalyzer.py b/src/logging.disabled/LogPGUAnalyzer.py deleted file mode 100644 index a3551fd..0000000 --- a/src/logging.disabled/LogPGUAnalyzer.py +++ /dev/null @@ -1,42 +0,0 @@ -''' -Created on 25 janv. 2010 - -@author: Samuel Benveniste -''' - -from LogPGUPlayer import LogPGUPlayer - -class LogPGUAnalyzer(LogPGUPlayer): - ''' - classdocs - ''' - - - def __init__(self): - ''' - Constructor - ''' - - self.firstStepDurations = [] - self.firstStepClicks = [] - self.firstStepClicksIn = [] - - self.secondStepDurations = [] - self.secondStepClicks = [] - self.secondStepClicksIn = [] - - self.thirdStepDurations = [] - self.thirdStepClicks = [] - self.thirdStepClicksIn = [] - - self.songDurations = [] - self.songClicks = [] - self.songClicksIn = [] - self.songClicksPerMinute = [] - self.songClicksInPerMinute = [] - self.songTotalDurations = [] - - self.meanTimeBetweenNotes = [] - - LogPGUPlayer.__init__(self,20) - \ No newline at end of file diff --git a/src/logging.disabled/LogPGUPlayer.py b/src/logging.disabled/LogPGUPlayer.py deleted file mode 100644 index cf1a670..0000000 --- a/src/logging.disabled/LogPGUPlayer.py +++ /dev/null @@ -1,237 +0,0 @@ -''' -Created on 25 janv. 2010 - -@author: Samuel Benveniste -''' - -import pygame -import pickle - -from pgu import gui as pguGui - -from gui import constants - -from instruments.Instrument import Instrument -from songs.Song import Song -from cursor.WarpingCursor import * -from gui.StaticFamiliarizer import StaticFamiliarizer -from gui.SongFamiliarizer import SongFamiliarizer -from gui.SongPlayingScreen import SongPlayingScreen -from gui.DummyInstrumentChoice import DummyInstrumentChoice -from controllers.Wiimote import Wiimote - -class LogPGUPlayer(pguGui.Desktop): - ''' - classdocs - ''' - - - def __init__(self,rate): - ''' - Constructor - ''' - self.firstStepDurations = [] - self.firstStepClicks = [] - self.firstStepClicksIn = [] - - self.secondStepDurations = [] - self.secondStepClicks = [] - self.secondStepClicksIn = [] - - self.thirdStepDurations = [] - self.thirdStepClicks = [] - self.thirdStepClicksIn = [] - - self.songDurations = [] - self.songClicks = [] - self.songClicksIn = [] - self.songClicksPerMinute = [] - self.songClicksInPerMinute = [] - self.songTotalDurations = [] - - self.meanTimeBetweenNotes = [] - - pguGui.Desktop.__init__(self) - - self.replayRate = rate - #pguGui.theme.load('../data/themes/default') - - self.connect(pguGui.QUIT,self.quit,None) - - main = pguGui.Container(width=500, height=400) #, background=(220, 220, 220) ) - - - main.add(pguGui.Label("File Dialog Example", cls="h1"), 20, 20) - - - td_style = {'padding_right': 10} - t = pguGui.Table() - t.tr() - t.td( pguGui.Label('File Name:') , style=td_style ) - self.input_file = pguGui.Input() - t.td( self.input_file, style=td_style ) - self.browseButton = pguGui.Button("Browse...") - t.td( self.browseButton, style=td_style ) - self.browseButton.connect(pguGui.CLICK, self.open_file_browser, None) - - self.goButton = pguGui.Button("Go") - - self.goButton.connect(pguGui.CLICK, self.goButtonClicked,None) - - self.quitButton = pguGui.Button("Fin") - self.quitButton.connect(pguGui.CLICK,self.quit,None) - - t.td( self.browseButton, style=td_style ) - t.td( self.goButton, style=td_style ) - t.td( self.quitButton, style=td_style ) - - main.add(t, 20, 100) - - self.run(main) - #import profile - #profile.run('app.run(main)') - - def open_file_browser(self,data=None): - d = pguGui.FileDialog(path = "../../../saves") - d.connect(pguGui.CHANGE, self.handle_file_browser_closed, d) - d.open() - - - def handle_file_browser_closed(self,dlg): - if dlg.value: self.input_file.value = dlg.value - - def goButtonClicked(self,data=None): - if self.input_file.value.endswith(".fmwi"): - f = file(self.input_file.value, 'r') - unpickler = pickle.Unpickler(f) - log = unpickler.load() - f.close() - - log.eventLog.setReplayRate(self.replayRate) - - pygame.midi.init() - instruments = [Instrument(log.scale, i + 1, "".join(["../instruments/instrumentImages/", constants.instrumentImagePathList[i], ".jpg"]), constants.octaves[i]) for i in range(9)] - - joys = [[id,pygame.joystick.Joystick(id).get_name()] for id in range(pygame.joystick.get_count())] - for joy in joys: - if joy[1] in constants.joyNames: - pygame.joystick.Joystick(joy[0]).init() - - ports = [pygame.midi.get_device_info(id)[1] for id in range(pygame.midi.get_count())] - portOffset = ports.index(constants.portNames[0]) - print(portOffset) - - screen = pygame.display.get_surface() - clock = pygame.time.Clock() - cursorImages=[['../cursor/cursorImages/black/10.png'],['../cursor/cursorImages/red/10.png'],['../cursor/cursorImages/blue/10.png'],['../cursor/cursorImages/green/10.png']] - durations = [75 for i in range(len(cursorImages))] - - extsc = True - casc = False - easyMode = True - - song = Song(constants.scaleDict["majorScale"],[3,9,6,4,1,8,5,7,2,10],True) - - wiimoteCount = 4 - - cursors = [WarpingCursor(None, cursorImages[i], durations, (300 * i, 300 * i),'../cursor/cursorImages/black/flash.png') for i in range(wiimoteCount)] - wiimotes = [Wiimote(i, i + portOffset, None, instruments[0], cursors[i]) for i in range(wiimoteCount)] - dummyInstrumentChoice = DummyInstrumentChoice(wiimotes, window, screen, clock, joys, portOffset, log.activeWiimotes) - if log.level < 2 : - familiarize = StaticFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes,level = log.level,eventLog = log.eventLog,replay = True) - self.fillStaticFamiliarizerStats(familiarize) - elif log.level == 2 : - familiarize = SongFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,song,log.activeWiimotes,casc,extsc,easyMode,eventLog = log.eventLog,replay = True) - self.fillSongFamiliarizerStats(familiarize) - else : - familiarize = SongPlayingScreen(dummyInstrumentChoice,constants.songDict["clairdelalune"],easyMode = True,eventLog = log.eventLog,replay = True) - self.fillSongStats(familiarize) - - while familiarize.nextLevel != None : - if familiarize.nextLevel < 2 : - familiarize = StaticFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,log.activeWiimotes,level = familiarize.nextLevel,eventLog = familiarize.eventLog,replay = True) - self.fillStaticFamiliarizerStats(familiarize) - elif familiarize.nextLevel == 2 : - familiarize = SongFamiliarizer(wiimotes, window, screen, clock, joys, portOffset,song,log.activeWiimotes,casc,extsc,easyMode,eventLog = familiarize.eventLog,replay = True) - self.fillSongFamiliarizerStats(familiarize) - else : - familiarize = SongPlayingScreen(dummyInstrumentChoice,constants.songDict["clairdelalune"],easyMode = True,eventLog = familiarize.eventLog,replay = True) - self.fillSongStats(familiarize) - - for wiimote in wiimotes: - del wiimote.port - - pygame.midi.quit() - self.printStatsToFile() - - def fillStaticFamiliarizerStats(self,familiarizer): - if familiarizer.level == 0 : - self.firstStepClicks.append(familiarizer.clicks) - self.firstStepClicksIn.append(familiarizer.clicksIn) - self.firstStepDurations.append(familiarizer.duration) - - if familiarizer.level == 1 : - self.secondStepClicks.append(familiarizer.clicks) - self.secondStepClicksIn.append(familiarizer.clicksIn) - self.secondStepDurations.append(familiarizer.duration) - - def fillSongFamiliarizerStats(self,familiarizer): - self.thirdStepClicks.append(familiarizer.clicks) - self.thirdStepClicksIn.append(familiarizer.clicksIn) - self.thirdStepDurations.append(familiarizer.duration) - - def fillSongStats(self,familiarizer): - self.songClicks.append(familiarizer.clicks) - self.songClicksIn.append(familiarizer.clicksIn) - self.songClicksPerMinute.append(familiarizer.clicksPerMinute) - self.songClicksInPerMinute.append(familiarizer.clicksInPerMinute) - self.songDurations.append(familiarizer.songDurations) - self.songTotalDurations.append(familiarizer.totalDuration) - - def statsToFormattedString(self): - return("First step durations :\n"+"\n"+ - str(self.firstStepDurations)+"\n"+"\n"+ - "First step clicks :\n"+"\n"+ - str(self.firstStepClicks)+"\n"+"\n"+ - "First step clicksIn :\n"+"\n"+ - str(self.firstStepClicksIn)+"\n"+"\n"+ - "Second step durations :\n"+"\n"+ - str(self.secondStepDurations)+"\n"+"\n"+ - "Second step clicks :\n"+"\n"+ - str(self.secondStepClicks)+"\n"+"\n"+ - "Second step clicksIn :\n"+"\n"+ - str(self.secondStepClicksIn)+"\n"+"\n"+ - "Third step durations :\n"+"\n"+ - str(self.thirdStepDurations)+"\n"+"\n"+ - "Third step clicks :\n"+"\n"+ - str(self.thirdStepClicks)+"\n"+"\n"+ - "Third step clicksIn :\n"+"\n"+ - str(self.thirdStepClicksIn)+"\n"+"\n"+ - "song durations :\n"+"\n"+ - str(self.songDurations)+"\n"+"\n"+ - "song clicks :\n"+"\n"+ - str(self.songClicks)+"\n"+"\n"+ - "song clicksIn :\n"+"\n"+ - str(self.songClicksIn)+"\n"+"\n"+ - "song clicks per minute:\n"+"\n"+ - str(self.songClicksPerMinute)+"\n"+"\n"+ - "song clicksIn per minute :\n"+"\n"+ - str(self.songClicksInPerMinute)+"\n"+"\n"+ - "song total durations :\n"+"\n"+ - str(self.songTotalDurations)+"\n"+"\n") - - def printStatsToFile(self,path=None): - if path == None : - path = self.input_file.value.replace(".fmwi",".txt") - file = open(path,"w") - file.write("Log ID : "+self.input_file.value+"\n"+"\n") - file.write(self.statsToFormattedString()) - file.close() - -if __name__ == "__main__": - pygame.init() - modeResolution = (1024,768) - window = pygame.display.set_mode(modeResolution,pygame.FULLSCREEN) - logConfig = LogPGUPlayer(10000) - pygame.quit() - \ No newline at end of file diff --git a/src/logging.disabled/PickleableEvent.py b/src/logging.disabled/PickleableEvent.py deleted file mode 100755 index ab218f8..0000000 --- a/src/logging.disabled/PickleableEvent.py +++ /dev/null @@ -1,24 +0,0 @@ -import pygame -import copy -import pickle - -from pygame.event import Event - -class PickleableEvent(object): - "A pygame.Event that can be serialized." - - def __init__(self,type,dict): - self.__dict__ = copy.copy(dict) - self.type = type - self.event = Event(self.type,dict) - - def __getstate__(self): - d = [] - d.append(self.type) - d.append(copy.copy(self.event.dict)) - return d - - def __setstate__(self, d): - self.__dict__ = copy.copy(d[1]) - self.type = d[0] - self.event = Event(d[0],d[1]) \ No newline at end of file diff --git a/src/logging.disabled/__init__.py b/src/logging.disabled/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/mxmMidi/DataTypeConverters.py b/src/mxmMidi/DataTypeConverters.py deleted file mode 100644 index 25115de..0000000 --- a/src/mxmMidi/DataTypeConverters.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -from struct import pack, unpack - -""" -This module contains functions for reading and writing the special data types -that a midi file contains. -""" - -""" -nibbles are four bits. A byte consists of two nibles. -hiBits==0xF0, loBits==0x0F Especially used for setting -channel and event in 1. byte of musical midi events -""" - - - -def getNibbles(byte): - """ - Returns hi and lo bits in a byte as a tuple - >>> getNibbles(142) - (8, 14) - - Asserts byte value in byte range - >>> getNibbles(256) - Traceback (most recent call last): - ... - ValueError: Byte value out of range 0-255: 256 - """ - if not 0 <= byte <= 255: - raise ValueError('Byte value out of range 0-255: %s' % byte) - return (byte >> 4 & 0xF, byte & 0xF) - - -def setNibbles(hiNibble, loNibble): - """ - Returns byte with value set according to hi and lo bits - Asserts hiNibble and loNibble in range(16) - >>> setNibbles(8, 14) - 142 - - >>> setNibbles(8, 16) - Traceback (most recent call last): - ... - ValueError: Nible value out of range 0-15: (8, 16) - """ - if not (0 <= hiNibble <= 15) or not (0 <= loNibble <= 15): - raise ValueError('Nible value out of range 0-15: (%s, %s)' % (hiNibble, loNibble)) - return (hiNibble << 4) + loNibble - - - -def readBew(value): - """ - Reads string as big endian word, (asserts len(value) in [1,2,4]) - >>> readBew('aáâã') - 1642193635L - >>> readBew('aá') - 25057 - """ - return unpack('>%s' % {1:'B', 2:'H', 4:'L'}[len(value)], value)[0] - - -def writeBew(value, length): - """ - Write int as big endian formatted string, (asserts length in [1,2,4]) - Difficult to print the result in doctest, so I do a simple roundabout test. - >>> readBew(writeBew(25057, 2)) - 25057 - >>> readBew(writeBew(1642193635L, 4)) - 1642193635L - """ - return pack('>%s' % {1:'B', 2:'H', 4:'L'}[length], value) - - - -""" -Variable Length Data (varlen) is a data format sprayed liberally throughout -a midi file. It can be anywhere from 1 to 4 bytes long. -If the 8'th bit is set in a byte another byte follows. The value is stored -in the lowest 7 bits of each byte. So max value is 4x7 bits = 28 bits. -""" - - -def readVar(value): - """ - Converts varlength format to integer. Just pass it 0 or more chars that - might be a varlen and it will only use the relevant chars. - use varLen(readVar(value)) to see how many bytes the integer value takes. - asserts len(value) >= 0 - >>> readVar('€@') - 64 - >>> readVar('áâãa') - 205042145 - """ - sum = 0 - for byte in unpack('%sB' % len(value), value): - sum = (sum << 7) + (byte & 0x7F) - if not 0x80 & byte: break # stop after last byte - return sum - - - -def varLen(value): - """ - Returns the the number of bytes an integer will be when - converted to varlength - """ - if value <= 127: - return 1 - elif value <= 16383: - return 2 - elif value <= 2097151: - return 3 - else: - return 4 - - -def writeVar(value): - "Converts an integer to varlength format" - sevens = to_n_bits(value, varLen(value)) - for i in range(len(sevens)-1): - sevens[i] = sevens[i] | 0x80 - return fromBytes(sevens) - - -def to_n_bits(value, length=1, nbits=7): - "returns the integer value as a sequence of nbits bytes" - bytes = [(value >> (i*nbits)) & 0x7F for i in range(length)] - bytes.reverse() - return bytes - - -def toBytes(value): - "Turns a string into a list of byte values" - return unpack('%sB' % len(value), value) - - -def fromBytes(value): - "Turns a list of bytes into a string" - if not value: - return '' - return pack('%sB' % len(value), *value) - - - -if __name__ == '__main__': - -# print to7bits(0, 3) -# print to7bits(127, 3) -# print to7bits(255, 3) -# print to7bits(65536, 3) - - # simple test cases - -# print 'getHiLoHex', getNibbles(16) -# print 'setHiLoHex', setNibbles(1,0) -# -# print 'readBew', readBew('aáâã') -# print 'writeBew', writeBew(1642193635, 4) -# -# print 'varLen', varLen(1) -# - print 'readVar', readVar('€@') - print 'writeVar', writeVar(8192) - - print 'readVar', readVar('áâãa') - print 'writeVar', writeVar(205058401) -# -# vartest = '\x82\xF7\x80\x00' -# print 'toBytes', toBytes(vartest) -# print 'fromBytes', fromBytes([48, 49, 50,]) - - -# instr = '\xFF\xFF\xFF\x00' -# print 'readVar', readVar(instr) -# inst2 = 268435455 -# print inst2 -# print writeVar(inst2) -# print writeVar(readVar(instr)) - - s1 = 0x00000000 - print '%08X -' % s1, '00', writeVar(s1) - s2 = 0x00000040 - print '%08X -' % s2, '40', writeVar(s2) - s3 = 0x0000007F - print '%08X -' % s3, '7F', writeVar(s3) - s4 = 0x00000080 - print '%08X -' % s4, '81 00', writeVar(s4) - s5 = 0x00002000 - print '%08X -' % s5, 'C0 00', writeVar(s5) - s6 = 0x00003FFF - print '%08X -' % s6, 'FF 7F', writeVar(s6) - s7 = 0x00004000 - print '%08X -' % s7, '81 80 00', writeVar(s7) - s8 = 0x00100000 - print '%08X -' % s8, 'C0 80 00', writeVar(s8) - s9 = 0x001FFFFF - print '%08X -' % s9, 'FF FF 7F', writeVar(s9) - s10 = 0x00200000 - print '%08X -' % s10, '81 80 80 00', writeVar(s10) - s11 = 0x08000000 - print '%08X -' % s11, 'C0 80 80 00', writeVar(s11) - s12 = 0x0FFFFFFF - print '%08X -' % s12, 'FF FF FF 7F', writeVar(s12) - - - - - - - - - - - - \ No newline at end of file diff --git a/src/mxmMidi/EventDispatcher.py b/src/mxmMidi/EventDispatcher.py deleted file mode 100644 index 3c07a33..0000000 --- a/src/mxmMidi/EventDispatcher.py +++ /dev/null @@ -1,287 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -# std library -from struct import unpack - -# custom -from DataTypeConverters import readBew, readVar, varLen, toBytes - -# uhh I don't really like this, but there are so many constants to -# import otherwise -from constants import * - - -class EventDispatcher: - - - def __init__(self, outstream): - - """ - - The event dispatcher generates events on the outstream. - - """ - - # internal values, don't mess with 'em directly - self.outstream = outstream - - # public flags - - # A note_on with a velocity of 0x00 is actually the same as a - # note_off with a velocity of 0x40. When - # "convert_zero_velocity" is set, the zero velocity note_on's - # automatically gets converted into note_off's. This is a less - # suprising behaviour for those that are not into the intimate - # details of the midi spec. - self.convert_zero_velocity = 1 - - # If dispatch_continuos_controllers is true, continuos - # controllers gets dispatched to their defined handlers. Else - # they just trigger the "continuous_controller" event handler. - self.dispatch_continuos_controllers = 1 # NOT IMPLEMENTED YET - - # If dispatch_meta_events is true, meta events get's dispatched - # to their defined events. Else they all they trigger the - # "meta_event" handler. - self.dispatch_meta_events = 1 - - - - def header(self, format, nTracks, division): - "Triggers the header event" - self.outstream.header(format, nTracks, division) - - - def start_of_track(self, current_track): - "Triggers the start of track event" - - # I do this twice so that users can overwrite the - # start_of_track event handler without worrying whether the - # track number is updated correctly. - self.outstream.set_current_track(current_track) - self.outstream.start_of_track(current_track) - - - def sysex_event(self, data): - "Dispatcher for sysex events" - self.outstream.sysex_event(data) - - - def eof(self): - "End of file!" - self.outstream.eof() - - - def update_time(self, new_time=0, relative=1): - "Updates relative/absolute time." - self.outstream.update_time(new_time, relative) - - - def reset_time(self): - "Updates relative/absolute time." - self.outstream.reset_time() - - - # Event dispatchers for similar types of events - - - def channel_messages(self, hi_nible, channel, data): - - "Dispatches channel messages" - - stream = self.outstream - data = toBytes(data) - - if (NOTE_ON & 0xF0) == hi_nible: - note, velocity = data - # note_on with velocity 0x00 are same as note - # off with velocity 0x40 according to spec! - if velocity==0 and self.convert_zero_velocity: - stream.note_off(channel, note, 0x40) - else: - stream.note_on(channel, note, velocity) - - elif (NOTE_OFF & 0xF0) == hi_nible: - note, velocity = data - stream.note_off(channel, note, velocity) - - elif (AFTERTOUCH & 0xF0) == hi_nible: - note, velocity = data - stream.aftertouch(channel, note, velocity) - - elif (CONTINUOUS_CONTROLLER & 0xF0) == hi_nible: - controller, value = data - # A lot of the cc's are defined, so we trigger those directly - if self.dispatch_continuos_controllers: - self.continuous_controllers(channel, controller, value) - else: - stream.continuous_controller(channel, controller, value) - - elif (PATCH_CHANGE & 0xF0) == hi_nible: - program = data[0] - stream.patch_change(channel, program) - - elif (CHANNEL_PRESSURE & 0xF0) == hi_nible: - pressure = data[0] - stream.channel_pressure(channel, pressure) - - elif (PITCH_BEND & 0xF0) == hi_nible: - hibyte, lobyte = data - value = (hibyte<<7) + lobyte - stream.pitch_bend(channel, value) - - else: - - raise ValueError, 'Illegal channel message!' - - - - def continuous_controllers(self, channel, controller, value): - - "Dispatches channel messages" - - stream = self.outstream - - # I am not really shure if I ought to dispatch continuous controllers - # There's so many of them that it can clutter up the OutStream - # classes. - - # So I just trigger the default event handler - stream.continuous_controller(channel, controller, value) - - - - def system_commons(self, common_type, common_data): - - "Dispatches system common messages" - - stream = self.outstream - - # MTC Midi time code Quarter value - if common_type == MTC: - data = readBew(common_data) - msg_type = (data & 0x07) >> 4 - values = (data & 0x0F) - stream.midi_time_code(msg_type, values) - - elif common_type == SONG_POSITION_POINTER: - hibyte, lobyte = toBytes(common_data) - value = (hibyte<<7) + lobyte - stream.song_position_pointer(value) - - elif common_type == SONG_SELECT: - data = readBew(common_data) - stream.song_select(data) - - elif common_type == TUNING_REQUEST: - # no data then - stream.tuning_request(time=None) - - - - def meta_event(self, meta_type, data): - - "Dispatches meta events" - - stream = self.outstream - - # SEQUENCE_NUMBER = 0x00 (00 02 ss ss (seq-number)) - if meta_type == SEQUENCE_NUMBER: - number = readBew(data) - stream.sequence_number(number) - - # TEXT = 0x01 (01 len text...) - elif meta_type == TEXT: - stream.text(data) - - # COPYRIGHT = 0x02 (02 len text...) - elif meta_type == COPYRIGHT: - stream.copyright(data) - - # SEQUENCE_NAME = 0x03 (03 len text...) - elif meta_type == SEQUENCE_NAME: - stream.sequence_name(data) - - # INSTRUMENT_NAME = 0x04 (04 len text...) - elif meta_type == INSTRUMENT_NAME: - stream.instrument_name(data) - - # LYRIC = 0x05 (05 len text...) - elif meta_type == LYRIC: - stream.lyric(data) - - # MARKER = 0x06 (06 len text...) - elif meta_type == MARKER: - stream.marker(data) - - # CUEPOINT = 0x07 (07 len text...) - elif meta_type == CUEPOINT: - stream.cuepoint(data) - - # PROGRAM_NAME = 0x08 (05 len text...) - elif meta_type == PROGRAM_NAME: - stream.program_name(data) - - # DEVICE_NAME = 0x09 (09 len text...) - elif meta_type == DEVICE_NAME: - stream.device_name(data) - - # MIDI_CH_PREFIX = 0x20 (20 01 channel) - elif meta_type == MIDI_CH_PREFIX: - channel = readBew(data) - stream.midi_ch_prefix(channel) - - # MIDI_PORT = 0x21 (21 01 port (legacy stuff)) - elif meta_type == MIDI_PORT: - port = readBew(data) - stream.midi_port(port) - - # END_OFF_TRACK = 0x2F (2F 00) - elif meta_type == END_OF_TRACK: - stream.end_of_track() - - # TEMPO = 0x51 (51 03 tt tt tt (tempo in us/quarternote)) - elif meta_type == TEMPO: - b1, b2, b3 = toBytes(data) - # uses 3 bytes to represent time between quarter - # notes in microseconds - stream.tempo((b1<<16) + (b2<<8) + b3) - - # SMTP_OFFSET = 0x54 (54 05 hh mm ss ff xx) - elif meta_type == SMTP_OFFSET: - hour, minute, second, frame, framePart = toBytes(data) - stream.smtp_offset( - hour, minute, second, frame, framePart) - - # TIME_SIGNATURE = 0x58 (58 04 nn dd cc bb) - elif meta_type == TIME_SIGNATURE: - nn, dd, cc, bb = toBytes(data) - stream.time_signature(nn, dd, cc, bb) - - # KEY_SIGNATURE = 0x59 (59 02 sf mi) - elif meta_type == KEY_SIGNATURE: - sf, mi = toBytes(data) - stream.key_signature(sf, mi) - - # SPECIFIC = 0x7F (Sequencer specific event) - elif meta_type == SPECIFIC: - meta_data = toBytes(data) - stream.sequencer_specific(meta_data) - - # Handles any undefined meta events - else: # undefined meta type - meta_data = toBytes(data) - stream.meta_event(meta_type, meta_data) - - - - - -if __name__ == '__main__': - - - from MidiToText import MidiToText - - outstream = MidiToText() - dispatcher = EventDispatcher(outstream) - dispatcher.channel_messages(NOTE_ON, 0x00, '\x40\x40') \ No newline at end of file diff --git a/src/mxmMidi/MidiFileParser.py b/src/mxmMidi/MidiFileParser.py deleted file mode 100644 index 2b447bc..0000000 --- a/src/mxmMidi/MidiFileParser.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -# std library -from struct import unpack - -# uhh I don't really like this, but there are so many constants to -# import otherwise -from constants import * - -from EventDispatcher import EventDispatcher - -class MidiFileParser: - - """ - - The MidiFileParser is the lowest level parser that see the data as - midi data. It generates events that gets triggered on the outstream. - - """ - - def __init__(self, raw_in, outstream): - - """ - raw_data is the raw content of a midi file as a string. - """ - - # internal values, don't mess with 'em directly - self.raw_in = raw_in - self.dispatch = EventDispatcher(outstream) - - # Used to keep track of stuff - self._running_status = None - - - - - def parseMThdChunk(self): - - "Parses the header chunk" - - raw_in = self.raw_in - - header_chunk_type = raw_in.nextSlice(4) - header_chunk_zise = raw_in.readBew(4) - - # check if it is a proper midi file - if header_chunk_type != 'MThd': - raise TypeError, "It is not a valid midi file!" - - # Header values are at fixed locations, so no reason to be clever - self.format = raw_in.readBew(2) - self.nTracks = raw_in.readBew(2) - self.division = raw_in.readBew(2) - - # Theoretically a header larger than 6 bytes can exist - # but no one has seen one in the wild - # But correctly ignore unknown data if it is though - if header_chunk_zise > 6: - raw_in.moveCursor(header_chunk_zise-6) - - # call the header event handler on the stream - self.dispatch.header(self.format, self.nTracks, self.division) - - - - def parseMTrkChunk(self): - - "Parses a track chunk. This is the most important part of the parser." - - # set time to 0 at start of a track - self.dispatch.reset_time() - - dispatch = self.dispatch - raw_in = self.raw_in - - # Trigger event at the start of a track - dispatch.start_of_track(self._current_track) - # position cursor after track header - raw_in.moveCursor(4) - # unsigned long is 4 bytes - tracklength = raw_in.readBew(4) - track_endposition = raw_in.getCursor() + tracklength # absolute position! - - while raw_in.getCursor() < track_endposition: - - # find relative time of the event - time = raw_in.readVarLen() - dispatch.update_time(time) - - # be aware of running status!!!! - peak_ahead = raw_in.readBew(move_cursor=0) - if (peak_ahead & 0x80): - # the status byte has the high bit set, so it - # was not running data but proper status byte - status = self._running_status = raw_in.readBew() - else: - # use that darn running status - status = self._running_status - # could it be illegal data ?? Do we need to test for that? - # I need more example midi files to be shure. - - # Also, while I am almost certain that no realtime - # messages will pop up in a midi file, I might need to - # change my mind later. - - # we need to look at nibbles here - hi_nible, lo_nible = status & 0xF0, status & 0x0F - - # match up with events - - # Is it a meta_event ?? - # these only exists in midi files, not in transmitted midi data - # In transmitted data META_EVENT (0xFF) is a system reset - if status == META_EVENT: - meta_type = raw_in.readBew() - meta_length = raw_in.readVarLen() - meta_data = raw_in.nextSlice(meta_length) - dispatch.meta_event(meta_type, meta_data) - - - # Is it a sysex_event ?? - elif status == SYSTEM_EXCLUSIVE: - # ignore sysex events - sysex_length = raw_in.readVarLen() - # don't read sysex terminator - sysex_data = raw_in.nextSlice(sysex_length-1) - # only read last data byte if it is a sysex terminator - # It should allways be there, but better safe than sorry - if raw_in.readBew(move_cursor=0) == END_OFF_EXCLUSIVE: - eo_sysex = raw_in.readBew() - dispatch.sysex_event(sysex_data) - # the sysex code has not been properly tested, and might be fishy! - - - # is it a system common event? - elif hi_nible == 0xF0: # Hi bits are set then - data_sizes = { - MTC:1, - SONG_POSITION_POINTER:2, - SONG_SELECT:1, - } - data_size = data_sizes.get(hi_nible, 0) - common_data = raw_in.nextSlice(data_size) - common_type = lo_nible - dispatch.system_common(common_type, common_data) - - - # Oh! Then it must be a midi event (channel voice message) - else: - data_sizes = { - PATCH_CHANGE:1, - CHANNEL_PRESSURE:1, - NOTE_OFF:2, - NOTE_ON:2, - AFTERTOUCH:2, - CONTINUOUS_CONTROLLER:2, - PITCH_BEND:2, - } - data_size = data_sizes.get(hi_nible, 0) - channel_data = raw_in.nextSlice(data_size) - event_type, channel = hi_nible, lo_nible - dispatch.channel_messages(event_type, channel, channel_data) - - - def parseMTrkChunks(self): - "Parses all track chunks." - for t in range(self.nTracks): - self._current_track = t - self.parseMTrkChunk() # this is where it's at! - self.dispatch.eof() - - - -if __name__ == '__main__': - - # get data - test_file = 'test/midifiles/minimal.mid' - test_file = 'test/midifiles/cubase-minimal.mid' - test_file = 'test/midifiles/Lola.mid' -# f = open(test_file, 'rb') -# raw_data = f.read() -# f.close() -# -# -# # do parsing - from MidiToText import MidiToText - from RawInstreamFile import RawInstreamFile - - midi_in = MidiFileParser(RawInstreamFile(test_file), MidiToText()) - midi_in.parseMThdChunk() - midi_in.parseMTrkChunks() - \ No newline at end of file diff --git a/src/mxmMidi/MidiInFile.py b/src/mxmMidi/MidiInFile.py deleted file mode 100644 index 57f4c7e..0000000 --- a/src/mxmMidi/MidiInFile.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -from RawInstreamFile import RawInstreamFile -from MidiFileParser import MidiFileParser - - -class MidiInFile: - - """ - - Parses a midi file, and triggers the midi events on the outStream - object. - - Get example data from a minimal midi file, generated with cubase. - >>> test_file = 'C:/Documents and Settings/maxm/Desktop/temp/midi/src/midi/tests/midifiles/minimal-cubase-type0.mid' - - Do parsing, and generate events with MidiToText, - so we can see what a minimal midi file contains - >>> from MidiToText import MidiToText - >>> midi_in = MidiInFile(MidiToText(), test_file) - >>> midi_in.read() - format: 0, nTracks: 1, division: 480 - ---------------------------------- - - Start - track #0 - sequence_name: Type 0 - tempo: 500000 - time_signature: 4 2 24 8 - note_on - ch:00, note:48, vel:64 time:0 - note_off - ch:00, note:48, vel:40 time:480 - End of track - - End of file - - - """ - - def __init__(self, outStream, infile): - # these could also have been mixins, would that be better? Nah! - self.raw_in = RawInstreamFile(infile) - self.parser = MidiFileParser(self.raw_in, outStream) - - - def read(self): - "Start parsing the file" - p = self.parser - p.parseMThdChunk() - p.parseMTrkChunks() - - - def setData(self, data=''): - "Sets the data from a plain string" - self.raw_in.setData(data) - - diff --git a/src/mxmMidi/MidiInStream.py b/src/mxmMidi/MidiInStream.py deleted file mode 100644 index 22f7e09..0000000 --- a/src/mxmMidi/MidiInStream.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -from MidiOutStream import MidiOutStream - -class MidiInStream: - - """ - Takes midi events from the midi input and calls the apropriate - method in the eventhandler object - """ - - def __init__(self, midiOutStream, device): - - """ - - Sets a default output stream, and sets the device from where - the input comes - - """ - - if midiOutStream is None: - self.midiOutStream = MidiOutStream() - else: - self.midiOutStream = midiOutStream - - - def close(self): - - """ - Stop the MidiInstream - """ - - - def read(self, time=0): - - """ - - Start the MidiInstream. - - "time" sets timer to specific start value. - - """ - - - def resetTimer(self, time=0): - """ - - Resets the timer, probably a good idea if there is some kind - of looping going on - - """ - diff --git a/src/mxmMidi/MidiOutFile.py b/src/mxmMidi/MidiOutFile.py deleted file mode 100644 index a39bc9f..0000000 --- a/src/mxmMidi/MidiOutFile.py +++ /dev/null @@ -1,448 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -from MidiOutStream import MidiOutStream -from RawOutstreamFile import RawOutstreamFile - -from constants import * -from DataTypeConverters import fromBytes, writeVar - -class MidiOutFile(MidiOutStream): - - - """ - MidiOutFile is an eventhandler that subclasses MidiOutStream. - """ - - - def __init__(self, raw_out=''): - - self.raw_out = RawOutstreamFile(raw_out) - MidiOutStream.__init__(self) - - - def write(self): - self.raw_out.write() - - - def event_slice(self, slc): - """ - Writes the slice of an event to the current track. Correctly - inserting a varlen timestamp too. - """ - trk = self._current_track_buffer - trk.writeVarLen(self.rel_time()) - trk.writeSlice(slc) - - - ##################### - ## Midi events - - - def note_on(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - slc = fromBytes([NOTE_ON + channel, note, velocity]) - self.event_slice(slc) - - - def note_off(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - slc = fromBytes([NOTE_OFF + channel, note, velocity]) - self.event_slice(slc) - - - def aftertouch(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - slc = fromBytes([AFTERTOUCH + channel, note, velocity]) - self.event_slice(slc) - - - def continuous_controller(self, channel, controller, value): - - """ - channel: 0-15 - controller, value: 0-127 - """ - slc = fromBytes([CONTINUOUS_CONTROLLER + channel, controller, value]) - self.event_slice(slc) - # These should probably be implemented - # http://users.argonet.co.uk/users/lenny/midi/tech/spec.html#ctrlnums - - - def patch_change(self, channel, patch): - - """ - channel: 0-15 - patch: 0-127 - """ - slc = fromBytes([PATCH_CHANGE + channel, patch]) - self.event_slice(slc) - - - def channel_pressure(self, channel, pressure): - - """ - channel: 0-15 - pressure: 0-127 - """ - slc = fromBytes([CHANNEL_PRESSURE + channel, pressure]) - self.event_slice(slc) - - - def pitch_bend(self, channel, value): - - """ - channel: 0-15 - value: 0-16383 - """ - msb = (value>>7) & 0xFF - lsb = value & 0xFF - slc = fromBytes([PITCH_BEND + channel, msb, lsb]) - self.event_slice(slc) - - - - - ##################### - ## System Exclusive - -# def sysex_slice(sysex_type, data): -# "" -# sysex_len = writeVar(len(data)+1) -# self.event_slice(SYSTEM_EXCLUSIVE + sysex_len + data + END_OFF_EXCLUSIVE) -# - def system_exclusive(self, data): - - """ - data: list of values in range(128) - """ - sysex_len = writeVar(len(data)+1) - self.event_slice(chr(SYSTEM_EXCLUSIVE) + sysex_len + data + chr(END_OFF_EXCLUSIVE)) - - - ##################### - ## Common events - - def midi_time_code(self, msg_type, values): - """ - msg_type: 0-7 - values: 0-15 - """ - value = (msg_type<<4) + values - self.event_slice(fromBytes([MIDI_TIME_CODE, value])) - - - def song_position_pointer(self, value): - - """ - value: 0-16383 - """ - lsb = (value & 0x7F) - msb = (value >> 7) & 0x7F - self.event_slice(fromBytes([SONG_POSITION_POINTER, lsb, msb])) - - - def song_select(self, songNumber): - - """ - songNumber: 0-127 - """ - self.event_slice(fromBytes([SONG_SELECT, songNumber])) - - - def tuning_request(self): - - """ - No values passed - """ - self.event_slice(chr(TUNING_REQUEST)) - - - ######################### - # header does not really belong here. But anyhoo!!! - - def header(self, format=0, nTracks=1, division=96): - - """ - format: type of midi file in [0,1,2] - nTracks: number of tracks. 1 track for type 0 file - division: timing division ie. 96 ppq. - - """ - raw = self.raw_out - raw.writeSlice('MThd') - bew = raw.writeBew - bew(6, 4) # header size - bew(format, 2) - bew(nTracks, 2) - bew(division, 2) - - - def eof(self): - - """ - End of file. No more events to be processed. - """ - # just write the file then. - self.write() - - - ##################### - ## meta events - - - def meta_slice(self, meta_type, data_slice): - "Writes a meta event" - slc = fromBytes([META_EVENT, meta_type]) + \ - writeVar(len(data_slice)) + data_slice - self.event_slice(slc) - - - def meta_event(self, meta_type, data): - """ - Handles any undefined meta events - """ - self.meta_slice(meta_type, fromBytes(data)) - - - def start_of_track(self, n_track=0): - """ - n_track: number of track - """ - self._current_track_buffer = RawOutstreamFile() - self.reset_time() - self._current_track += 1 - - - def end_of_track(self): - """ - Writes the track to the buffer. - """ - raw = self.raw_out - raw.writeSlice(TRACK_HEADER) - track_data = self._current_track_buffer.getvalue() - # wee need to know size of track data. - eot_slice = writeVar(self.rel_time()) + fromBytes([META_EVENT, END_OF_TRACK, 0]) - raw.writeBew(len(track_data)+len(eot_slice), 4) - # then write - raw.writeSlice(track_data) - raw.writeSlice(eot_slice) - - - - def sequence_number(self, value): - - """ - value: 0-65535 - """ - self.meta_slice(meta_type, writeBew(value, 2)) - - - def text(self, text): - """ - Text event - text: string - """ - self.meta_slice(TEXT, text) - - - def copyright(self, text): - - """ - Copyright notice - text: string - """ - self.meta_slice(COPYRIGHT, text) - - - def sequence_name(self, text): - """ - Sequence/track name - text: string - """ - self.meta_slice(SEQUENCE_NAME, text) - - - def instrument_name(self, text): - - """ - text: string - """ - self.meta_slice(INSTRUMENT_NAME, text) - - - def lyric(self, text): - - """ - text: string - """ - self.meta_slice(LYRIC, text) - - - def marker(self, text): - - """ - text: string - """ - self.meta_slice(MARKER, text) - - - def cuepoint(self, text): - - """ - text: string - """ - self.meta_slice(CUEPOINT, text) - - - def midi_ch_prefix(self, channel): - - """ - channel: midi channel for subsequent data - (deprecated in the spec) - """ - self.meta_slice(MIDI_CH_PREFIX, chr(channel)) - - - def midi_port(self, value): - - """ - value: Midi port (deprecated in the spec) - """ - self.meta_slice(MIDI_CH_PREFIX, chr(value)) - - - def tempo(self, value): - - """ - value: 0-2097151 - tempo in us/quarternote - (to calculate value from bpm: int(60,000,000.00 / BPM)) - """ - hb, mb, lb = (value>>16 & 0xff), (value>>8 & 0xff), (value & 0xff) - self.meta_slice(TEMPO, fromBytes([hb, mb, lb])) - - - def smtp_offset(self, hour, minute, second, frame, framePart): - - """ - hour, - minute, - second: 3 bytes specifying the hour (0-23), minutes (0-59) and - seconds (0-59), respectively. The hour should be - encoded with the SMPTE format, just as it is in MIDI - Time Code. - frame: A byte specifying the number of frames per second (one - of : 24, 25, 29, 30). - framePart: A byte specifying the number of fractional frames, - in 100ths of a frame (even in SMPTE-based tracks - using a different frame subdivision, defined in the - MThd chunk). - """ - self.meta_slice(SMTP_OFFSET, fromBytes([hour, minute, second, frame, framePart])) - - - - def time_signature(self, nn, dd, cc, bb): - - """ - nn: Numerator of the signature as notated on sheet music - dd: Denominator of the signature as notated on sheet music - The denominator is a negative power of 2: 2 = quarter - note, 3 = eighth, etc. - cc: The number of MIDI clocks in a metronome click - bb: The number of notated 32nd notes in a MIDI quarter note - (24 MIDI clocks) - """ - self.meta_slice(TIME_SIGNATURE, fromBytes([nn, dd, cc, bb])) - - - - - def key_signature(self, sf, mi): - - """ - sf: is a byte specifying the number of flats (-ve) or sharps - (+ve) that identifies the key signature (-7 = 7 flats, -1 - = 1 flat, 0 = key of C, 1 = 1 sharp, etc). - mi: is a byte specifying a major (0) or minor (1) key. - """ - self.meta_slice(KEY_SIGNATURE, fromBytes([sf, mi])) - - - - def sequencer_specific(self, data): - - """ - data: The data as byte values - """ - self.meta_slice(SEQUENCER_SPECIFIC, data) - - - - - -# ##################### -# ## realtime events - -# These are of no use in a midi file, so they are ignored!!! - -# def timing_clock(self): -# def song_start(self): -# def song_stop(self): -# def song_continue(self): -# def active_sensing(self): -# def system_reset(self): - - - -if __name__ == '__main__': - - out_file = 'test/midifiles/midiout.mid' - midi = MidiOutFile(out_file) - -#format: 0, nTracks: 1, division: 480 -#---------------------------------- -# -#Start - track #0 -#sequence_name: Type 0 -#tempo: 500000 -#time_signature: 4 2 24 8 -#note_on - ch:00, note:48, vel:64 time:0 -#note_off - ch:00, note:48, vel:40 time:480 -#End of track -# -#End of file - - - midi.header(0, 1, 480) - - midi.start_of_track() - midi.sequence_name('Type 0') - midi.tempo(750000) - midi.time_signature(4, 2, 24, 8) - ch = 0 - for i in range(127): - midi.note_on(ch, i, 0x64) - midi.update_time(96) - midi.note_off(ch, i, 0x40) - midi.update_time(0) - - midi.update_time(0) - midi.end_of_track() - - midi.eof() # currently optional, should it do the write instead of write?? - - - midi.write() \ No newline at end of file diff --git a/src/mxmMidi/MidiOutStream.py b/src/mxmMidi/MidiOutStream.py deleted file mode 100644 index c128fa6..0000000 --- a/src/mxmMidi/MidiOutStream.py +++ /dev/null @@ -1,471 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -class MidiOutStream: - - - """ - - MidiOutstream is Basically an eventhandler. It is the most central - class in the Midi library. You use it both for writing events to - an output stream, and as an event handler for an input stream. - - This makes it extremely easy to take input from one stream and - send it to another. Ie. if you want to read a Midi file, do some - processing, and send it to a midiport. - - All time values are in absolute values from the opening of a - stream. To calculate time values, please use the MidiTime and - MidiDeltaTime classes. - - """ - - def __init__(self): - - # the time is rather global, so it needs to be stored - # here. Otherwise there would be no really simple way to - # calculate it. The alternative would be to have each event - # handler do it. That sucks even worse! - self._absolute_time = 0 - self._relative_time = 0 - self._current_track = 0 - self._running_status = None - - # time handling event handlers. They should be overwritten with care - - def update_time(self, new_time=0, relative=1): - """ - Updates the time, if relative is true, new_time is relative, - else it's absolute. - """ - if relative: - self._relative_time = new_time - self._absolute_time += new_time - else: - self._relative_time = new_time - self._absolute_time - self._absolute_time = new_time - - def reset_time(self): - """ - reset time to 0 - """ - self._relative_time = 0 - self._absolute_time = 0 - - def rel_time(self): - "Returns the relative time" - return self._relative_time - - def abs_time(self): - "Returns the absolute time" - return self._absolute_time - - # running status methods - - def reset_run_stat(self): - "Invalidates the running status" - self._running_status = None - - def set_run_stat(self, new_status): - "Set the new running status" - self._running_status = new_status - - def get_run_stat(self): - "Set the new running status" - return self._running_status - - # track handling event handlers - - def set_current_track(self, new_track): - "Sets the current track number" - self._current_track = new_track - - def get_current_track(self): - "Returns the current track number" - return self._current_track - - - ##################### - ## Midi events - - - def channel_message(self, message_type, channel, data): - """The default event handler for channel messages""" - pass - - - def note_on(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - pass - - - def note_off(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - pass - - - def aftertouch(self, channel=0, note=0x40, velocity=0x40): - - """ - channel: 0-15 - note, velocity: 0-127 - """ - pass - - - def continuous_controller(self, channel, controller, value): - - """ - channel: 0-15 - controller, value: 0-127 - """ - pass - - - def patch_change(self, channel, patch): - - """ - channel: 0-15 - patch: 0-127 - """ - pass - - - def channel_pressure(self, channel, pressure): - - """ - channel: 0-15 - pressure: 0-127 - """ - pass - - - def pitch_bend(self, channel, value): - - """ - channel: 0-15 - value: 0-16383 - - """ - pass - - - - - ##################### - ## System Exclusive - - def system_exclusive(self, data): - - """ - data: list of values in range(128) - """ - pass - - - ##################### - ## Common events - - def song_position_pointer(self, value): - - """ - value: 0-16383 - """ - pass - - - def song_select(self, songNumber): - - """ - songNumber: 0-127 - """ - pass - - - def tuning_request(self): - - """ - No values passed - """ - pass - - - def midi_time_code(self, msg_type, values): - """ - msg_type: 0-7 - values: 0-15 - """ - pass - - - ######################### - # header does not really belong here. But anyhoo!!! - - def header(self, format=0, nTracks=1, division=96): - - """ - format: type of midi file in [1,2] - nTracks: number of tracks - division: timing division - """ - pass - - - def eof(self): - - """ - End of file. No more events to be processed. - """ - pass - - - ##################### - ## meta events - - - def meta_event(self, meta_type, data): - - """ - Handles any undefined meta events - """ - pass - - - def start_of_track(self, n_track=0): - - """ - n_track: number of track - """ - pass - - - def end_of_track(self): - - """ - n_track: number of track - """ - pass - - - def sequence_number(self, value): - - """ - value: 0-16383 - """ - pass - - - def text(self, text): - - """ - Text event - text: string - """ - pass - - - def copyright(self, text): - - """ - Copyright notice - text: string - """ - pass - - - def sequence_name(self, text): - - """ - Sequence/track name - text: string - """ - pass - - - def instrument_name(self, text): - - """ - text: string - """ - pass - - - def lyric(self, text): - - """ - text: string - """ - pass - - - def marker(self, text): - - """ - text: string - """ - pass - - - def cuepoint(self, text): - - """ - text: string - """ - pass - - - def midi_ch_prefix(self, channel): - - """ - channel: midi channel for subsequent data (deprecated in the spec) - """ - pass - - - def midi_port(self, value): - - """ - value: Midi port (deprecated in the spec) - """ - pass - - - def tempo(self, value): - - """ - value: 0-2097151 - tempo in us/quarternote - (to calculate value from bpm: int(60,000,000.00 / BPM)) - """ - pass - - - def smtp_offset(self, hour, minute, second, frame, framePart): - - """ - hour, - minute, - second: 3 bytes specifying the hour (0-23), minutes (0-59) and - seconds (0-59), respectively. The hour should be - encoded with the SMPTE format, just as it is in MIDI - Time Code. - frame: A byte specifying the number of frames per second (one - of : 24, 25, 29, 30). - framePart: A byte specifying the number of fractional frames, - in 100ths of a frame (even in SMPTE-based tracks - using a different frame subdivision, defined in the - MThd chunk). - """ - pass - - - - def time_signature(self, nn, dd, cc, bb): - - """ - nn: Numerator of the signature as notated on sheet music - dd: Denominator of the signature as notated on sheet music - The denominator is a negative power of 2: 2 = quarter - note, 3 = eighth, etc. - cc: The number of MIDI clocks in a metronome click - bb: The number of notated 32nd notes in a MIDI quarter note - (24 MIDI clocks) - """ - pass - - - - def key_signature(self, sf, mi): - - """ - sf: is a byte specifying the number of flats (-ve) or sharps - (+ve) that identifies the key signature (-7 = 7 flats, -1 - = 1 flat, 0 = key of C, 1 = 1 sharp, etc). - mi: is a byte specifying a major (0) or minor (1) key. - """ - pass - - - - def sequencer_specific(self, data): - - """ - data: The data as byte values - """ - pass - - - - - ##################### - ## realtime events - - def timing_clock(self): - - """ - No values passed - """ - pass - - - - def song_start(self): - - """ - No values passed - """ - pass - - - - def song_stop(self): - - """ - No values passed - """ - pass - - - - def song_continue(self): - - """ - No values passed - """ - pass - - - - def active_sensing(self): - - """ - No values passed - """ - pass - - - - def system_reset(self): - - """ - No values passed - """ - pass - - - -if __name__ == '__main__': - - midiOut = MidiOutStream() - midiOut.update_time(0,0) - midiOut.note_on(0, 63, 127) - midiOut.note_off(0, 63, 127) - - \ No newline at end of file diff --git a/src/mxmMidi/MidiToText.py b/src/mxmMidi/MidiToText.py deleted file mode 100644 index 7a35ff3..0000000 --- a/src/mxmMidi/MidiToText.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -from MidiOutStream import MidiOutStream -class MidiToText(MidiOutStream): - - - """ - This class renders a midi file as text. It is mostly used for debugging - """ - - ############################# - # channel events - - def channel_message(self, message_type, channel, data): - """The default event handler for channel messages""" - print 'message_type:%X, channel:%X, data size:%X' % (message_type, channel, len(data)) - - - def note_on(self, channel=0, note=0x40, velocity=0x40): - print 'note_on - ch:%02X, note:%02X, vel:%02X time:%s' % (channel, note, velocity, self.timeInMs()) - - def note_off(self, channel=0, note=0x40, velocity=0x40): - print 'note_off - ch:%02X, note:%02X, vel:%02X time:%s' % (channel, note, velocity, self.abs_time()) - - def aftertouch(self, channel=0, note=0x40, velocity=0x40): - print 'aftertouch', channel, note, velocity - - - def continuous_controller(self, channel, controller, value): - print 'controller - ch: %02X, cont: #%02X, value: %02X' % (channel, controller, value) - - - def patch_change(self, channel, patch): - print 'patch_change - ch:%02X, patch:%02X' % (channel, patch) - - - def channel_pressure(self, channel, pressure): - print 'channel_pressure', channel, pressure - - - def pitch_bend(self, channel, value): - print 'pitch_bend ch:%s, value:%s' % (channel, value) - - - - ##################### - ## Common events - - - def system_exclusive(self, data): - print 'system_exclusive - data size: %s' % len(data) - - - def song_position_pointer(self, value): - print 'song_position_pointer: %s' % value - - - def song_select(self, songNumber): - print 'song_select: %s' % songNumber - - - def tuning_request(self): - print 'tuning_request' - - - def midi_time_code(self, msg_type, values): - print 'midi_time_code - msg_type: %s, values: %s' % (msg_type, values) - - - - ######################### - # header does not really belong here. But anyhoo!!! - - def header(self, format=0, nTracks=1, division=96): - print 'format: %s, nTracks: %s, division: %s' % (format, nTracks, division) - print '----------------------------------' - print '' - print division - self.division = division - - def eof(self): - print 'End of file' - - - def start_of_track(self, n_track=0): - print 'Start - track #%s' % n_track - - - def end_of_track(self): - print 'End of track' - print '' - - - - ############### - # sysex event - - def sysex_event(self, data): - print 'sysex_event - datasize: %X' % len(data) - - - ##################### - ## meta events - - def meta_event(self, meta_type, data): - print 'undefined_meta_event:', meta_type, len(data) - - - def sequence_number(self, value): - print 'sequence_number', value - - - def text(self, text): - print 'text', text - - - def copyright(self, text): - print 'copyright', text - - - def sequence_name(self, text): - print 'sequence_name:', text - - - def instrument_name(self, text): - print 'instrument_name:', text - - - def lyric(self, text): - print 'lyric', text - - - def marker(self, text): - print 'marker', text - - - def cuepoint(self, text): - print 'cuepoint', text - - - def midi_ch_prefix(self, channel): - print 'midi_ch_prefix', channel - - - def midi_port(self, value): - print 'midi_port:', value - - - def tempo(self, value): - print 'tempo:', value - self.tempo = value - - - def smtp_offset(self, hour, minute, second, frame, framePart): - print 'smtp_offset', hour, minute, second, frame, framePart - - - def time_signature(self, nn, dd, cc, bb): - print 'time_signature:', nn, dd, cc, bb - - - def key_signature(self, sf, mi): - print 'key_signature', sf, mi - - - def sequencer_specific(self, data): - print 'sequencer_specific', len(data) - - def timeInMs(self): - return(long(self.abs_time())*1000000000/(long(self.tempo)*long(self.division))) - - - -if __name__ == '__main__': - - # get data - test_file = '../songs/midis/test.mid' - f = open(test_file, 'rb') - - # do parsing - from MidiInFile import MidiInFile - midiIn = MidiInFile(MidiToText(), f) - midiIn.read() - f.close() diff --git a/src/mxmMidi/RawInstreamFile.py b/src/mxmMidi/RawInstreamFile.py deleted file mode 100644 index 0c2eba6..0000000 --- a/src/mxmMidi/RawInstreamFile.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -# standard library imports -from types import StringType -from struct import unpack - -# custom import -from DataTypeConverters import readBew, readVar, varLen - - -class RawInstreamFile: - - """ - - It parses and reads data from an input file. It takes care of big - endianess, and keeps track of the cursor position. The midi parser - only reads from this object. Never directly from the file. - - """ - - def __init__(self, infile=''): - """ - If 'file' is a string we assume it is a path and read from - that file. - If it is a file descriptor we read from the file, but we don't - close it. - Midi files are usually pretty small, so it should be safe to - copy them into memory. - """ - if infile: - if isinstance(infile, StringType): - infile = open(infile, 'rb') - self.data = infile.read() - infile.close() - else: - # don't close the f - self.data = infile.read() - else: - self.data = '' - # start at beginning ;-) - self.cursor = 0 - - - # setting up data manually - - def setData(self, data=''): - "Sets the data from a string." - self.data = data - - # cursor operations - - def setCursor(self, position=0): - "Sets the absolute position if the cursor" - self.cursor = position - - - def getCursor(self): - "Returns the value of the cursor" - return self.cursor - - - def moveCursor(self, relative_position=0): - "Moves the cursor to a new relative position" - self.cursor += relative_position - - # native data reading functions - - def nextSlice(self, length, move_cursor=1): - "Reads the next text slice from the raw data, with length" - c = self.cursor - slc = self.data[c:c+length] - if move_cursor: - self.moveCursor(length) - return slc - - - def readBew(self, n_bytes=1, move_cursor=1): - """ - Reads n bytes of date from the current cursor position. - Moves cursor if move_cursor is true - """ - return readBew(self.nextSlice(n_bytes, move_cursor)) - - - def readVarLen(self): - """ - Reads a variable length value from the current cursor position. - Moves cursor if move_cursor is true - """ - MAX_VARLEN = 4 # Max value varlen can be - var = readVar(self.nextSlice(MAX_VARLEN, 0)) - # only move cursor the actual bytes in varlen - self.moveCursor(varLen(var)) - return var - - - -if __name__ == '__main__': - - test_file = 'test/midifiles/minimal.mid' - fis = RawInstreamFile(test_file) - print fis.nextSlice(len(fis.data)) - - test_file = 'test/midifiles/cubase-minimal.mid' - cubase_minimal = open(test_file, 'rb') - fis2 = RawInstreamFile(cubase_minimal) - print fis2.nextSlice(len(fis2.data)) - cubase_minimal.close() diff --git a/src/mxmMidi/RawOutstreamFile.py b/src/mxmMidi/RawOutstreamFile.py deleted file mode 100644 index 73eed31..0000000 --- a/src/mxmMidi/RawOutstreamFile.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -# standard library imports -import sys -from types import StringType -from struct import unpack -from cStringIO import StringIO - -# custom import -from DataTypeConverters import writeBew, writeVar, fromBytes - -class RawOutstreamFile: - - """ - - Writes a midi file to disk. - - """ - - def __init__(self, outfile=''): - self.buffer = StringIO() - self.outfile = outfile - - - # native data reading functions - - - def writeSlice(self, str_slice): - "Writes the next text slice to the raw data" - self.buffer.write(str_slice) - - - def writeBew(self, value, length=1): - "Writes a value to the file as big endian word" - self.writeSlice(writeBew(value, length)) - - - def writeVarLen(self, value): - "Writes a variable length word to the file" - var = self.writeSlice(writeVar(value)) - - - def write(self): - "Writes to disc" - if self.outfile: - if isinstance(self.outfile, StringType): - outfile = open(self.outfile, 'wb') - outfile.write(self.getvalue()) - outfile.close() - else: - self.outfile.write(self.getvalue()) - else: - sys.stdout.write(self.getvalue()) - - def getvalue(self): - return self.buffer.getvalue() - - -if __name__ == '__main__': - - out_file = 'test/midifiles/midiout.mid' - out_file = '' - rawOut = RawOutstreamFile(out_file) - rawOut.writeSlice('MThd') - rawOut.writeBew(6, 4) - rawOut.writeBew(1, 2) - rawOut.writeBew(2, 2) - rawOut.writeBew(15360, 2) - rawOut.write() diff --git a/src/mxmMidi/__init__.py b/src/mxmMidi/__init__.py deleted file mode 100644 index b2d2031..0000000 --- a/src/mxmMidi/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -#import MidiOutStream -#import MidiInStream -#import MidiInFile -#import MidiToText \ No newline at end of file diff --git a/src/mxmMidi/changes.txt b/src/mxmMidi/changes.txt deleted file mode 100644 index 8b6670a..0000000 --- a/src/mxmMidi/changes.txt +++ /dev/null @@ -1,45 +0,0 @@ ------------------------------------------------------------------------- -r409 | maxm | 2006-01-05 16:37:29 +0100 (to, 05 jan 2006) | 1 line - -Made RawOutstreamFile.py write to std out if no outfile is given. ------------------------------------------------------------------------- -r403 | maxm | 2006-01-05 13:34:11 +0100 (to, 05 jan 2006) | 1 line - - ------------------------------------------------------------------------- -r402 | maxm | 2006-01-05 13:33:56 +0100 (to, 05 jan 2006) | 1 line - -- Fixed minor bugs, added coding headers ------------------------------------------------------------------------- -r401 | maxm | 2006-01-01 23:09:17 +0100 (s_, 01 jan 2006) | 1 line - -Fixed sysex dispathcer bug. ------------------------------------------------------------------------- -r268 | maxm | 2005-02-04 12:26:59 +0100 (fr, 04 feb 2005) | 1 line - - ------------------------------------------------------------------------- -r128 | maxm | 2004-12-18 14:05:27 +0100 (l_, 18 dec 2004) | 1 line - -Fixed bug when using relative time ------------------------------------------------------------------------- -r15 | maxm | 2004-03-09 15:01:41 +0100 (ti, 09 mar 2004) | 1 line - -made a copy to meta folder ------------------------------------------------------------------------- -r13 | maxm | 2004-03-09 09:17:23 +0100 (ti, 09 mar 2004) | 1 line - -Deleted .pyc files ------------------------------------------------------------------------- -r12 | maxm | 2004-03-09 09:15:54 +0100 (ti, 09 mar 2004) | 1 line - -Removed file/folder ------------------------------------------------------------------------- -r3 | maxm | 2004-03-08 23:16:25 +0100 (ma, 08 mar 2004) | 1 line - -Adde midi ------------------------------------------------------------------------- -r1 | maxm | 2004-03-08 22:49:23 +0100 (ma, 08 mar 2004) | 1 line - -Initial Import ------------------------------------------------------------------------- diff --git a/src/mxmMidi/constants.py b/src/mxmMidi/constants.py deleted file mode 100644 index 81b91bc..0000000 --- a/src/mxmMidi/constants.py +++ /dev/null @@ -1,210 +0,0 @@ -# -*- coding: ISO-8859-1 -*- - -################################################### -## Definitions of the different midi events - - - -################################################### -## Midi channel events (The most usual events) -## also called "Channel Voice Messages" - -NOTE_OFF = 0x80 -# 1000cccc 0nnnnnnn 0vvvvvvv (channel, note, velocity) - -NOTE_ON = 0x90 -# 1001cccc 0nnnnnnn 0vvvvvvv (channel, note, velocity) - -AFTERTOUCH = 0xA0 -# 1010cccc 0nnnnnnn 0vvvvvvv (channel, note, velocity) - -CONTINUOUS_CONTROLLER = 0xB0 # see Channel Mode Messages!!! -# 1011cccc 0ccccccc 0vvvvvvv (channel, controller, value) - -PATCH_CHANGE = 0xC0 -# 1100cccc 0ppppppp (channel, program) - -CHANNEL_PRESSURE = 0xD0 -# 1101cccc 0ppppppp (channel, pressure) - -PITCH_BEND = 0xE0 -# 1110cccc 0vvvvvvv 0wwwwwww (channel, value-lo, value-hi) - - -################################################### -## Channel Mode Messages (Continuous Controller) -## They share a status byte. -## The controller makes the difference here - -# High resolution continuous controllers (MSB) - -BANK_SELECT = 0x00 -MODULATION_WHEEL = 0x01 -BREATH_CONTROLLER = 0x02 -FOOT_CONTROLLER = 0x04 -PORTAMENTO_TIME = 0x05 -DATA_ENTRY = 0x06 -CHANNEL_VOLUME = 0x07 -BALANCE = 0x08 -PAN = 0x0A -EXPRESSION_CONTROLLER = 0x0B -EFFECT_CONTROL_1 = 0x0C -EFFECT_CONTROL_2 = 0x0D -GEN_PURPOSE_CONTROLLER_1 = 0x10 -GEN_PURPOSE_CONTROLLER_2 = 0x11 -GEN_PURPOSE_CONTROLLER_3 = 0x12 -GEN_PURPOSE_CONTROLLER_4 = 0x13 - -# High resolution continuous controllers (LSB) - -BANK_SELECT = 0x20 -MODULATION_WHEEL = 0x21 -BREATH_CONTROLLER = 0x22 -FOOT_CONTROLLER = 0x24 -PORTAMENTO_TIME = 0x25 -DATA_ENTRY = 0x26 -CHANNEL_VOLUME = 0x27 -BALANCE = 0x28 -PAN = 0x2A -EXPRESSION_CONTROLLER = 0x2B -EFFECT_CONTROL_1 = 0x2C -EFFECT_CONTROL_2 = 0x2D -GENERAL_PURPOSE_CONTROLLER_1 = 0x30 -GENERAL_PURPOSE_CONTROLLER_2 = 0x31 -GENERAL_PURPOSE_CONTROLLER_3 = 0x32 -GENERAL_PURPOSE_CONTROLLER_4 = 0x33 - -# Switches - -SUSTAIN_ONOFF = 0x40 -PORTAMENTO_ONOFF = 0x41 -SOSTENUTO_ONOFF = 0x42 -SOFT_PEDAL_ONOFF = 0x43 -LEGATO_ONOFF = 0x44 -HOLD_2_ONOFF = 0x45 - -# Low resolution continuous controllers - -SOUND_CONTROLLER_1 = 0x46 # (TG: Sound Variation; FX: Exciter On/Off) -SOUND_CONTROLLER_2 = 0x47 # (TG: Harmonic Content; FX: Compressor On/Off) -SOUND_CONTROLLER_3 = 0x48 # (TG: Release Time; FX: Distortion On/Off) -SOUND_CONTROLLER_4 = 0x49 # (TG: Attack Time; FX: EQ On/Off) -SOUND_CONTROLLER_5 = 0x4A # (TG: Brightness; FX: Expander On/Off)75 SOUND_CONTROLLER_6 (TG: Undefined; FX: Reverb OnOff) -SOUND_CONTROLLER_7 = 0x4C # (TG: Undefined; FX: Delay OnOff) -SOUND_CONTROLLER_8 = 0x4D # (TG: Undefined; FX: Pitch Transpose OnOff) -SOUND_CONTROLLER_9 = 0x4E # (TG: Undefined; FX: Flange/Chorus OnOff) -SOUND_CONTROLLER_10 = 0x4F # (TG: Undefined; FX: Special Effects OnOff) -GENERAL_PURPOSE_CONTROLLER_5 = 0x50 -GENERAL_PURPOSE_CONTROLLER_6 = 0x51 -GENERAL_PURPOSE_CONTROLLER_7 = 0x52 -GENERAL_PURPOSE_CONTROLLER_8 = 0x53 -PORTAMENTO_CONTROL = 0x54 # (PTC) (0vvvvvvv is the source Note number) (Detail) -EFFECTS_1 = 0x5B # (Ext. Effects Depth) -EFFECTS_2 = 0x5C # (Tremelo Depth) -EFFECTS_3 = 0x5D # (Chorus Depth) -EFFECTS_4 = 0x5E # (Celeste Depth) -EFFECTS_5 = 0x5F # (Phaser Depth) -DATA_INCREMENT = 0x60 # (0vvvvvvv is n/a; use 0) -DATA_DECREMENT = 0x61 # (0vvvvvvv is n/a; use 0) -NON_REGISTERED_PARAMETER_NUMBER = 0x62 # (LSB) -NON_REGISTERED_PARAMETER_NUMBER = 0x63 # (MSB) -REGISTERED_PARAMETER_NUMBER = 0x64 # (LSB) -REGISTERED_PARAMETER_NUMBER = 0x65 # (MSB) - -# Channel Mode messages - (Detail) - -ALL_SOUND_OFF = 0x78 -RESET_ALL_CONTROLLERS = 0x79 -LOCAL_CONTROL_ONOFF = 0x7A -ALL_NOTES_OFF = 0x7B -OMNI_MODE_OFF = 0x7C # (also causes ANO) -OMNI_MODE_ON = 0x7D # (also causes ANO) -MONO_MODE_ON = 0x7E # (Poly Off; also causes ANO) -POLY_MODE_ON = 0x7F # (Mono Off; also causes ANO) - - - -################################################### -## System Common Messages, for all channels - -SYSTEM_EXCLUSIVE = 0xF0 -# 11110000 0iiiiiii 0ddddddd ... 11110111 - -MTC = 0xF1 # MIDI Time Code Quarter Frame -# 11110001 - -SONG_POSITION_POINTER = 0xF2 -# 11110010 0vvvvvvv 0wwwwwww (lo-position, hi-position) - -SONG_SELECT = 0xF3 -# 11110011 0sssssss (songnumber) - -#UNDEFINED = 0xF4 -## 11110100 - -#UNDEFINED = 0xF5 -## 11110101 - -TUNING_REQUEST = 0xF6 -# 11110110 - -END_OFF_EXCLUSIVE = 0xF7 # terminator -# 11110111 # End of system exclusive - - -################################################### -## Midifile meta-events - -SEQUENCE_NUMBER = 0x00 # 00 02 ss ss (seq-number) -TEXT = 0x01 # 01 len text... -COPYRIGHT = 0x02 # 02 len text... -SEQUENCE_NAME = 0x03 # 03 len text... -INSTRUMENT_NAME = 0x04 # 04 len text... -LYRIC = 0x05 # 05 len text... -MARKER = 0x06 # 06 len text... -CUEPOINT = 0x07 # 07 len text... -PROGRAM_NAME = 0x08 # 08 len text... -DEVICE_NAME = 0x09 # 09 len text... - -MIDI_CH_PREFIX = 0x20 # MIDI channel prefix assignment (unofficial) - -MIDI_PORT = 0x21 # 21 01 port, legacy stuff but still used -END_OF_TRACK = 0x2F # 2f 00 -TEMPO = 0x51 # 51 03 tt tt tt (tempo in us/quarternote) -SMTP_OFFSET = 0x54 # 54 05 hh mm ss ff xx -TIME_SIGNATURE = 0x58 # 58 04 nn dd cc bb -KEY_SIGNATURE = 0x59 # ??? len text... -SPECIFIC = 0x7F # Sequencer specific event - -FILE_HEADER = 'MThd' -TRACK_HEADER = 'MTrk' - -################################################### -## System Realtime messages -## I don't supose these are to be found in midi files?! - -TIMING_CLOCK = 0xF8 -# undefined = 0xF9 -SONG_START = 0xFA -SONG_CONTINUE = 0xFB -SONG_STOP = 0xFC -# undefined = 0xFD -ACTIVE_SENSING = 0xFE -SYSTEM_RESET = 0xFF - - -################################################### -## META EVENT, it is used only in midi files. -## In transmitted data it means system reset!!! - -META_EVENT = 0xFF -# 11111111 - - -################################################### -## Helper functions - -def is_status(byte): - return (byte & 0x80) == 0x80 # 1000 0000 - - diff --git a/src/mxmMidi/example_mimimal_type0.py b/src/mxmMidi/example_mimimal_type0.py deleted file mode 100644 index d8d1842..0000000 --- a/src/mxmMidi/example_mimimal_type0.py +++ /dev/null @@ -1,29 +0,0 @@ -from MidiOutFile import MidiOutFile - -""" -This is an example of the smallest possible type 0 midi file, where -all the midi events are in the same track. -""" - -out_file = 'midiout/minimal_type0.mid' -midi = MidiOutFile(out_file) - -# non optional midi framework -midi.header() -midi.start_of_track() - - -# musical events - -midi.update_time(0) -midi.note_on(channel=0, note=0x40) - -midi.update_time(192) -midi.note_off(channel=0, note=0x40) - - -# non optional midi framework -midi.update_time(0) -midi.end_of_track() - -midi.eof() diff --git a/src/mxmMidi/example_print_channel_0.py b/src/mxmMidi/example_print_channel_0.py deleted file mode 100644 index 2dbe3e4..0000000 --- a/src/mxmMidi/example_print_channel_0.py +++ /dev/null @@ -1,23 +0,0 @@ -from MidiOutStream import MidiOutStream -from MidiInFile import MidiInFile - -""" -This prints all note on events on midi channel 0 -""" - - -class Transposer(MidiOutStream): - - "Transposes all notes by 1 octave" - - def note_on(self, channel=0, note=0x40, velocity=0x40): - if channel == 0: - print channel, note, velocity, self.rel_time() - - -event_handler = Transposer() - -in_file = 'midiout/minimal_type0.mid' -midi_in = MidiInFile(event_handler, in_file) -midi_in.read() - diff --git a/src/mxmMidi/example_print_events.py b/src/mxmMidi/example_print_events.py deleted file mode 100644 index b1e27f9..0000000 --- a/src/mxmMidi/example_print_events.py +++ /dev/null @@ -1,28 +0,0 @@ -from MidiToText import MidiToText - -""" -This is an example that uses the MidiToText eventhandler. When an -event is triggered on it, it prints the event to the console. -""" - -midi = MidiToText() - -# non optional midi framework -midi.header() -midi.start_of_track() - - -# musical events - -midi.update_time(0) -midi.note_on(channel=0, note=0x40) - -midi.update_time(192) -midi.note_off(channel=0, note=0x40) - - -# non optional midi framework -midi.update_time(0) -midi.end_of_track() # not optional! - -midi.eof() diff --git a/src/mxmMidi/example_print_file.py b/src/mxmMidi/example_print_file.py deleted file mode 100644 index 4fcd531..0000000 --- a/src/mxmMidi/example_print_file.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -This is an example that uses the MidiToText eventhandler. When an -event is triggered on it, it prints the event to the console. - -It gets the events from the MidiInFile. - -So it prints all the events from the infile to the console. great for -debugging :-s -""" - - -# get data -test_file = 'test/midifiles/minimal-cubase-type0.mid' - -# do parsing -from MidiInFile import MidiInFile -from MidiToText import MidiToText # the event handler -midiIn = MidiInFile(MidiToText(), test_file) -midiIn.read() diff --git a/src/mxmMidi/example_transpose_octave.py b/src/mxmMidi/example_transpose_octave.py deleted file mode 100644 index 57dbbff..0000000 --- a/src/mxmMidi/example_transpose_octave.py +++ /dev/null @@ -1,40 +0,0 @@ -from MidiOutFile import MidiOutFile -from MidiInFile import MidiInFile - -""" -This is an example of the smallest possible type 0 midi file, where -all the midi events are in the same track. -""" - - -class Transposer(MidiOutFile): - - "Transposes all notes by 1 octave" - - def _transp(self, ch, note): - if ch != 9: # not the drums! - note += 12 - if note > 127: - note = 127 - return note - - - def note_on(self, channel=0, note=0x40, velocity=0x40): - note = self._transp(channel, note) - MidiOutFile.note_on(self, channel, note, velocity) - - - def note_off(self, channel=0, note=0x40, velocity=0x40): - note = self._transp(channel, note) - MidiOutFile.note_off(self, channel, note, velocity) - - -out_file = 'midiout/transposed.mid' -midi_out = Transposer(out_file) - -#in_file = 'midiout/minimal_type0.mid' -#in_file = 'test/midifiles/Lola.mid' -in_file = 'test/midifiles/tennessee_waltz.mid' -midi_in = MidiInFile(midi_out, in_file) -midi_in.read() - diff --git a/src/mxmMidi/experimental/EventDispatcherBase.py b/src/mxmMidi/experimental/EventDispatcherBase.py deleted file mode 100644 index 71bde62..0000000 --- a/src/mxmMidi/experimental/EventDispatcherBase.py +++ /dev/null @@ -1,76 +0,0 @@ -class EventDispatcherBase: - - - def __init__(self, outstream): - """ - The event dispatcher generates events on the outstream. This - is the base implementation. It is more like an interface for - how the EventDispatcher. It has the methods that are used by - the Midi Parser. - """ - # internal values, don't mess with 'em directly - self.outstream = outstream - - - def eof(self): - "End of file!" - self.outstream.eof() - - - def update_time(self, new_time=0, relative=1): - "Updates relative/absolute time." - self.outstream.update_time(new_time, relative) - - # 'official' midi events - - def header(self, format, nTracks, division): - "Triggers the header event" - self.outstream.header(format, nTracks, division) - - - def start_of_track(self, current_track): - "Triggers the start of track event" - - # I do this twice so that users can overwrite the - # start_of_track event handler without worrying whether the - # track number is updated correctly. - self.outstream.set_current_track(current_track) - self.outstream.start_of_track(current_track) - - # Event dispatchers for midi events - - def channel_messages(self, hi_nible, channel, data): - "Dispatches channel messages" - self.outstream.channel_message(hi_nible, channel, data) - - - def continuous_controllers(self, channel, controller, value): - "Dispatches channel messages" - self.outstream.continuous_controller(channel, controller, value) - - - def system_commons(self, common_type, common_data): - "Dispatches system common messages" - self.outstream.system_common(common_type, common_data) - - - def meta_event(self, meta_type, data): - "Dispatches meta events" - self.outstream.meta_event(meta_type, data) - - - def sysex_events(self, data): - "Dispatcher for sysex events" - self.outstream.sysex_event(data) - - - -if __name__ == '__main__': - - - from MidiToText import MidiToText - from constants import NOTE_ON - - outstream = MidiToText() - dispatcher = EventDispatcherBase(outstream) - dispatcher.channel_messages(NOTE_ON, 0x00, '\x40\x40') \ No newline at end of file diff --git a/src/mxmMidi/experimental/MidiOutPassThrough.py b/src/mxmMidi/experimental/MidiOutPassThrough.py deleted file mode 100644 index 25ceed4..0000000 --- a/src/mxmMidi/experimental/MidiOutPassThrough.py +++ /dev/null @@ -1,182 +0,0 @@ -from MidiOutStream import MidiOutStream - -class MidiOutPassThrough(MidiOutStream): - - - """ - - This class i mainly used for testing the event dispatcher. The - methods just returns the passed parameters as a tupple. - - """ - - - ##################### - ## Midi channel events - - - def note_on(self, channel, note, velocity, time=None): - return channel, note, velocity, time - - - def note_off(self, channel, note, velocity, time=None): - return channel, note, velocity, time - - - def aftertouch(self, channel, note, velocity, time=None): - return channel, note, velocity, time - - - def continuous_controller(self, channel, controller, value, time=None): - return channel, controller, value, time - - - def patch_change(self, channel, patch, time=None): - return channel, patch, time - - - def channel_pressure(self, channel, pressure, time=None): - return channel, pressure, time - - - ##################### - ## defined continuous controller events - -# def cc_ - - ##################### - ## Common events - - def system_exclusive(self, data, time=None): - return data, time - - - def song_position_pointer(self, hiPos, loPos, time=None): - return hiPos, loPos, time - - - def song_select(self, songNumber, time=None): - return songNumber, time - - - def tuning_request(self, time=None): - return time - - - - ######################### - # header does not really belong here. But anyhoo!!! - - def header(self, format, nTracks, division): - return format, nTracks, division - - - def eof(self): - return 'eof' - - - ##################### - ## meta events - - def start_of_track(self, n_track=0): - return n_track - - - def end_of_track(self, n_track=0, time=None): - return n_track, time - - - def sequence_number(self, hiVal, loVal, time=None): - return hiVal, loVal, time - - - def text(self, text, time=None): - return text, time - - - def copyright(self, text, time=None): - return text, time - - - def sequence_name(self, text, time=None): - return text, time - - - def instrument_name(self, text, time=None): - return text, time - - - def lyric(self, text, time=None): - return text, time - - - def marker(self, text, time=None): - return text, time - - - def cuepoint(self, text, time=None): - return text, time - - - def midi_port(self, value, time=None): - return value, time - - - def tempo(self, value, time=None): - return value, time - - def smtp_offset(self, hour, minute, second, frame, framePart, time=None): - return hour, minute, second, frame, framePart, time - - - def time_signature(self, nn, dd, cc, bb, time=None): - return nn, dd, cc, bb, time - - - def key_signature(self, sf, mi, time=None): - return sf, mi, time - - - def sequencer_specific(self, data, time=None): - return data, time - - - - - ##################### - ## realtime events - - def timing_clock(self, time=None): - return time - - - def song_start(self, time=None): - return time - - - def song_stop(self, time=None): - return time - - - def song_continue(self, time=None): - return time - - - def active_sensing(self, time=None): - return time - - - def system_reset(self, time=None): - return time - - - - - -if __name__ == '__main__': - - midiOut = MidiOutStream() - midiOut.note_on(0, 63, 127, 0) - midiOut.note_off(0, 63, 127, 384) - - \ No newline at end of file diff --git a/src/mxmMidi/experimental/MidiOutStreamBase.py b/src/mxmMidi/experimental/MidiOutStreamBase.py deleted file mode 100644 index 1abada0..0000000 --- a/src/mxmMidi/experimental/MidiOutStreamBase.py +++ /dev/null @@ -1,135 +0,0 @@ -class MidiOutStreamBase: - - - """ - - MidiOutStreamBase is Basically an eventhandler. It is the most central - class in the Midi library. You use it both for writing events to - an output stream, and as an event handler for an input stream. - - This makes it extremely easy to take input from one stream and - send it to another. Ie. if you want to read a Midi file, do some - processing, and send it to a midiport. - - All time values are in absolute values from the opening of a - stream. To calculate time values, please use the MidiTime and - MidiDeltaTime classes. - - """ - - def __init__(self): - - # the time is rather global, so it needs to be stored - # here. Otherwise there would be no really simple way to - # calculate it. The alternative would be to have each event - # handler do it. That sucks even worse! - self._absolute_time = 0 - self._relative_time = 0 - self._current_track = 0 - - # time handling event handlers. They should overwritten with care - - def update_time(self, new_time=0, relative=1): - """ - Updates the time, if relative is true, new_time is relative, - else it's absolute. - """ - if relative: - self._relative_time = new_time - self._absolute_time += new_time - else: - self._absolute_time = new_time - self._relative_time = new_time - self._absolute_time - - def rel_time(self): - "Returns the relative time" - return self._relative_time - - def abs_time(self): - "Returns the absolute time" - return self._absolute_time - - # track handling event handlers - - def set_current_track(self, new_track): - "Sets the current track number" - self._current_track = new_track - - def get_current_track(self): - "Returns the current track number" - return self._current_track - - - ##################### - ## Midi events - - - def channel_message(self, message_type, channel, data): - """The default event handler for channel messages""" - pass - - - ##################### - ## Common events - - def system_exclusive(self, data): - - """The default event handler for system_exclusive messages""" - pass - - - def system_common(self, common_type, common_data): - - """The default event handler for system common messages""" - pass - - - ######################### - # header does not really belong here. But anyhoo!!! - - def header(self, format, nTracks, division): - - """ - format: type of midi file in [1,2] - nTracks: number of tracks - division: timing division - """ - pass - - - def start_of_track(self, n_track=0): - - """ - n_track: number of track - """ - pass - - - def eof(self): - - """ - End of file. No more events to be processed. - """ - pass - - - ##################### - ## meta events - - - def meta_event(self, meta_type, data, time): - - """The default event handler for meta_events""" - pass - - - - -if __name__ == '__main__': - - midiOut = MidiOutStreamBase() - midiOut.update_time(0,0) - midiOut.note_on(0, 63, 127) - midiOut.note_off(0, 63, 127) - - \ No newline at end of file diff --git a/src/mxmMidi/experimental/readme.txt b/src/mxmMidi/experimental/readme.txt deleted file mode 100644 index 4234118..0000000 --- a/src/mxmMidi/experimental/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Stuff that I am just playing around with \ No newline at end of file diff --git a/src/mxmMidi/midiout/minimal_type0.mid b/src/mxmMidi/midiout/minimal_type0.mid deleted file mode 100644 index ffdfcda..0000000 Binary files a/src/mxmMidi/midiout/minimal_type0.mid and /dev/null differ diff --git a/src/mxmMidi/midiout/transposed.mid b/src/mxmMidi/midiout/transposed.mid deleted file mode 100644 index a964548..0000000 Binary files a/src/mxmMidi/midiout/transposed.mid and /dev/null differ diff --git a/src/mxmMidi/readme.txt b/src/mxmMidi/readme.txt deleted file mode 100644 index d3c7431..0000000 --- a/src/mxmMidi/readme.txt +++ /dev/null @@ -1,50 +0,0 @@ -This is the documentation for the midi package -============================================== - - -The modules follows the following naming convention: - - -MidiIn.py ---------------------- - -The MidiIn modules reads midi content for a specific type of stream. Ie. a file or a midi port. It then generates events and triggers them on a MidiOutStream. - - -MidiOut.py ----------------------- - -The MidiOut modules are event handlers, that reacts to events generated by a a Midi in module. - - -MidiInBase.py ---------------- - -The base class for input streams. - - -MidiOutBase.py ----------------- - -The base class for the output streams. - - - - - - -Internal modules -================ - - -DataTypeConverters.py ---------------------- - -A collection of functions that converts the special data types used in midi files to and from strings. - - -constants.py ------------- - -A collection of constants from the midi spec. - diff --git a/src/mxmMidi/test/midifiles/midiout.mid b/src/mxmMidi/test/midifiles/midiout.mid deleted file mode 100644 index eff8ffa..0000000 Binary files a/src/mxmMidi/test/midifiles/midiout.mid and /dev/null differ diff --git a/src/mxmMidi/test/midifiles/minimal-cubase-type0.mid b/src/mxmMidi/test/midifiles/minimal-cubase-type0.mid deleted file mode 100644 index dcea0cf..0000000 Binary files a/src/mxmMidi/test/midifiles/minimal-cubase-type0.mid and /dev/null differ diff --git a/src/mxmMidi/test/midifiles/minimal-cubase-type1.mid b/src/mxmMidi/test/midifiles/minimal-cubase-type1.mid deleted file mode 100644 index 94ad302..0000000 Binary files a/src/mxmMidi/test/midifiles/minimal-cubase-type1.mid and /dev/null differ diff --git a/src/mxmMidi/test/midifiles/minimal.mid b/src/mxmMidi/test/midifiles/minimal.mid deleted file mode 100644 index c4567b2..0000000 Binary files a/src/mxmMidi/test/midifiles/minimal.mid and /dev/null differ diff --git a/src/mxmMidi/test/midifiles/minimal.txt b/src/mxmMidi/test/midifiles/minimal.txt deleted file mode 100644 index dd9f61e..0000000 --- a/src/mxmMidi/test/midifiles/minimal.txt +++ /dev/null @@ -1,26 +0,0 @@ -MThd | Format=1 | # of Tracks=2 | Division=15360 - - - - -Track #0 ****************************************** - Time Event - - 1: 1: 0 |Time Sig | 4/4 | MIDI-clocks\click=24 | 32nds\quarter=8 - |Tempo | BPM=120 | micros\quarter=500000 - 101: 1: 0 |End of track| - - - - - -Track #1 ****************************************** - Time Event - - 1: 1: 0 |Track Name | len=7 | - 0x53 0x79 0x6E 0x74 0x68 0x20 0x31 - |Instrument | len=7 | - 0x53 0x79 0x6E 0x74 0x68 0x20 0x31 - |On Note | chan= 1 | pitch=C 1 | vol=127 - 2: 1: 0 |Off Note | chan= 1 | pitch=c 1 | vol=0 - 101: 1: 0 |End of track| diff --git a/src/mxmMidi/test/midifiles/minimal_analyse.txt b/src/mxmMidi/test/midifiles/minimal_analyse.txt deleted file mode 100644 index 498dfe9..0000000 --- a/src/mxmMidi/test/midifiles/minimal_analyse.txt +++ /dev/null @@ -1,54 +0,0 @@ -4D 54 68 64 MThd -00 00 00 06 len: 6 -00 01 Type: 1 -00 02 tracks: 2 -3C 00 tempo: 15360 - - - -4D 54 72 6B MTrk -00 00 00 16 len: 22 - -00 time - FF 58 04 Time Signature - 04 02 18 08 4/4 24 8 - -00 time - FF 51 03 TEMPO: - 07 A1 20 500.000 mySec - -82 F7 80 00 time ## oh bugger, it's buggy. - FF 2F 00 End Of Track - - - -4D 54 72 6B MTrk -00 00 00 2C len: 44 - -00 time - FF 03 Sequence/Track Name - 07 len: 7 - 53 79 6E 74 - 68 20 31 'Synth 1' - -00 time - FF 04 Instrument - 07 len: 7 - 53 79 6E 74 - 68 20 31 'Synth 1' - -00 time - FF 21 01 Midi port - 04 Port #5 - -00 time - 90 24 7F Note ON - 83 E0 00 Note OFF - -00 time - 80 24 00 Note OFF - -00 82 F3 A0 - -00 - FF 2F 00 End Of Track \ No newline at end of file diff --git a/src/mxmMidi/test/midifiles/readme.txt b/src/mxmMidi/test/midifiles/readme.txt deleted file mode 100644 index f3f59cd..0000000 --- a/src/mxmMidi/test/midifiles/readme.txt +++ /dev/null @@ -1,7 +0,0 @@ -These files are used for testing the midi package -================================================= - -minimal.mid ------------ - -A minimal working midifile. Plays a one bar "middle C" at 120 bpm. The absolute simplest file I could get to play in midi devices. \ No newline at end of file diff --git a/src/mxmMidi/test/readme.txt b/src/mxmMidi/test/readme.txt deleted file mode 100644 index c40adf3..0000000 --- a/src/mxmMidi/test/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Embarrasingly empty. - -Why don't you write some tests? \ No newline at end of file diff --git a/src/mxmMidi/version.txt b/src/mxmMidi/version.txt deleted file mode 100644 index 446ba66..0000000 --- a/src/mxmMidi/version.txt +++ /dev/null @@ -1 +0,0 @@ -0.1.4 \ No newline at end of file diff --git a/src/pgu/__init__.py b/src/pgu/__init__.py deleted file mode 100644 index 5cc6d1c..0000000 --- a/src/pgu/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Phil's pyGame Utilities - - -""" -__version__ = '0.12.3' - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/algo.py b/src/pgu/algo.py deleted file mode 100644 index 993eab0..0000000 --- a/src/pgu/algo.py +++ /dev/null @@ -1,143 +0,0 @@ -"""Some handy algorithms for use in games, etc. - -

please note that this file is alpha, and is subject to modification in -future versions of pgu!

-""" - -# The manhattan distance metric -def manhattan_dist(a,b): - return abs(a[0]-b[0]) + abs(a[1]-b[1]) - -class node: - def __init__(self, prev, pos, dest, dist): - self.prev,self.pos,self.dest = prev,pos,dest - if self.prev == None: self.g = 0 - else: self.g = self.prev.g + 1 - self.h = dist(pos,dest) - self.f = self.g+self.h - - -def astar(start,end,layer,dist=manhattan_dist): - """uses the a* algorithm to find a path - -
astar(start,end,layer,dist): return [list of positions]
- -
-
start
start position -
end
end position -
layer
a grid where zero cells are open and non-zero cells are walls -
dist
a distance function dist(a,b) - manhattan distance is used by default -
- -

returns a list of positions from start to end

- """ - - w,h = len(layer[0]),len(layer) - if start[0] < 0 or start[1] < 0 or start[0] >= w or start[1] >= h: - return [] #start outside of layer - if end[0] < 0 or end[1] < 0 or end[0] >= w or end[1] >= h: - return [] #end outside of layer - - if layer[start[1]][start[0]]: - return [] #start is blocked - if layer[end[1]][end[0]]: - return [] #end is blocked - - opens = [] - open = {} - closed = {} - cur = node(None, start, end, dist) - open[cur.pos] = cur - opens.append(cur) - while len(open): - cur = opens.pop(0) - if cur.pos not in open: continue - del open[cur.pos] - closed[cur.pos] = cur - if cur.pos == end: break - for dx,dy in [(0,-1),(1,0),(0,1),(-1,0)]:#(-1,-1),(1,-1),(-1,1),(1,1)]: - pos = cur.pos[0]+dx,cur.pos[1]+dy - # Check if the point lies in the grid - if (pos[0] < 0 or pos[1] < 0 or - pos[0] >= w or pos[1] >= h or - layer[pos[0]][pos[1]]): - continue - #check for blocks of diagonals - if layer[cur.pos[1]+dy][cur.pos[0]]: continue - if layer[cur.pos[1]][cur.pos[0]+dx]: continue - new = node(cur, pos, end, dist) - if pos in open and new.f >= open[pos].f: continue - if pos in closed and new.f >= closed[pos].f: continue - if pos in open: del open[pos] - if pos in closed: del closed[pos] - open[pos] = new - lo = 0 - hi = len(opens) - while lo < hi: - mid = (lo+hi)/2 - if new.f < opens[mid].f: hi = mid - else: lo = mid + 1 - opens.insert(lo,new) - - if cur.pos != end: - return [] - - path = [] - while cur.prev != None: - path.append(cur.pos) - cur = cur.prev - path.reverse() - return path - - -def getline(a,b): - """returns a path of points from a to b - -
getline(a,b): return [list of points]
- -
-
a
starting point -
b
ending point -
- -

returns a list of points from a to b

- """ - - path = [] - - x1,y1 = a - x2,y2 = b - dx,dy = abs(x2-x1),abs(y2-y1) - - if x2 >= x1: xi1,xi2 = 1,1 - else: xi1,xi2 = -1,-1 - - if y2 >= y1: yi1,yi2 = 1,1 - else: yi1,yi2 = -1,-1 - - if dx >= dy: - xi1,yi2 = 0,0 - d = dx - n = dx/2 - a = dy - p = dx - else: - xi2,yi1 = 0,0 - d = dy - n = dy/2 - a = dx - p = dy - - x,y = x1,y1 - c = 0 - while c <= p: - path.append((x,y)) - n += a - if n > d: - n -= d - x += xi1 - y += yi1 - x += xi2 - y += yi2 - c += 1 - return path diff --git a/src/pgu/ani.py b/src/pgu/ani.py deleted file mode 100644 index c33d380..0000000 --- a/src/pgu/ani.py +++ /dev/null @@ -1,90 +0,0 @@ -"""animation loading and manipulating functions. - -

please note that this file is alpha, and is subject to modification in -future versions of pgu!

-""" - -print 'pgu.ani','This module is alpha, and is subject to change.' - -import math -import pygame - -def _ani_load(tv,name,parts,frames,shape): - l = len(frames) - #print name,parts,l - n = parts.pop() - if len(parts): - s = l/n - for i in xrange(0,n): - _ani_load(tv,name + ".%d"%i,parts[:],frames[s*i:s*(i+1)],shape) - return - - for i in xrange(0,n): - tv.images[name+".%d"%i] = frames[i],shape - -def ani_load(tv,name,img,size,shape,parts): - """load an animation from an image - -
ani_load(tv,name,image,size,shape,parts)
- -
-
tv
vid to load into -
name
prefix name to give the images -
image
image to load anis from -
size
w,h size of image -
shape
shape of image (usually a subset of 0,0,w,h) used for collision detection -
parts
list of parts to divide the animation into -
for example parts = [4,5] would yield 4 animations 5 frames long, 20 total -
for example parts = [a,b,c] would yield ... images['name.a.b.c'] ..., a*b*c total -
- - """ - parts = parts[:] - parts.reverse() - w,h = size - frames = [] - for y in xrange(0,img.get_height(),h): - for x in xrange(0,img.get_width(),w): - frames.append(img.subsurface(x,y,w,h)) - _ani_load(tv,name,parts,frames,shape) - - -def image_rotate(tv,name,img,shape,angles,diff=0): - """rotate an image and put it into tv.images - -
image_rotate(tv,name,image,shape,angles,diff=0)
- -
-
tv
vid to load into -
name
prefix name to give the images -
image
image to load anis from -
shape
shape fimage (usually a subset of 0,0,w,h) used for collision detection -
angles
a list of angles to render in degrees -
diff
a number to add to the angles, to correct for source image not actually being at 0 degrees -
- """ - w1,h1 = img.get_width(),img.get_height() - shape = pygame.Rect(shape) - ps = shape.topleft,shape.topright,shape.bottomleft,shape.bottomright - for a in angles: - img2 = pygame.transform.rotate(img,a+diff) - w2,h2 = img2.get_width(),img2.get_height() - minx,miny,maxx,maxy = 1024,1024,0,0 - for x,y in ps: - x,y = x-w1/2,y-h1/2 - a2 = math.radians(a+diff) - #NOTE: the + and - are switched from the normal formula because of - #the weird way that pygame does the angle... - x2 = x*math.cos(a2) + y*math.sin(a2) - y2 = y*math.cos(a2) - x*math.sin(a2) - x2,y2 = x2+w2/2,y2+h2/2 - minx = min(minx,x2) - miny = min(miny,y2) - maxx = max(maxx,x2) - maxy = max(maxy,y2) - r = pygame.Rect(minx,miny,maxx-minx,maxy-miny) - #print r - #((ww-w)/2,(hh-h)/2,w,h) - tv.images["%s.%d"%(name,a)] = img2,r - - diff --git a/src/pgu/engine.py b/src/pgu/engine.py deleted file mode 100644 index 76be583..0000000 --- a/src/pgu/engine.py +++ /dev/null @@ -1,154 +0,0 @@ -"""a state engine. -""" -import pygame -from pygame.locals import * - -class State: - """Template Class -- for a state. - -
State(game,value...)
- -
-
game
The state engine. -
value
I usually pass in a custom value to a state -
- -

For all of the template methods, they should return None unless they return - a new State to switch the engine to.

- """ - def __init__(self,game,value=None): - self.game,self.value = game,value - def init(self): - """Template Method - Initialize the state, called once the first time a state is selected. - -
State.init()
- """ - return - def paint(self,screen): - """Template Method - Paint the screen. Called once after the state is selected. - -

State is responsible for calling pygame.display.flip() or whatever.

- -
State.paint(screen)
- """ - return - - def repaint(self): - """Template Method - Request a repaint of this state. - -
State.repaint()
- """ - self._paint = 1 - def update(self,screen): - """Template Method - Update the screen. - -

State is responsible for calling pygame.display.update(updates) or whatever.

- -
State.update(screen)
- """ - return - def loop(self): - """Template Method - Run a logic loop, called once per frame. - -
State.loop()
- """ - return - def event(self,e): - """Template Method - Recieve an event. - -
State.event(e)
- """ - return - -class Quit(State): - """A state to quit the state engine. - -
Quit(game,value)
- """ - - def init(self): - self.game.quit = 1 - -class Game: - """Template Class - The state engine. - """ - def fnc(self,f,v=None): - s = self.state - if not hasattr(s,f): return 0 - f = getattr(s,f) - if v != None: r = f(v) - else: r = f() - if r != None: - self.state = r - self.state._paint = 1 - return 1 - return 0 - - def run(self,state,screen=None): - """Run the state engine, this is a infinite loop (until a quit occurs). - -
Game.run(state,screen=None)
- -
-
game
a state engine -
screen
the screen -
- """ - self.quit = 0 - self.state = state - if screen != None: self.screen = screen - - self.init() - - while not self.quit: - self.loop() - - def loop(self): - s = self.state - if not hasattr(s,'_init') or s._init: - s._init = 0 - if self.fnc('init'): return - else: - if self.fnc('loop'): return - if not hasattr(s,'_paint') or s._paint: - s._paint = 0 - if self.fnc('paint',self.screen): return - else: - if self.fnc('update',self.screen): return - - for e in pygame.event.get(): - #NOTE: this might break API? - #if self.event(e): return - if not self.event(e): - if self.fnc('event',e): return - - self.tick() - return - - def init(self): - """Template Method - called at the beginning of State.run() to initialize things. - -
Game.init()
- """ - return - - def tick(self): - """Template Method - called once per frame, usually for timer purposes. - -
Game.tick()
- """ - pygame.time.wait(10) - - def event(self,e): - """Template Method - called with each event, so the engine can capture special events. - -
Game.event(e): return captured
- -

return a True value if the event is captured and does not need to be passed onto the current - state

- """ - if e.type is QUIT: - self.state = Quit(self) - return 1 - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/fonts.py b/src/pgu/fonts.py deleted file mode 100644 index ab6f73d..0000000 --- a/src/pgu/fonts.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Some handy font-like objects. - -

please note that this file is alpha, and is subject to modification in -future versions of pgu!

-""" - -print 'pgu.fonts','This module is alpha, and is subject to change.' - -import pygame -from pygame.locals import * - -class TileFont: - """Creates an instance of the TileFont class. Interface compatible with pygame.Font - -

TileFonts are fonts that are stored in a tiled image. Where the image opaque, it assumed that the font is visible. Font color is changed automatically, so it does not work with - fonts with stylized coloring.

- -
TileFont(fname,size,hints,scale=None,sensitive=False)
- -
-
size
the dimensions of the characters -
hints
a string of hints "abcdefg..." -
scale
size to scale font to -
sensitive
case sensitivity -
- """ - - def __init__(self,fname,size,hints,scale=None,sensitive=False): - - self.image = pygame.image.load(fname) - - w,h = self.image.get_width(),self.image.get_height() - tw,th = size - if not scale: scale = size - self._size = size - self.scale = scale - - self.chars = {} - x,y = 0,0 - self.sensitive = sensitive - if not self.sensitive: hints = hints.lower() - for c in hints: - if c not in ('\r','\n','\t'): - img = self.image.subsurface(x,y,tw,th) - self.chars[c] = img - x += tw - if x >= w: x,y = 0,y+th - - self.colors = {} - - def size(self,text): - tw,th = self.scale - return len(text)*tw,th - - def render(self,text,antialias=0,color=(255,255,255),background=None): - size = self.size(text) - scale = self.scale - tw,th = self._size - if background == None: - s = pygame.Surface(size).convert_alpha() - s.fill((0,0,0,0)) - else: - s = pygame.Surface(size).convert() - s.fill(background) - - if not self.sensitive: text = text.lower() - - if color not in self.colors: self.colors[color] = {} - colored = self.colors[color] - - x,y = 0,0 - for c in text: - if c in self.chars: - if c not in colored: - img = self.chars[c].convert_alpha() - for yy in xrange(0,th): - for xx in xrange(0,tw): - r,g,b,a = img.get_at((xx,yy)) - if a > 128: - img.set_at((xx,yy),color) - colored[c] = img - img = colored[c] - if scale != (tw,th): img = pygame.transform.scale(img,scale) - s.blit(img,(x,y)) - x += scale[0] - return s - - -class BorderFont: - """a decorator for normal fonts, adds a border. Interface compatible with pygame.Font. - -
BorderFont(font,size=1,color=(0,0,0))
- -
-
size
width of border; defaults 0 -
color
color of border; default (0,0,0) -
- """ - def __init__(self,font,size=1,color=(0,0,0)): - - self.font = font - self._size = size - self.color = color - - def size(self,text): - w,h = self.font.size(text) - s = self._size - return w+s*2,h+s*2 - - def render(self,text,antialias=0,color=(255,255,255),background=None): - size = self.size(text) - - if background == None: - s = pygame.Surface(size).convert_alpha() - s.fill((0,0,0,0)) - else: - s = pygame.Surface(size).convert() - s.fill(background) - - bg = self.font.render(text,antialias,self.color) - fg = self.font.render(text,antialias,color) - - si = self._size - dirs = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] - for dx,dy in dirs: s.blit(bg,(si+dx*si,si+dy*si)) - s.blit(fg,(si,si)) - - return s - - diff --git a/src/pgu/gui/__init__.py b/src/pgu/gui/__init__.py deleted file mode 100644 index 256fb63..0000000 --- a/src/pgu/gui/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -import pygame -from pygame.locals import * - -from theme import Theme -from style import Style -from widget import Widget -from surface import subsurface, ProxySurface -from const import * - -from container import Container -from app import App, Desktop -from table import Table -from document import Document -#html -from area import SlideBox, ScrollArea, List - -from form import Form -from group import Group - -from basic import Spacer, Color, Label, Image, parse_color -from button import Icon, Button, Switch, Checkbox, Radio, Tool, Link -from input import Input, Password -from keysym import Keysym -from slider import VSlider, HSlider, VScrollBar, HScrollBar -from select import Select -from misc import ProgressBar - -from menus import Menus -from dialog import Dialog, FileDialog -from textarea import TextArea - -from deprecated import Toolbox, action_open, action_setvalue, action_quit, action_exec diff --git a/src/pgu/gui/app.py b/src/pgu/gui/app.py deleted file mode 100644 index 857af98..0000000 --- a/src/pgu/gui/app.py +++ /dev/null @@ -1,279 +0,0 @@ -""" -""" -import pygame -from pygame.locals import * - -import pguglobals -import container -from const import * - -class App(container.Container): - """The top-level widget for an application. - -
App(theme=None)
- -
-
theme
an instance of a Theme, optional as it will use the default Theme class. -
- - Basic Example - - app = gui.App() - app.run(widget=widget,screen=screen) - - - Integrated Example - - app = gui.App() - gui.init(widget=widget) - while 1: - for e in pygame.event.get(): - app.event(e) - app.update(screen) - - - - - """ - def __init__(self,theme=None,**params): - self.set_global_app() - - if theme == None: - from theme import Theme - theme = Theme() - self.theme = theme - - params['decorate'] = 'app' - container.Container.__init__(self,**params) - self._quit = False - self.widget = None - self._chsize = False - self._repaint = False - - self.screen = None - self.container = None - self.events = [] - - def set_global_app(self): - # Keep a global reference to this application instance so that PGU - # components can easily find it. - pguglobals.app = self - # For backwards compatibility we keep a reference in the class - # itself too. - App.app = self - - def resize(self): - - screen = self.screen - w = self.widget - wsize = 0 - - #5 cases - - #input screen is already set use its size - if screen: - self.screen = screen - width,height = screen.get_width(),screen.get_height() - - #display.screen - elif pygame.display.get_surface(): - screen = pygame.display.get_surface() - self.screen = screen - width,height = screen.get_width(),screen.get_height() - - #app has width,height - elif self.style.width != 0 and self.style.height != 0: - screen = pygame.display.set_mode((self.style.width,self.style.height),SWSURFACE) - self.screen = screen - width,height = screen.get_width(),screen.get_height() - - #widget has width,height, or its own size.. - else: - wsize = 1 - width,height = w.rect.w,w.rect.h = w.resize() - #w._resize() - screen = pygame.display.set_mode((width,height),SWSURFACE) - self.screen = screen - - #use screen to set up size of this widget - self.style.width,self.style.height = width,height - self.rect.w,self.rect.h = width,height - self.rect.x,self.rect.y = 0,0 - - w.rect.x,w.rect.y = 0,0 - w.rect.w,w.rect.h = w.resize(width,height) - - for w in self.windows: - w.rect.w,w.rect.h = w.resize() - - self._chsize = False - - - def init(self,widget=None,screen=None): #TODO widget= could conflict with module widget - """Initialize the application. - -
App.init(widget=None,screen=None)
- -
-
widget
main widget -
screen
pygame.Surface to render to -
- """ - - self.set_global_app() - - if widget: self.widget = widget - if screen: self.screen = screen - - self.resize() - - w = self.widget - - self.widgets = [] - self.widgets.append(w) - w.container = self - self.focus(w) - - pygame.key.set_repeat(500,30) - - self._repaint = True - self._quit = False - - self.send(INIT) - - def event(self,e): - """Pass an event to the main widget. - -
App.event(e)
- -
-
e
event -
- """ - self.set_global_app() - - #NOTE: might want to deal with ACTIVEEVENT in the future. - self.send(e.type,e) - container.Container.event(self,e) - if e.type == MOUSEBUTTONUP: - if e.button not in (4,5): #ignore mouse wheel - sub = pygame.event.Event(CLICK,{ - 'button':e.button, - 'pos':e.pos}) - self.send(sub.type,sub) - container.Container.event(self,sub) - - - def loop(self): - self.set_global_app() - - s = self.screen - for e in pygame.event.get(): - if not (e.type == QUIT and self.mywindow): - self.event(e) - us = self.update(s) - pygame.display.update(us) - - - def paint(self,screen): - self.screen = screen - if self._chsize: - self.resize() - self._chsize = False - if hasattr(self,'background'): - self.background.paint(screen) - container.Container.paint(self,screen) - - def update(self,screen): - """Update the screen. - -
-
screen
pygame surface -
- """ - self.screen = screen - if self._chsize: - self.resize() - self._chsize = False - if self._repaint: - self.paint(screen) - self._repaint = False - return [pygame.Rect(0,0,screen.get_width(),screen.get_height())] - else: - us = container.Container.update(self,screen) - return us - - def run(self,widget=None,screen=None): - """Run an application. - -

Automatically calls App.init and then forever loops App.event and App.update

- -
-
widget
main widget -
screen
pygame.Surface to render to -
- """ - self.init(widget,screen) - while not self._quit: - self.loop() - pygame.time.wait(10) - - def reupdate(self,w=None): pass - def repaint(self,w=None): self._repaint = True - def repaintall(self): self._repaint = True - def chsize(self): - self._chsize = True - self._repaint = True - - def quit(self,value=None): self._quit = True - - def open(self, w, pos=None): - w.container = self - - if (w.rect.w == 0 or w.rect.h == 0): - w.rect.size = w.resize() - - if (not pos): - # Auto-center the window - w.rect.center = self.rect.center - #w.rect.topleft = ((self.rect.w - w.rect.w)/2, - # (self.rect.h - w.rect.h)/2) - else: - # Show the window in a particular location - w.rect.topleft = pos - - self.windows.append(w) - self.mywindow = w - self.focus(w) - self.repaint(w) - w.send(OPEN) - - def close(self, w): - if self.myfocus is w: self.blur(w) - - if w not in self.windows: return #no need to remove it twice! happens. - - self.windows.remove(w) - - self.mywindow = None - if self.windows: - self.mywindow = self.windows[-1] - self.focus(self.mywindow) - - if not self.mywindow: - self.myfocus = self.widget #HACK: should be done fancier, i think.. - if not self.myhover: - self.enter(self.widget) - - self.repaintall() - w.send(CLOSE) - - -class Desktop(App): - """Create an App using the desktop theme class. - -
Desktop()
- """ - def __init__(self,**params): - params.setdefault('cls','desktop') - App.__init__(self,**params) diff --git a/src/pgu/gui/area.py b/src/pgu/gui/area.py deleted file mode 100644 index 64074d6..0000000 --- a/src/pgu/gui/area.py +++ /dev/null @@ -1,454 +0,0 @@ -""" -""" -import os - -import pguglobals -from const import * -import surface -import container, table -import group -import basic, button, slider -from pygame.font import Font - -class SlideBox(container.Container): - """A scrollable area with no scrollbars. - -
SlideBox(widget,width,height)
- -
-
widget
widget to be able to scroll around -
width, height
size of scrollable area -
- - Example - - c = SlideBox(w,100,100) - c.offset = (10,10) - c.repaint() - - - """ - - def __init__(self, widget, width, height, **params): - params.setdefault('width', width) - params.setdefault('height', height) - container.Container.__init__(self, **params) - self.offset = [0, 0] - self.widget = widget - - def __setattr__(self,k,v): - if k == 'widget': - if hasattr(self,'widget'): - self.remove(self.widget) - self.add(v,0,0) - self.__dict__[k] = v - - - def paint(self, s): - #if not hasattr(self,'surface'): - self.surface = pygame.Surface((self.max_rect.w,self.max_rect.h),0,s) - #self.surface.fill((0,0,0,0)) - pguglobals.app.theme.render(self.surface,self.style.background,pygame.Rect(0,0,self.max_rect.w,self.max_rect.h)) - self.bkgr = pygame.Surface((s.get_width(),s.get_height()),0,s) - self.bkgr.blit(s,(0,0)) - container.Container.paint(self,self.surface) - s.blit(self.surface,(-self.offset[0],-self.offset[1])) - self._offset = self.offset[:] - return - - def paint_for_when_pygame_supports_other_tricks(self,s): - #this would be ideal if pygame had support for it! - #and if pgu also had a paint(self,s,rect) method to paint small parts - sr = (self.offset[0],self.offset[1],self.max_rect.w,self.max_rect.h) - cr = (-self.offset[0],-self.offset[1],s.get_width(),s.get_height()) - s2 = s.subsurface(sr) - s2.set_clip(cr) - container.Container.paint(self,s2) - - def proxy_paint(self, s): - container.Container.paint(self, surface.ProxySurface(parent=None, - rect=self.max_rect, - real_surface=s, - offset=self.offset)) - def update(self, s): - rects = container.Container.update(self,self.surface) - - rets = [] - s_rect = pygame.Rect(0,0,s.get_width(),s.get_height()) - - if self.offset == self._offset: - for r in rects: - r2 = r.move((-self.offset[0],-self.offset[1])) - if r2.colliderect(s_rect): - s.blit(self.surface.subsurface(r),r2) - rets.append(r2) - else: - s.blit(self.bkgr,(0,0)) - sub = pygame.Rect(self.offset[0],self.offset[1],min(s.get_width(),self.max_rect.w-self.offset[0]),min(s.get_height(),self.max_rect.h-self.offset[1])) -# print sub -# print self.surface.get_width(),self.surface.get_height() -# print s.get_width(),s.get_height() -# print self.offset -# print self.style.width,self.style.height - s.blit(self.surface.subsurface(sub),(0,0)) - rets.append(s_rect) - self._offset = self.offset[:] - return rets - - def proxy_update(self, s): - rects = container.Container.update(self, surface.ProxySurface(parent=None, - rect=self.max_rect, - real_surface=s, - offset=self.offset)) - result = [] - for r in rects: result.append(pygame.Rect(r).move(self.offset)) - return result - - def resize(self, width=None, height=None): - container.Container.resize(self) - self.max_rect = pygame.Rect(self.widget.rect) - #self.max_rect.w = max(self.max_rect.w,self.style.width) - #self.max_rect.h = max(self.max_rect.h,self.style.height) - return self.style.width,self.style.height - #self.rect = pygame.Rect(self.rect[0], self.rect[1], self.style.width, self.style.height) - - def event(self, e): - if e.type in [MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION]: - pos = (e.pos[0] + self.offset[0], e.pos[1] + self.offset[1]) - if self.max_rect.collidepoint(pos): - e_params = {'pos': pos } - if e.type == MOUSEMOTION: - e_params['buttons'] = e.buttons - e_params['rel'] = e.rel - else: - e_params['button'] = e.button - e = pygame.event.Event(e.type, e_params) - container.Container.event(self, e) - -#class SlideBox(Area): -# def __init__(self,*args,**params): -# print 'gui.SlideBox','Scheduled to be renamed to Area.' -# Area.__init__(self,*args,**params) - -class ScrollArea(table.Table): - """A scrollable area with scrollbars. - -
ScrollArea(widget,width,height,hscrollbar=True)
- -
-
widget
widget to be able to scroll around -
width, height
size of scrollable area. Set either to 0 to default to size of widget. -
hscrollbar
set to False if you do not wish to have a horizontal scrollbar -
vscrollbar
set to False if you do not wish to have a vertical scrollbar -
step
set to how far clicks on the icons will step -
- """ - def __init__(self, widget, width=0, height=0, hscrollbar=True, vscrollbar=True,step=24, **params): - w= widget - params.setdefault('cls', 'scrollarea') - table.Table.__init__(self, width=width,height=height,**params) - - self.sbox = SlideBox(w, width=width, height=height, cls=self.cls+".content") - self.widget = w - self.vscrollbar = vscrollbar - self.hscrollbar = hscrollbar - - self.step = step - - def __setattr__(self,k,v): - if k == 'widget': - self.sbox.widget = v - self.__dict__[k] = v - - def resize(self,width=None,height=None): - widget = self.widget - box = self.sbox - - #self.clear() - table.Table.clear(self) - #print 'resize',self,self._rows - - self.tr() - self.td(box) - - widget.rect.w, widget.rect.h = widget.resize() - my_width,my_height = self.style.width,self.style.height - if not my_width: - my_width = widget.rect.w - self.hscrollbar = False - if not my_height: - my_height = widget.rect.h - self.vscrollbar = False - - box.style.width,box.style.height = my_width,my_height #self.style.width,self.style.height - - box.rect.w,box.rect.h = box.resize() - - #print widget.rect - #print box.rect - #r = table.Table.resize(self,width,height) - #print r - #return r - - #print box.offset - -# #this old code automatically adds in a scrollbar if needed -# #but it doesn't always work -# self.vscrollbar = None -# if widget.rect.h > box.rect.h: -# self.vscrollbar = slider.VScrollBar(box.offset[1],0, 65535, 0,step=self.step) -# self.td(self.vscrollbar) -# self.vscrollbar.connect(CHANGE, self._vscrollbar_changed, None) -# -# vs = self.vscrollbar -# vs.rect.w,vs.rect.h = vs.resize() -# box.style.width = self.style.width - vs.rect.w -# -# -# self.hscrollbar = None -# if widget.rect.w > box.rect.w: -# self.hscrollbar = slider.HScrollBar(box.offset[0], 0,65535, 0,step=self.step) -# self.hscrollbar.connect(CHANGE, self._hscrollbar_changed, None) -# self.tr() -# self.td(self.hscrollbar) -# -# hs = self.hscrollbar -# hs.rect.w,hs.rect.h = hs.resize() -# box.style.height = self.style.height - hs.rect.h - - xt,xr,xb,xl = pguglobals.app.theme.getspacing(box) - - - if self.vscrollbar: - self.vscrollbar = slider.VScrollBar(box.offset[1],0, 65535, 0,step=self.step) - self.td(self.vscrollbar) - self.vscrollbar.connect(CHANGE, self._vscrollbar_changed, None) - - vs = self.vscrollbar - vs.rect.w,vs.rect.h = vs.resize() - if self.style.width: - box.style.width = self.style.width - (vs.rect.w + xl+xr) - - if self.hscrollbar: - self.hscrollbar = slider.HScrollBar(box.offset[0], 0,65535, 0,step=self.step) - self.hscrollbar.connect(CHANGE, self._hscrollbar_changed, None) - self.tr() - self.td(self.hscrollbar) - - hs = self.hscrollbar - hs.rect.w,hs.rect.h = hs.resize() - if self.style.height: - box.style.height = self.style.height - (hs.rect.h + xt + xb) - - if self.hscrollbar: - hs = self.hscrollbar - hs.min = 0 - hs.max = widget.rect.w - box.style.width - hs.style.width = box.style.width - hs.size = hs.style.width * box.style.width / max(1,widget.rect.w) - else: - box.offset[0] = 0 - - if self.vscrollbar: - vs = self.vscrollbar - vs.min = 0 - vs.max = widget.rect.h - box.style.height - vs.style.height = box.style.height - vs.size = vs.style.height * box.style.height / max(1,widget.rect.h) - else: - box.offset[1] = 0 - - #print self.style.width,box.style.width, hs.style.width - - r = table.Table.resize(self,width,height) - return r - - def x_resize(self, width=None, height=None): - w,h = table.Table.resize(self, width, height) - if self.hscrollbar: - if self.widget.rect.w <= self.sbox.rect.w: - self.hscrollbar.size = self.hscrollbar.style.width - else: - self.hscrollbar.size = max(20,self.hscrollbar.style.width * self.sbox.rect.w / self.widget.rect.w) - self._hscrollbar_changed(None) - if self.widget.rect.h <= self.sbox.rect.h: - self.vscrollbar.size = self.vscrollbar.style.height - else: - self.vscrollbar.size = max(20,self.vscrollbar.style.height * self.sbox.rect.h / self.widget.rect.h) - self._vscrollbar_changed(None) - return w,h - - def _vscrollbar_changed(self, xxx): - #y = (self.widget.rect.h - self.sbox.rect.h) * self.vscrollbar.value / 1000 - #if y >= 0: self.sbox.offset[1] = -y - self.sbox.offset[1] = self.vscrollbar.value - self.sbox.reupdate() - - def _hscrollbar_changed(self, xxx): - #x = (self.widget.rect.w - self.sbox.rect.w) * self.hscrollbar.value / 1000 - #if x >= 0: self.sbox.offset[0] = -x - self.sbox.offset[0] = self.hscrollbar.value - self.sbox.reupdate() - - - def set_vertical_scroll(self, percents): - #if not self.vscrollbar: return - if not hasattr(self.vscrollbar,'value'): return - self.vscrollbar.value = percents #min(max(percents*10, 0), 1000) - self._vscrollbar_changed(None) - - def set_horizontal_scroll(self, percents): - #if not self.hscrollbar: return - if not hasattr(self.hscrollbar,'value'): return - self.hscrollbar.value = percents #min(max(percents*10, 0), 1000) - self._hscrollbar_changed(None) - - def event(self, e): - #checking for event recipient - if (table.Table.event(self, e)): - return True - - #mouse wheel scrolling - if self.vscrollbar: - if not hasattr(self.vscrollbar,'value'): - return False - - if e.type == pygame.locals.MOUSEBUTTONDOWN: - if e.button == 4: #wheel up - self.vscrollbar._click(-1) - return True - elif e.button == 5: #wheel down - self.vscrollbar._click(1) - return True - return False - - - - -class _List_Item(button._button): - def __init__(self,label=None,image=None,value=None,**params): #TODO label= could conflict with the module label - #param image: an imagez.Image object (optional) - #param text: a string object - params.setdefault('cls','list.item') - button._button.__init__(self,**params) - self.group = None - self.value = value #(self, value) - self.widget = None - - if type(label) == str: - label = basic.Label(label, cls=self.cls+".label") - - if image and label: - self.widget = container.Container() - self.widget.add(image, 0, 0) - #HACK: improper use of .resize() - image.rect.w,image.rect.h = image.resize() - self.widget.add(label, image.rect.w, 0) - elif image: self.widget = image - elif label: self.widget = label - - self.pcls = "" - - def resize(self,width=None,height=None): - self.widget.rect.w,self.widget.rect.h = self.widget.resize() - return self.widget.rect.w,self.widget.rect.h -# self.widget._resize() -# self.rect.w,self.rect.h = self.widget.rect_margin.w,self.widget.rect_margin.h - - def event(self,e): - button._button.event(self,e) - if self.group.value == self.value: self.pcls = "down" - - def paint(self,s): - if self.group.value == self.value: self.pcls = "down" - self.widget.paint(surface.subsurface(s,self.widget.rect)) - - def click(self): - self.group.value = self.value - for w in self.group.widgets: - if w != self: w.pcls = "" - - - -class List(ScrollArea): - """A list of items in an area. - -

This widget can be a form element, it has a value set to whatever item is selected.

- -
List(width,height)
- """ - def _change(self, value): - self.value = self.group.value - self.send(CHANGE) - - def __init__(self, width, height, **params): - params.setdefault('cls', 'list') - self.table = table.Table(width=width) - ScrollArea.__init__(self, self.table, width, height,hscrollbar=False ,**params) - - self.items = [] - - g = group.Group() - self.group = g - g.connect(CHANGE,self._change,None) - self.value = self.group.value = None - - self.add = self._add - self.remove = self._remove - - def clear(self): - """Clear the list. - -
List.clear()
- """ - self.items = [] - self.group = group.Group() - self.group.connect(CHANGE,self._change,None) - self.table.clear() - self.set_vertical_scroll(0) - self.blur(self.myfocus) - - def _docs(self): #HACK: nasty hack to get the docs in "my way" - def add(self, label, image=None, value=None): - """Add an item to the list. - -
List.add(label,image=None,value=None)
- -
-
label
a label for the item -
image
an image for the item -
value
a value for the item -
- """ - - def remove(self,value): - """Remove an item from the list. - -
List.remove(value)
- -
-
value
a value of an item to remove from the list -
- """ - - def _add(self, label, image = None, value=None): - item = _List_Item(label,image=image,value=value) - self.table.tr() - self.table.add(item) - self.items.append(item) - item.group = self.group - item.group.add(item) - - def _remove(self, item): - for i in self.items: - if i.value == item: item = i - if item not in self.items: return - item.blur() - self.items.remove(item) - self.group.widgets.remove(item) - self.table.remove_row(item.style.row) - -#class List(ListArea): -# def __init__(self,*args,**params): -# print 'gui.List','Scheduled to be renamed to ListArea. API may also be changed in the future.' -# ListArea.__init__(self,*args,**params) diff --git a/src/pgu/gui/basic.py b/src/pgu/gui/basic.py deleted file mode 100644 index 3800440..0000000 --- a/src/pgu/gui/basic.py +++ /dev/null @@ -1,136 +0,0 @@ -"""These widgets are all grouped together because they are non-interactive widgets. -""" - -import pygame - -from const import * -import widget - -# Turns a descriptive string or a tuple into a pygame color -def parse_color(desc): - if (is_color(desc)): - # Already a color - return desc - elif (desc and desc[0] == "#"): - # Because of a bug in pygame 1.8.1 we need to explicitly define the - # alpha value otherwise it will default to transparent. - if (len(desc) == 7): - desc += "FF" - return pygame.Color(desc) - -# Determines if the given object is a pygame-compatible color or not -def is_color(col): - # In every version of pygame (up to 1.8.1 so far) will interpret - # a tuple as a color. - if (type(col) == tuple): - return col - if (hasattr(pygame, "Color") and type(pygame.Color) == type): - # This is a recent version of pygame that uses a proper type - # instance for colors. - return (isinstance(col, pygame.Color)) - # Otherwise, this version of pygame only supports tuple colors - return False - -class Spacer(widget.Widget): - """A invisible space. - -
Spacer(width,height)
- - """ - def __init__(self,width,height,**params): - params.setdefault('focusable',False) - widget.Widget.__init__(self,width=width,height=height,**params) - - -class Color(widget.Widget): - """A block of color. - -

The color can be changed at run-time.

- -
Color(value=None)
- - Example - - c = Color() - c.value = (255,0,0) - c.value = (0,255,0) - - """ - - - def __init__(self,value=None,**params): - params.setdefault('focusable',False) - if value != None: params['value']=value - widget.Widget.__init__(self,**params) - - def paint(self,s): - if hasattr(self,'value'): s.fill(self.value) - - def __setattr__(self,k,v): - if k == 'value' and type(v) == str: - v = parse_color(v) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - -class Label(widget.Widget): - """A text label. - -
Label(value)
- -
-
value
text to be displayed -
- - Example - - w = Label(value="I own a rubber chicken!") - - w = Label("3 rubber chickens") - - """ - def __init__(self,value,**params): - params.setdefault('focusable',False) - params.setdefault('cls','label') - widget.Widget.__init__(self,**params) - self.value = value - self.font = self.style.font - self.style.width, self.style.height = self.font.size(self.value) - - def paint(self,s): - s.blit(self.font.render(self.value, 1, self.style.color),(0,0)) - -class Image(widget.Widget): - """An image. - -
Image(value)
- -
-
value
a file name or a pygame.Surface -
- - """ - def __init__(self,value,**params): - params.setdefault('focusable',False) - widget.Widget.__init__(self,**params) - if type(value) == str: value = pygame.image.load(value) - - ow,oh = iw,ih = value.get_width(),value.get_height() - sw,sh = self.style.width,self.style.height - - if sw and not sh: - iw,ih = sw,ih*sw/iw - elif sh and not sw: - iw,ih = iw*sh/ih,sh - elif sw and sh: - iw,ih = sw,sh - - if (ow,oh) != (iw,ih): - value = pygame.transform.scale(value,(iw,ih)) - self.style.width,self.style.height = iw,ih - self.value = value - - def paint(self,s): - s.blit(self.value,(0,0)) diff --git a/src/pgu/gui/button.py b/src/pgu/gui/button.py deleted file mode 100644 index 90cdd1e..0000000 --- a/src/pgu/gui/button.py +++ /dev/null @@ -1,351 +0,0 @@ -""" -""" - -from pygame.locals import * - -from const import * -import widget, surface -import basic - -class _button(widget.Widget): - def __init__(self,**params): - widget.Widget.__init__(self,**params) - self.state = 0 - - def event(self,e): - if e.type == ENTER: self.repaint() - elif e.type == EXIT: self.repaint() - elif e.type == FOCUS: self.repaint() - elif e.type == BLUR: self.repaint() - elif e.type == KEYDOWN: - if e.key == K_SPACE or e.key == K_RETURN: - self.state = 1 - self.repaint() - elif e.type == MOUSEBUTTONDOWN: - self.state = 1 - self.repaint() - elif e.type == KEYUP: - if self.state == 1: - sub = pygame.event.Event(CLICK,{'pos':(0,0),'button':1}) - #self.send(sub.type,sub) - self._event(sub) - - self.state = 0 - self.repaint() - elif e.type == MOUSEBUTTONUP: - self.state = 0 - self.repaint() - elif e.type == CLICK: - self.click() - - self.pcls = "" - if self.state == 0 and self.container.myhover is self: - self.pcls = "hover" - if self.state == 1 and self.container.myhover is self: - self.pcls = "down" - - def click(self): - pass - - -class Button(_button): - """A button, buttons can be clicked, they are usually used to set up callbacks. - -
Button(value=None)
- -
-
value
either a widget or a string -
- - Example - - w = gui.Button("Click Me") - w.connect(gui.CLICK,fnc,value) - - """ - def __init__(self,value=None,**params): - params.setdefault('cls','button') - _button.__init__(self,**params) - self.value = value - - def __setattr__(self,k,v): - if k == 'value' and type(v) == str: v = basic.Label(v,cls=self.cls+".label") - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and v != None: - pass - - if k == 'value' and _v != NOATTR and _v != None and _v != v: - self.send(CHANGE) - self.chsize() - - def resize(self,width=None,height=None): - self.value.rect.x,self.value.rect.y = 0,0 - self.value.rect.w,self.value.rect.h = self.value.resize(width,height) - return self.value.rect.w,self.value.rect.h -# -# self.value._resize() -# self.rect.w,self.rect.h = self.value.rect_margin.w,self.value.rect_margin.h -# -# if self.style.width: self.rect.w = max(self.rect.w,self.style.width) -# if self.style.height: self.rect.w = max(self.rect.w,self.style.height) -# -# xt,xr,xb,xl = self.value.getspacing() -# -# self.value._resize(self.rect.w-(xl+xr),self.rect.h-(xt+xb)) -# - def paint(self,s): - self.value.pcls = self.pcls - self.value.paint(surface.subsurface(s,self.value.rect)) - -class Switch(_button): - """A switch can have two states, True or False. - -
Switch(value=False)
- -
-
value
initial value, (True, False) -
- - Example - - w = gui.Switch(True) - w.connect(gui.CHANGE,fnc,value) - - """ - def __init__(self,value=False,**params): - params.setdefault('cls','switch') - _button.__init__(self,**params) - self.value = value - - img = self.style.off - self.style.width = img.get_width() - self.style.height = img.get_height() - - def paint(self,s): - #self.pcls = "" - #if self.container.myhover is self: self.pcls = "hover" - if self.value: img = self.style.on - else: img = self.style.off - s.blit(img,(0,0)) - - def __setattr__(self,k,v): - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - - def click(self): - self.value = not self.value - -class Checkbox(_button): - """Within a Group of Checkbox widgets several may be selected at a time. - -
Checkbox(group,value=None)
- -
-
group
a gui.Group for the Checkbox to belong to -
value
the value -
- - Example - - g = gui.Group(name='colors',value=['r','b']) - - t = gui.Table() - t.tr() - t.td(gui.Label('Red')) - t.td(gui.Checkbox(g,'r')) - t.tr() - t.td(gui.Label('Green')) - t.td(gui.Checkbox(g,'g')) - t.tr() - t.td(gui.Label('Blue')) - t.td(gui.Checkbox(g,'b')) - - """ - - def __init__(self,group,value=None,**params): - params.setdefault('cls','checkbox') - _button.__init__(self,**params) - self.group = group - self.group.add(self) - if self.group.value == None: - self.group.value = [] - self.value = value - - img = self.style.off - self.style.width = img.get_width() - self.style.height = img.get_height() - - def paint(self,s): - #self.pcls = "" - #if self.container.myhover is self: self.pcls = "hover" - if self.value in self.group.value: img = self.style.on - else: img = self.style.off - - s.blit(img,(0,0)) - - def click(self): - if self.value in self.group.value: - self.group.value.remove(self.value) - else: - self.group.value.append(self.value) - self.group._change() - -class Radio(_button): - """Within a Group of Radio widgets only one may be selected at a time. - -
Radio(group,value=None)
- -
-
group
a gui.Group for the Radio to belong to -
value
the value -
- - Example - - g = gui.Group(name='colors',value='g') - - t = gui.Table() - t.tr() - t.td(gui.Label('Red')) - t.td(gui.Radio(g,'r')) - t.tr() - t.td(gui.Label('Green')) - t.td(gui.Radio(g,'g')) - t.tr() - t.td(gui.Label('Blue')) - t.td(gui.Radio(g,'b')) - - """ - - - def __init__(self,group=None,value=None,**params): - params.setdefault('cls','radio') - _button.__init__(self,**params) - self.group = group - self.group.add(self) - self.value = value - - img = self.style.off - self.style.width = img.get_width() - self.style.height = img.get_height() - - def paint(self,s): - #self.pcls = "" - #if self.container.myhover is self: self.pcls = "hover" - if self.group.value == self.value: img = self.style.on - else: img = self.style.off - s.blit(img,(0,0)) - - def click(self): - self.group.value = self.value - -class Tool(_button): - """Within a Group of Tool widgets only one may be selected at a time. - -
Tool(group,widget=None,value=None)
- -
-
group
a gui.Group for the Tool to belong to -
widget
a widget to appear on the Tool (similar to a Button) -
value
the value -
- - Example - - g = gui.Group(name='colors',value='g') - - t = gui.Table() - t.tr() - t.td(gui.Tool(g,'Red','r')) - t.tr() - t.td(gui.Tool(g,'Green','g')) - t.tr() - t.td(gui.Tool(g,'Blue','b')) - - """ - - def __init__(self,group,widget=None,value=None,**params): #TODO widget= could conflict with module widget - params.setdefault('cls','tool') - _button.__init__(self,**params) - self.group = group - self.group.add(self) - self.value = value - - if widget: - self.setwidget(widget) - - if self.group.value == self.value: self.pcls = "down" - - def setwidget(self,w): - self.widget = w - - def resize(self,width=None,height=None): - self.widget.rect.w,self.widget.rect.h = self.widget.resize() - #self.widget._resize() - #self.rect.w,self.rect.h = self.widget.rect_margin.w,self.widget.rect_margin.h - - return self.widget.rect.w,self.widget.rect.h - - def event(self,e): - _button.event(self,e) - if self.group.value == self.value: self.pcls = "down" - - def paint(self,s): - if self.group.value == self.value: self.pcls = "down" - self.widget.paint(surface.subsurface(s,self.widget.rect)) - - def click(self): - self.group.value = self.value - for w in self.group.widgets: - if w != self: w.pcls = "" - - -class Icon(_button): - """TODO - might be deprecated - """ - def __init__(self,cls,**params): - params['cls'] = cls - _button.__init__(self,**params) - s = self.style.image - self.style.width = s.get_width() - self.style.height = s.get_height() - self.state = 0 - - def paint(self,s): - #self.pcls = "" - #if self.state == 0 and hasattr(self.container,'myhover') and self.container.myhover is self: self.pcls = "hover" - #if self.state == 1 and hasattr(self.container,'myhover') and self.container.myhover is self: self.pcls = "down" - s.blit(self.style.image,(0,0)) - -class Link(_button): - """A link, links can be clicked, they are usually used to set up callbacks. - Basically the same as the button widget, just text only with a different cls. Made for - convenience. - -
Link(value=None)
- -
-
value
a string -
- - Example - - w = gui.Link("Click Me") - w.connect(gui.CLICK,fnc,value) - - """ - def __init__(self,value,**params): - params.setdefault('focusable',True) - params.setdefault('cls','link') - _button.__init__(self,**params) - self.value = value - self.font = self.style.font - self.style.width, self.style.height = self.font.size(self.value) - - def paint(self,s): - s.blit(self.font.render(self.value, 1, self.style.color),(0,0)) - diff --git a/src/pgu/gui/const.py b/src/pgu/gui/const.py deleted file mode 100644 index c865cd8..0000000 --- a/src/pgu/gui/const.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Constants. -

-Event Types - -

from pygame

-
-
QUIT -
MOUSEBUTTONDOWN -
MOUSEBUTTONUP -
MOUSEMOTION -
KEYDOWN -
- -

gui specific

-
-
ENTER -
EXIT -
BLUR -
FOCUS -
CLICK -
CHANGE -
OPEN -
CLOSE -
INIT -
- -Other -
-
NOATTR -
-""" -import pygame - -from pygame.locals import QUIT, MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION, KEYDOWN, USEREVENT -ENTER = pygame.locals.USEREVENT + 0 -EXIT = pygame.locals.USEREVENT + 1 -BLUR = pygame.locals.USEREVENT + 2 -FOCUS = pygame.locals.USEREVENT + 3 -CLICK = pygame.locals.USEREVENT + 4 -CHANGE = pygame.locals.USEREVENT + 5 -OPEN = pygame.locals.USEREVENT + 6 -CLOSE = pygame.locals.USEREVENT + 7 -INIT = 'init' - -class NOATTR: pass \ No newline at end of file diff --git a/src/pgu/gui/container.py b/src/pgu/gui/container.py deleted file mode 100644 index 73a8e68..0000000 --- a/src/pgu/gui/container.py +++ /dev/null @@ -1,414 +0,0 @@ -""" -""" -import pygame -from pygame.locals import * - -from const import * -import widget, surface -import pguglobals - -class Container(widget.Widget): - """The base container widget, can be used as a template as well as stand alone. - -
Container()
- """ - def __init__(self,**params): - widget.Widget.__init__(self,**params) - self.myfocus = None - self.mywindow = None - self.myhover = None - #self.background = 0 - self.widgets = [] - self.windows = [] - self.toupdate = {} - self.topaint = {} - - def update(self,s): - updates = [] - - if self.myfocus: self.toupdate[self.myfocus] = self.myfocus - - for w in self.topaint: - if w is self.mywindow: - continue - else: - sub = surface.subsurface(s,w.rect) - #if (hasattr(w, "_container_bkgr")): - # sub.blit(w._container_bkgr,(0,0)) - w.paint(sub) - updates.append(pygame.rect.Rect(w.rect)) - - for w in self.toupdate: - if w is self.mywindow: - continue - else: - us = w.update(surface.subsurface(s,w.rect)) - if us: - for u in us: - updates.append(pygame.rect.Rect(u.x + w.rect.x,u.y+w.rect.y,u.w,u.h)) - - for w in self.topaint: - if w is self.mywindow: - w.paint(self.top_surface(s,w)) - updates.append(pygame.rect.Rect(w.rect)) - else: - continue - - for w in self.toupdate: - if w is self.mywindow: - us = w.update(self.top_surface(s,w)) - else: - continue - if us: - for u in us: - updates.append(pygame.rect.Rect(u.x + w.rect.x,u.y+w.rect.y,u.w,u.h)) - - self.topaint = {} - self.toupdate = {} - - return updates - - def repaint(self,w=None): - if not w: - return widget.Widget.repaint(self) - self.topaint[w] = w - self.reupdate() - - def reupdate(self,w=None): - if not w: - return widget.Widget.reupdate(self) - self.toupdate[w] = w - self.reupdate() - - def paint(self,s): - self.toupdate = {} - self.topaint = {} - for w in self.widgets: - try: - sub = surface.subsurface(s, w.rect) - except: - print 'container.paint(): %s not inside %s' % ( - w.__class__.__name__,self.__class__.__name__) - print s.get_width(), s.get_height(), w.rect - print "" - else: -# if (not hasattr(w,'_container_bkgr') or -# w._container_bkgr.get_size() != sub.get_size()): -# #w._container_bkgr.get_width() == sub.get_width() and -# #w._container_bkgr.get_height() == sub.get_height())): -# w._container_bkgr = sub.copy() -# w._container_bkgr.fill((0,0,0,0)) -# w._container_bkgr.blit(sub,(0,0)) - w.paint(sub) - - for w in self.windows: - w.paint(self.top_surface(s,w)) - - def top_surface(self,s,w): - x,y = s.get_abs_offset() - s = s.get_abs_parent() - return surface.subsurface(s,(x+w.rect.x,y+w.rect.y,w.rect.w,w.rect.h)) - - def event(self,e): - used = False - - if self.mywindow and e.type == MOUSEBUTTONDOWN: - w = self.mywindow - if self.myfocus is w: - if not w.rect.collidepoint(e.pos): self.blur(w) - if not self.myfocus: - if w.rect.collidepoint(e.pos): self.focus(w) - - if not self.mywindow: - #### by Gal Koren - ## - ## if e.type == FOCUS: - if e.type == FOCUS and not self.myfocus: - #self.first() - pass - elif e.type == EXIT: - if self.myhover: self.exit(self.myhover) - elif e.type == BLUR: - if self.myfocus: self.blur(self.myfocus) - elif e.type == MOUSEBUTTONDOWN: - h = None - for w in self.widgets: - if not w.disabled: #focusable not considered, since that is only for tabs - if w.rect.collidepoint(e.pos): - h = w - if self.myfocus is not w: self.focus(w) - if not h and self.myfocus: - self.blur(self.myfocus) - elif e.type == MOUSEMOTION: - if 1 in e.buttons: - if self.myfocus: ws = [self.myfocus] - else: ws = [] - else: ws = self.widgets - - h = None - for w in ws: - if w.rect.collidepoint(e.pos): - h = w - if self.myhover is not w: self.enter(w) - if not h and self.myhover: - self.exit(self.myhover) - w = self.myhover - - if w and w is not self.myfocus: - sub = pygame.event.Event(e.type,{ - 'buttons':e.buttons, - 'pos':(e.pos[0]-w.rect.x,e.pos[1]-w.rect.y), - 'rel':e.rel}) - used = w._event(sub) - - w = self.myfocus - if w: - sub = e - - if e.type == MOUSEBUTTONUP or e.type == MOUSEBUTTONDOWN: - sub = pygame.event.Event(e.type,{ - 'button':e.button, - 'pos':(e.pos[0]-w.rect.x,e.pos[1]-w.rect.y)}) - used = w._event(sub) - elif e.type == CLICK and self.myhover is w: - sub = pygame.event.Event(e.type,{ - 'button':e.button, - 'pos':(e.pos[0]-w.rect.x,e.pos[1]-w.rect.y)}) - used = w._event(sub) - elif e.type == CLICK: #a dead click - pass - elif e.type == MOUSEMOTION: - sub = pygame.event.Event(e.type,{ - 'buttons':e.buttons, - 'pos':(e.pos[0]-w.rect.x,e.pos[1]-w.rect.y), - 'rel':e.rel}) - used = w._event(sub) - else: - used = w._event(sub) - - if not used: - if e.type is KEYDOWN: - if e.key is K_TAB and self.myfocus: - if (e.mod&KMOD_SHIFT) == 0: - self.myfocus.next() - else: - self.myfocus.previous() - return True - elif e.key == K_UP: - self._move_focus(0,-1) - return True - elif e.key == K_RIGHT: - self._move_focus(1,0) - return True - elif e.key == K_DOWN: - self._move_focus(0,1) - return True - elif e.key == K_LEFT: - self._move_focus(-1,0) - return True - return used - - def _move_focus(self,dx_,dy_): - myfocus = self.myfocus - if not self.myfocus: return - - widgets = self._get_widgets(pguglobals.app) - #if myfocus not in widgets: return - #widgets.remove(myfocus) - if myfocus in widgets: - widgets.remove(myfocus) - rect = myfocus.get_abs_rect() - fx,fy = rect.centerx,rect.centery - - def sign(v): - if v < 0: return -1 - if v > 0: return 1 - return 0 - - dist = [] - for w in widgets: - wrect = w.get_abs_rect() - wx,wy = wrect.centerx,wrect.centery - dx,dy = wx-fx,wy-fy - if dx_ > 0 and wrect.left < rect.right: continue - if dx_ < 0 and wrect.right > rect.left: continue - if dy_ > 0 and wrect.top < rect.bottom: continue - if dy_ < 0 and wrect.bottom > rect.top: continue - dist.append((dx*dx+dy*dy,w)) - if not len(dist): return - dist.sort() - d,w = dist.pop(0) - w.focus() - - def _get_widgets(self,c): - widgets = [] - if c.mywindow: - widgets.extend(self._get_widgets(c.mywindow)) - else: - for w in c.widgets: - if isinstance(w,Container): - widgets.extend(self._get_widgets(w)) - elif not w.disabled and w.focusable: - widgets.append(w) - return widgets - - def remove(self,w): - """Remove a widget from the container. - -
Container.remove(w)
- """ - self.blur(w) - self.widgets.remove(w) - #self.repaint() - self.chsize() - - def add(self,w,x,y): - """Add a widget to the container. - -
Container.add(w,x,y)
- -
-
x, y
position of the widget -
- """ - w.style.x = x - w.style.y = y - w.container = self - #NOTE: this might fix it, sort of... - #but the thing is, we don't really want to resize - #something if it is going to get resized again later - #for no reason... - #w.rect.x,w.rect.y = w.style.x,w.style.y - #w.rect.w, w.rect.h = w.resize() - self.widgets.append(w) - self.chsize() - - def open(self,w=None,x=None,y=None): - if (not w): - w = self - - if (x != None): - # The position is relative to this container - rect = self.get_abs_rect() - pos = (rect.x + x, rect.y + y) - else: - pos = None - # Have the application open the window - pguglobals.app.open(w, pos) - - def focus(self,w=None): - widget.Widget.focus(self) ### by Gal koren -# if not w: -# return widget.Widget.focus(self) - if not w: return - if self.myfocus: self.blur(self.myfocus) - if self.myhover is not w: self.enter(w) - self.myfocus = w - w._event(pygame.event.Event(FOCUS)) - - #print self.myfocus,self.myfocus.__class__.__name__ - - def blur(self,w=None): - if not w: - return widget.Widget.blur(self) - if self.myfocus is w: - if self.myhover is w: self.exit(w) - self.myfocus = None - w._event(pygame.event.Event(BLUR)) - - def enter(self,w): - if self.myhover: self.exit(self.myhover) - self.myhover = w - w._event(pygame.event.Event(ENTER)) - - def exit(self,w): - if self.myhover and self.myhover is w: - self.myhover = None - w._event(pygame.event.Event(EXIT)) - - -# def first(self): -# for w in self.widgets: -# if w.focusable: -# self.focus(w) -# return -# if self.container: self.container.next(self) - -# def next(self,w): -# if w not in self.widgets: return #HACK: maybe. this happens in windows for some reason... -# -# for w in self.widgets[self.widgets.index(w)+1:]: -# if w.focusable: -# self.focus(w) -# return -# if self.container: return self.container.next(self) - - - def _next(self,orig=None): - start = 0 - if orig in self.widgets: start = self.widgets.index(orig)+1 - for w in self.widgets[start:]: - if not w.disabled and w.focusable: - if isinstance(w,Container): - if w._next(): - return True - else: - self.focus(w) - return True - return False - - def _previous(self,orig=None): - end = len(self.widgets) - if orig in self.widgets: end = self.widgets.index(orig) - ws = self.widgets[:end] - ws.reverse() - for w in ws: - if not w.disabled and w.focusable: - if isinstance(w,Container): - if w._previous(): - return True - else: - self.focus(w) - return True - return False - - def next(self,w=None): - if w != None and w not in self.widgets: return #HACK: maybe. this happens in windows for some reason... - - if self._next(w): return True - if self.container: return self.container.next(self) - - - def previous(self,w=None): - if w != None and w not in self.widgets: return #HACK: maybe. this happens in windows for some reason... - - if self._previous(w): return True - if self.container: return self.container.previous(self) - - def resize(self,width=None,height=None): - #r = self.rect - #r.w,r.h = 0,0 - ww,hh = 0,0 - if self.style.width: ww = self.style.width - if self.style.height: hh = self.style.height - - for w in self.widgets: - #w.rect.w,w.rect.h = 0,0 - w.rect.x,w.rect.y = w.style.x,w.style.y - w.rect.w, w.rect.h = w.resize() - #w._resize() - - ww = max(ww,w.rect.right) - hh = max(hh,w.rect.bottom) - return ww,hh - - # Returns the widget with the given name - def find(self, name): - for w in self.widgets: - if (w.name == name): - return w - elif (isinstance(w, Container)): - tmp = w.find(name) - if (tmp): return tmp - return None - diff --git a/src/pgu/gui/deprecated.py b/src/pgu/gui/deprecated.py deleted file mode 100644 index 8d53515..0000000 --- a/src/pgu/gui/deprecated.py +++ /dev/null @@ -1,76 +0,0 @@ -import pygame - -from const import * -import table -import group -import button, basic -import pguglobals - -def action_open(value): - print 'gui.action_open',"Scheduled to be deprecated." - value.setdefault('x',None) - value.setdefault('y',None) - value['container'].open(value['window'],value['x'],value['y']) - -def action_setvalue(value): - print 'gui.action_setvalue',"Scheduled to be deprecated." - a,b = value - b.value = a.value - -def action_quit(value): - print 'gui.action_quit',"Scheduled to be deprecated." - value.quit() - -def action_exec(value): - print 'gui.action_exec',"Scheduled to be deprecated." - exec(value['script'],globals(),value['dict']) - -class Toolbox(table.Table): - def __setattr__(self,k,v): - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.group.value = v - for w in self.group.widgets: - if w.value != v: w.pcls = "" - else: w.pcls = "down" - self.repaint() - - def _change(self,value): - self.value = self.group.value - self.send(CHANGE) - - def __init__(self,data,cols=0,rows=0,tool_cls='tool',value=None,**params): - print 'gui.Toolbox','Scheduled to be deprecated.' - params.setdefault('cls','toolbox') - table.Table.__init__(self,**params) - - if cols == 0 and rows == 0: cols = len(data) - if cols != 0 and rows != 0: rows = 0 - - self.tools = {} - - _value = value - - g = group.Group() - self.group = g - g.connect(CHANGE,self._change,None) - self.group.value = _value - - x,y,p,s = 0,0,None,1 - for ico,value in data: - #from __init__ import theme - img = pguglobals.app.theme.get(tool_cls+"."+ico,"","image") - if img: - i = basic.Image(img) - else: i = basic.Label(ico,cls=tool_cls+".label") - p = button.Tool(g,i,value,cls=tool_cls) - self.tools[ico] = p - #p.style.hexpand = 1 - #p.style.vexpand = 1 - self.add(p,x,y) - s = 0 - if cols != 0: x += 1 - if cols != 0 and x == cols: x,y = 0,y+1 - if rows != 0: y += 1 - if rows != 0 and y == rows: x,y = x+1,0 diff --git a/src/pgu/gui/dialog.py b/src/pgu/gui/dialog.py deleted file mode 100644 index 0d30b34..0000000 --- a/src/pgu/gui/dialog.py +++ /dev/null @@ -1,168 +0,0 @@ -""" -""" -import os - -from const import * -import table, area -import basic, input, button -import pguglobals - -class Dialog(table.Table): - """A dialog window with a title bar and an "close" button on the bar. - -
Dialog(title,main)
- -
-
title
title widget, usually a label -
main
main widget, usually a container -
- - Example - - title = gui.Label("My Title") - main = gui.Container() - #add stuff to the container... - - d = gui.Dialog(title,main) - d.open() - - """ - def __init__(self,title,main,**params): - params.setdefault('cls','dialog') - table.Table.__init__(self,**params) - - - self.tr() - self.td(title,align=-1,cls=self.cls+'.bar') - clos = button.Icon(self.cls+".bar.close") - clos.connect(CLICK,self.close,None) - self.td(clos,align=1,cls=self.cls+'.bar') - - self.tr() - self.td(main,colspan=2,cls=self.cls+".main") - - -# self.tr() -# -# -# t = table.Table(cls=self.cls+".bar") -# t.tr() -# t.td(title) -# clos = button.Icon(self.cls+".bar.close") -# t.td(clos,align=1) -# clos.connect(CLICK,self.close,None) -# self.add(t,0,0) -# -# main.rect.w,main.rect.h = main.resize() -# clos.rect.w,clos.rect.h = clos.resize() -# title.container.style.width = main.rect.w - clos.rect.w -# -# self.tr() -# self.td(main,cls=self.cls+".main") -# - - -class FileDialog(Dialog): - """A file picker dialog window. - -
FileDialog()
-

Some optional parameters:

-
-
title_txt
title text -
button_txt
button text -
path
initial path -
- """ - - def __init__(self, title_txt="File Browser", button_txt="Okay", cls="dialog", folderText = "Folder", fileText = "File", path=None, customFont = None, showCurDir = True, customWidth = 350, customHeight = 150): - - self.customFont = customFont - self.showCurDir= showCurDir - cls1 = 'filedialog' - if not path: self.curdir = os.getcwd() - else: self.curdir = path - self.dir_img = basic.Image( - pguglobals.app.theme.get(cls1+'.folder', '', 'image')) - td_style = {'padding_left': 4, - 'padding_right': 4, - 'padding_top': 2, - 'padding_bottom': 2} - self.title = basic.Label(title_txt, cls=cls+".title.label") - self.body = table.Table() - self.list = area.List(width=customWidth, height=customHeight) - self.input_dir = input.Input(customFont = self.customFont) - self.input_file = input.Input(customFont = self.customFont) - self._list_dir_() - self.button_ok = button.Button(button_txt) - self.body.tr() - if self.showCurDir : - self.body.td(basic.Label(folderText), style=td_style, align=-1) - self.body.td(self.input_dir, style=td_style) - self.body.tr() - self.body.td(self.list, colspan=3, style=td_style) - self.list.connect(CHANGE, self._item_select_changed_, None) - self.button_ok.connect(CLICK, self._button_okay_clicked_, None) - self.body.tr() - self.body.td(basic.Label(fileText), style=td_style, align=-1) - self.body.td(self.input_file, style=td_style) - self.body.td(self.button_ok, style=td_style) - self.value = None - Dialog.__init__(self, self.title, self.body) - - def _list_dir_(self): - self.input_dir.value = self.curdir - self.input_dir.pos = len(self.curdir) - self.input_dir.vpos = 0 - dirs = [] - files = [] - try: - for i in os.listdir(self.curdir): - if os.path.isdir(os.path.join(self.curdir, i)): dirs.append(i) - else: files.append(i) - except: - self.input_file.value = "Opps! no access" - #if '..' not in dirs: dirs.append('..') - dirs.sort() - dirs = ['..'] + dirs - - files.sort() - for i in dirs: - #item = ListItem(image=self.dir_img, text=i, value=i) - if self.customFont == None : - self.list.add(i,image=self.dir_img,value=i) - else : - label = basic.Label(i,font = self.customFont) - self.list.add(label,image=self.dir_img,value=i) - for i in files: - #item = ListItem(image=None, text=i, value=i) - if self.customFont == None : - self.list.add(i,value=i) - else: - label = basic.Label(i,font = self.customFont) - self.list.add(label,value=i) - #self.list.resize() - self.list.set_vertical_scroll(0) - #self.list.repaintall() - - - def _item_select_changed_(self, arg): - self.input_file.value = self.list.value - fname = os.path.abspath(os.path.join(self.curdir, self.input_file.value)) - if os.path.isdir(fname): - self.input_file.value = "" - self.curdir = fname - self.list.clear() - self._list_dir_() - - - def _button_okay_clicked_(self, arg): - if self.input_dir.value != self.curdir: - if os.path.isdir(self.input_dir.value): - self.input_file.value = "" - self.curdir = os.path.abspath(self.input_dir.value) - self.list.clear() - self._list_dir_() - else: - self.value = os.path.join(self.curdir, self.input_file.value) - self.send(CHANGE) - self.close() diff --git a/src/pgu/gui/document.py b/src/pgu/gui/document.py deleted file mode 100644 index 1bd96df..0000000 --- a/src/pgu/gui/document.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -""" -import pygame - -import container -import layout - -class _document_widget: - def __init__(self,w,align=None): - #w.rect.w,w.rect.h = w.resize() - #self.rect = w.rect - self.widget = w - if align != None: self.align = align - -class Document(container.Container): - """A document container contains many widgets strung together in a document format. (How informative!) - -
Document()
- - """ - def __init__(self,**params): - params.setdefault('cls','document') - container.Container.__init__(self,**params) - self.layout = layout.Layout(pygame.Rect(0,0,self.rect.w,self.rect.h)) - - def add(self,e,align=None): - """Add a widget. - -
Document.add(e,align=None)
- -
-
e
widget -
align
alignment (None,-1,0,1) -
- """ - dw = _document_widget(e,align) - self.layout.add(dw) - e.container = self - e._c_dw = dw - self.widgets.append(e) - self.chsize() - - def remove(self,e): - self.layout._widgets.remove(e._c_dw) - self.widgets.remove(e) - self.chsize() - - - def block(self,align): - """Start a new block. - -
Document.block(align)
- -
-
align
alignment of block (-1,0,1) -
- """ - self.layout.add(align) - - def space(self,e): - """Add a spacer. - -
Document.space(e)
- -
-
e
a (w,h) size for the spacer -
- """ - self.layout.add(e) - - def br(self,height): - """Add a line break. - -
Document.br(height)
- -
-
height
height of line break -
- """ - self.layout.add((0,height)) - - def resize(self,width=None,height=None): - if self.style.width: width = self.style.width - if self.style.height: height = self.style.height - - for w in self.widgets: - w.rect.w,w.rect.h = w.resize() - - if (width != None and w.rect.w > width) or (height != None and w.rect.h > height): - w.rect.w,w.rect.h = w.resize(width,height) - - dw = w._c_dw - dw.rect = pygame.Rect(0,0,w.rect.w,w.rect.h) - - if width == None: width = 65535 - self.layout.rect = pygame.Rect(0,0,width,0) - self.layout.resize() - - _max_w = 0 - - for w in self.widgets: - #xt,xl,xb,xr = w.getspacing() - dw = w._c_dw - w.style.x,w.style.y,w.rect.w,w.rect.h = dw.rect.x,dw.rect.y,dw.rect.w,dw.rect.h - #w.resize() - w.rect.x,w.rect.y = w.style.x,w.style.y - _max_w = max(_max_w,w.rect.right) - - #self.rect.w = _max_w #self.layout.rect.w - #self.rect.h = self.layout.rect.h - #print 'document',_max_w,self.layout.rect.h - return _max_w,self.layout.rect.h diff --git a/src/pgu/gui/form.py b/src/pgu/gui/form.py deleted file mode 100644 index 9a874f9..0000000 --- a/src/pgu/gui/form.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -""" -import widget - -class Form(widget.Widget): - """A form that automatically will contain all named widgets. - -

After a form is created, all named widget that are subsequently created are added - to that form. You may use dict style access to access named widgets.

- -
Form()
- - Example - - f = gui.Form() - - w = gui.Input("Phil",name="firstname") - w = gui.Input("Hassey",name="lastname") - - print f.results() - print '' - print f.items() - print '' - print f['firstname'].value - print f['lastname'].value - - """ - - def __init__(self): - widget.Widget.__init__(self,decorate=False) - self._elist = [] - self._emap = {} - self._dirty = 0 - Form.form = self - - def add(self,e,name=None,value=None): - if name != None: e.name = name - if value != None: e.value = value - self._elist.append(e) - self._dirty = 1 - - def _clean(self): - for e in self._elist[:]: - if not hasattr(e,'name') or e.name == None: - self._elist.remove(e) - self._emap = {} - for e in self._elist: - self._emap[e.name] = e - self._dirty = 0 - - def __getitem__(self,k): - if self._dirty: self._clean() - return self._emap[k] - - def __contains__(self,k): - if self._dirty: self._clean() - if k in self._emap: return True - return False - - def results(self): - """Return a dict of name => values. - -
Form.results(): return dict
- """ - if self._dirty: self._clean() - r = {} - for e in self._elist: - r[e.name] = e.value - return r - - def items(self): - """Return a list of name, value keys. - -
Form.items(): return list
- """ - return self.results().items() - - #def start(self): - # Object.start(self,-1) diff --git a/src/pgu/gui/group.py b/src/pgu/gui/group.py deleted file mode 100644 index bcb231a..0000000 --- a/src/pgu/gui/group.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -""" -from const import * -import widget - -class Group(widget.Widget): - """An object for grouping together Form elements. - -
Group(name=None,value=None)
- -
-
name
name as used in the Form -
value
values that are currently selected in the group -
- -

See [[gui-button]] for several examples.

- -

When the value changes, an gui.CHANGE event is sent. - Although note, that when the value is a list, it may have to be sent by hand via - g.send(gui.CHANGE)

- """ - - def __init__(self,name=None,value=None): - widget.Widget.__init__(self,name=name,value=value) - self.widgets = [] - - def add(self,w): - """Add a widget to this group. - -
Group.add(w)
- """ - self.widgets.append(w) - - def __setattr__(self,k,v): - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k] = v - if k == 'value' and _v != NOATTR and _v != v: - self._change() - - def _change(self): - self.send(CHANGE) - for w in self.widgets: - w.repaint() diff --git a/src/pgu/gui/input.py b/src/pgu/gui/input.py deleted file mode 100644 index 3f3f653..0000000 --- a/src/pgu/gui/input.py +++ /dev/null @@ -1,169 +0,0 @@ -""" -""" -import pygame -from pygame.locals import * - -from const import * -import widget - -class Input(widget.Widget): - """A single line text input. - -
Input(value="",size=20)
- -
-
value
initial text -
size
size for the text box, in characters -
- - Example - - w = Input(value="Cuzco the Goat",size=20) - - w = Input("Marbles") - - - """ - def __init__(self,value="",size=20,customFont = None,**params): - params.setdefault('cls','input') - widget.Widget.__init__(self,**params) - self.value = value - self.pos = len(str(value)) - self.vpos = 0 - if customFont != None: - self.font = customFont - else: - self.font = self.style.font - w,h = self.font.size("e"*size) - if not self.style.height: self.style.height = h - if not self.style.width: self.style.width = w - #self.style.height = max(self.style.height,h) - #self.style.width = max(self.style.width,w) - #self.rect.w=w+self.style.padding_left+self.style.padding_right; - #self.rect.h=h+self.style.padding_top+self.style.padding_bottom; - - def paint(self,s): - - r = pygame.Rect(0,0,self.rect.w,self.rect.h) - - cs = 2 #NOTE: should be in a style - - w,h = self.font.size(self.value[0:self.pos]) - x = w-self.vpos - if x < 0: self.vpos -= -x - if x+cs > s.get_width(): self.vpos += x+cs-s.get_width() - - s.blit(self.font.render(self.value, 1, self.style.color),(-self.vpos,0)) - - if self.container.myfocus is self: - w,h = self.font.size(self.value[0:self.pos]) - r.x = w-self.vpos - r.w = cs - r.h = h - s.fill(self.style.color,r) - - def _setvalue(self,v): - self.__dict__['value'] = v - self.send(CHANGE) - - def event(self,e): - used = None - if e.type == KEYDOWN: - if e.key == K_BACKSPACE: - if self.pos: - self._setvalue(self.value[:self.pos-1] + self.value[self.pos:]) - self.pos -= 1 - elif e.key == K_DELETE: - if len(self.value) > self.pos: - self._setvalue(self.value[:self.pos] + self.value[self.pos+1:]) - elif e.key == K_HOME: - self.pos = 0 - elif e.key == K_END: - self.pos = len(self.value) - elif e.key == K_LEFT: - if self.pos > 0: self.pos -= 1 - used = True - elif e.key == K_RIGHT: - if self.pos < len(self.value): self.pos += 1 - used = True - elif e.key == K_RETURN: - self.next() - elif e.key == K_TAB: - pass - else: - #c = str(e.unicode) - try: - c = (e.unicode).encode('latin-1') - if c: - self._setvalue(self.value[:self.pos] + c + self.value[self.pos:]) - self.pos += 1 - except: #ignore weird characters - pass - self.repaint() - elif e.type == FOCUS: - self.repaint() - elif e.type == BLUR: - self.repaint() - - self.pcls = "" - if self.container.myfocus is self: self.pcls = "focus" - - return used - - def __setattr__(self,k,v): - if k == 'value': - if v == None: v = '' - v = str(v) - self.pos = len(v) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - -class Password(Input): - """A password input, text is *-ed out. - -
Password(value="",size=20)
- -
-
value
initial text -
size
size for the text box, in characters -
- - Example - - w = Password(value="password",size=20) - - w = Password("53[r3+") - - - """ - - def paint(self,s): - hidden="*" - show=len(self.value)*hidden - - #print "self.value:",self.value - - if self.pos == None: self.pos = len(self.value) - - r = pygame.Rect(0,0,self.rect.w,self.rect.h) - - cs = 2 #NOTE: should be in a style - - w,h = self.font.size(show) - x = w-self.vpos - if x < 0: self.vpos -= -x - if x+cs > s.get_width(): self.vpos += x+cs-s.get_width() - - s.blit(self.font.render(show, 1, self.style.color),(-self.vpos,0)) - - if self.container.myfocus is self: - #w,h = self.font.size(self.value[0:self.pos]) - w,h = self.font.size(show[0:self.pos]) - r.x = w-self.vpos - r.w = cs - r.h = h - s.fill(self.style.color,r) - diff --git a/src/pgu/gui/keysym.py b/src/pgu/gui/keysym.py deleted file mode 100644 index cc24089..0000000 --- a/src/pgu/gui/keysym.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -""" -import pygame -from pygame.locals import * - -from const import * -import widget - -class Keysym(widget.Widget): - """A keysym input. - -

This widget records the keysym of the key pressed while this widget is in focus.

- -
Keysym(value=None)
- -
-
value
initial keysym, see pygame keysyms
- - Example - - w = Input(value=pygame.locals.K_g) - - w = Input(pygame.locals.K_g) - - w = Input() - - - """ - - def __init__(self,value=None,**params): - params.setdefault('cls','keysym') - widget.Widget.__init__(self,**params) - self.value = value - - self.font = self.style.font - w,h = self.font.size("Right Super") #"Right Shift") - self.style.width,self.style.height = w,h - #self.rect.w=w+self.style.padding_left+self.style.padding_right - #self.rect.h=h+self.style.padding_top+self.style.padding_bottom - - def event(self,e): - used = None - if e.type == FOCUS or e.type == BLUR: self.repaint() - elif e.type == KEYDOWN: - if e.key != K_TAB: - self.value = e.key - self.repaint() - self.send(CHANGE) - used = True - self.next() - self.pcls = "" - if self.container.myfocus is self: self.pcls = "focus" - return used - - def paint(self,s): - r = pygame.rect.Rect(0,0,self.rect.w,self.rect.h) - #render_box(s,self.style.background,r) - if self.value == None: return - name = "" - for p in pygame.key.name(self.value).split(): name += p.capitalize()+" " - #r.x = self.style.padding_left; - #r.y = self.style.padding_bottom; - s.blit(self.style.font.render(name, 1, self.style.color), r) - - def __setattr__(self,k,v): - if k == 'value' and v != None: - v = int(v) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() diff --git a/src/pgu/gui/layout.py b/src/pgu/gui/layout.py deleted file mode 100644 index 01fe0cb..0000000 --- a/src/pgu/gui/layout.py +++ /dev/null @@ -1,172 +0,0 @@ -"""document layout engine.""" -class Layout: - """the document layout engine - - .widgets -- elements are kept in this list. read-only, use add to add items to it. - """ - - def __init__(self,rect=None): - """initialize the object with the size of the box.""" - self._widgets = [] - self.rect = rect - - def add(self,e): - """add a document element to the layout. - - a document element may be - - a tuple (w,h) if it is a whitespace element - - a tuple (0,h) if it is a linebreak element - - an integer -1,0,1 if it is a command to start a new block of elements that are aligned either left,center, or right. - - an object with a .rect (for size) -- such as a word element - - an object with a .rect (for size) and .align -- such as an image element - """ - - self._widgets.append(e) - - - def resize(self): - """resize the layout - this method recalculates the position of all document elements - after they have been added to the document. .rect.x,y will be updated for all - objects. - """ - self.init() - self.widgets = [] - for e in self._widgets: - if type(e) is tuple and e[0] != 0: - self.do_space(e) - elif type(e) is tuple and e[0] == 0: - self.do_br(e[1]) - elif type(e) is int: - self.do_block(align=e) - elif hasattr(e,'align'): - self.do_align(e) - else: - self.do_item(e) - self.line() - self.rect.h = max(self.y,self.left_bottom,self.right_bottom) - - def init(self): - self.x,self.y = self.rect.x,self.rect.y - self.left = self.rect.left - self.right = self.rect.right - self.left_bottom = 0 - self.right_bottom = 0 - self.y = self.rect.y - self.x = self.rect.x - self.h = 0 - - self.items = [] - self.align = -1 - - def getleft(self): - if self.y > self.left_bottom: - self.left = self.rect.left - return self.left - - def getright(self): - if self.y > self.right_bottom: - self.right = self.rect.right - return self.right - - def do_br(self,h): - self.line() - self.h = h - - def do_block(self,align=-1): - self.line() - self.align = align - - def do_align(self,e): - align = e.align - ox,oy,oh = self.x,self.y,self.h - w,h = e.rect.w,e.rect.h - - if align == 0: - self.line() - self.x = self.rect.left + (self.rect.width-w)/2 - self.fit = 0 - elif align == -1: - self.line() - self.y = max(self.left_bottom,self.y + self.h) - self.h = 0 - self.x = self.rect.left - elif align == 1: - self.line() - self.y = max(self.right_bottom,self.y + self.h) - self.h = 0 - self.x = self.rect.left + (self.rect.width-w) - - e.rect.x,e.rect.y = self.x,self.y - - self.x = self.x + w - self.y = self.y - - if align == 0: - self.h = max(self.h,h) - self.y = self.y + self.h - self.x = self.getleft() - self.h = 0 - elif align == -1: - self.left = self.x - self.left_bottom = self.y + h - self.x,self.y,self.h = ox + w,oy,oh - elif align == 1: - self.right = self.x - w - self.right_bottom = self.y + h - self.x,self.y,self.h = ox,oy,oh - - self.widgets.append(e) - - def do_space(self,e): - w,h = e - if self.x+w >= self.getright(): - self.line() - else: - self.items.append(e) - self.h = max(self.h,h) - self.x += w - - def do_item(self,e): - w,h = e.rect.w,e.rect.h - if self.x+w >= self.getright(): - self.line() - self.items.append(e) - self.h = max(self.h,h) - self.x += w - - def line(self): - x1 = self.getleft() - x2 = self.getright() - align = self.align - y = self.y - - if len(self.items) != 0 and type(self.items[-1]) == tuple: - del self.items[-1] - - w = 0 - for e in self.items: - if type(e) == tuple: w += e[0] - else: w += e.rect.w - - if align == -1: x = x1 - elif align == 0: - x = x1 + ((x2-x1)-w)/2 - self.fit = 0 - elif align == 1: x = x2 - w - - for e in self.items: - if type(e) == tuple: x += e[0] - else: - e.rect.x,e.rect.y = x,y - self.widgets.append(e) - x += e.rect.w - - self.items = [] - self.y = self.y + self.h - self.x = self.getleft() - self.h = 0 - - - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/gui/menus.py b/src/pgu/gui/menus.py deleted file mode 100644 index b850b6c..0000000 --- a/src/pgu/gui/menus.py +++ /dev/null @@ -1,119 +0,0 @@ -""" -""" -from const import * -import table -import basic, button - -class _Menu_Options(table.Table): - def __init__(self,menu,**params): - table.Table.__init__(self,**params) - - self.menu = menu - - def event(self,e): - handled = False - arect = self.get_abs_rect() - - if e.type == MOUSEMOTION: - abspos = e.pos[0]+arect.x,e.pos[1]+arect.y - for w in self.menu.container.widgets: - if not w is self.menu: - mrect = w.get_abs_rect() - if mrect.collidepoint(abspos): - self.menu._close(None) - w._open(None) - handled = True - - if not handled: table.Table.event(self,e) - -class _Menu(button.Button): - def __init__(self,parent,widget=None,**params): #TODO widget= could conflict with module widget - params.setdefault('cls','menu') - button.Button.__init__(self,widget,**params) - - self.parent = parent - - self._cls = self.cls - self.options = _Menu_Options(self, cls=self.cls+".options") - - self.connect(CLICK,self._open,None) - - self.pos = 0 - - def _open(self,value): - self.parent.value = self - self.pcls = 'down' - - self.repaint() - self.container.open(self.options,self.rect.x,self.rect.bottom) - self.options.connect(BLUR,self._close,None) - self.options.focus() - self.repaint() - - def _pass(self,value): - pass - - def _close(self,value): - self.pcls = '' - self.parent.value = None - self.repaint() - self.options.close() - - def _value(self,value): - self._close(None) - if value['fnc'] != None: - value['fnc'](value['value']) - - def event(self,e): - button.Button.event(self,e) - - if self.parent.value == self: - self.pcls = 'down' - - def add(self,w,fnc=None,value=None): - w.style.align = -1 - b = button.Button(w,cls=self.cls+".option") - b.connect(CLICK,self._value,{'fnc':fnc,'value':value}) - - self.options.tr() - self.options.add(b) - - return b - -class Menus(table.Table): - """A drop down menu bar. - -
Menus(data)
- -
-
data
Menu data, a list of (path,fnc,value), see example below -
- - Example - - data = [ - ('File/Save',fnc_save,None), - ('File/New',fnc_new,None), - ('Edit/Copy',fnc_copy,None), - ('Edit/Cut',fnc_cut,None), - ('Help/About',fnc_help,help_about_content), - ('Help/Reference',fnc_help,help_reference_content), - ] - w = Menus(data) - """ - - def __init__(self,data,menu_cls='menu',**params): - params.setdefault('cls','menus') - table.Table.__init__(self,**params) - - self.value = None - - n,m,mt = 0,None,None - for path,cmd,value in data: - parts = path.split("/") - if parts[0] != mt: - mt = parts[0] - m = _Menu(self,basic.Label(mt,cls=menu_cls+".label"),cls=menu_cls) - self.add(m,n,0) - n += 1 - m.add(basic.Label(parts[1],cls=m.cls+".option.label"),cmd,value) diff --git a/src/pgu/gui/misc.py b/src/pgu/gui/misc.py deleted file mode 100644 index afb10c5..0000000 --- a/src/pgu/gui/misc.py +++ /dev/null @@ -1,43 +0,0 @@ -from const import * -import widget -import pguglobals - -class ProgressBar(widget.Widget): - """A progress bar. - -
ProgressBar(value,min,max)
- -
-
value
starting value -
min
minimum value rendered on the screen (usually 0) -
max
maximum value -
- - Example - - w = gui.ProgressBar(0,0,100) - w.value = 25 - - """ - - def __init__(self,value,min,max,**params): - params.setdefault('cls','progressbar') - widget.Widget.__init__(self,**params) - self.min,self.max,self.value = min,max,value - - def paint(self,s): - r = pygame.rect.Rect(0,0,self.rect.w,self.rect.h) - r.w = r.w*(self.value-self.min)/(self.max-self.min) - self.bar = r - pguglobals.app.theme.render(s,self.style.bar,r) - - def __setattr__(self,k,v): - if k == 'value': - v = int(v) - v = max(v,self.min) - v = min(v,self.max) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() diff --git a/src/pgu/gui/pguglobals.py b/src/pgu/gui/pguglobals.py deleted file mode 100644 index dc0e673..0000000 --- a/src/pgu/gui/pguglobals.py +++ /dev/null @@ -1,7 +0,0 @@ -# pguglobals.py - A place to stick global variables that need to be accessed -# from other modules. To avoid problems with circular imports -# this module should not import any other PGU module. - -# A global reference to the application instance (App class) -app = None - diff --git a/src/pgu/gui/select.py b/src/pgu/gui/select.py deleted file mode 100644 index 0ee39e9..0000000 --- a/src/pgu/gui/select.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -""" - -import traceback - -from const import * -from button import Button -from basic import Label, Image -from table import Table - -class Select(Table): - """A select input. - -
Select(value=None)
- -
-
value
initial value -
- - Example - - w = Select(value="goats") - w.add("Cats","cats") - w.add("Goats","goats") - w.add("Dogs","Dogs") - - w.value = 'dogs' #changes the value from goats to dogs - - - """ - - # The drop-down arrow button for the selection widget - top_arrow = None - # A button displaying the currently selected item - top_selection = None - # The first option added to the selector - firstOption = None - # The PGU table of options - options = None - - def __init__(self,value=None,**params): - params.setdefault('cls','select') - Table.__init__(self,**params) - - label = Label(" ",cls=self.cls+".option.label") - self.top_selected = Button(label, cls=self.cls+".selected") - Table.add(self,self.top_selected) #,hexpand=1,vexpand=1)#,0,0) - - self.top_arrow = Button(Image(self.style.arrow), cls=self.cls+".arrow") - Table.add(self,self.top_arrow) #,hexpand=1,vexpand=1) #,1,0) - - self.options = Table(cls=self.cls+".options") - self.options.connect(BLUR,self._close,None) - self.options.name = "pulldown-table" - - self.values = [] - self.value = value - - def resize(self,width=None,height=None): - max_w,max_h = 0,0 - for w in self.options.widgets: - w.rect.w,w.rect.h = w.resize() - max_w,max_h = max(max_w,w.rect.w),max(max_h,w.rect.h) - - #xt,xr,xb,xl = self.top_selected.getspacing() - self.top_selected.style.width = max_w #+ xl + xr - self.top_selected.style.height = max_h #+ xt + xb - - self.top_arrow.connect(CLICK,self._open,None) - self.top_selected.connect(CLICK,self._open,None) - - w,h = Table.resize(self,width,height) - - self.options.style.width = w - #HACK: sort of, but not a big one.. - self.options.resize() - - return w,h - - def _open(self,value): - opts = self.options - - opts.rect.w, opts.rect.h = opts.resize() - -# y = self.rect.y -# c = self.container -# while hasattr(c, 'container'): -# y += c.rect.y -# if (not c.container): -# break -# c = c.container - -# if y + self.rect.h + opts.rect.h <= c.rect.h: #down -# dy = self.rect.y + self.rect.h -# else: #up -# dy = self.rect.y - self.rect.h - - opts.rect.w, opts.rect.h = opts.resize() - - # TODO - make sure there is enough space to open down - # ... - yp = self.rect.bottom-1 - - self.container.open(opts, self.rect.x, yp) - self.firstOption.focus() - - # TODO - this is a hack - for opt in self.options.widgets: - opt.repaint() - - def _close(self,value): - self.options.close() - self.top_selected.focus() - - def _setvalue(self,value): - self.value = value._value - if hasattr(self,'container'): - #self.chsize() - #HACK: improper use of resize() - #self.resize() #to recenter the new value, etc. - pass - # #self._resize() - - self._close(None) - #self.repaint() #this will happen anyways - - - - def __setattr__(self,k,v): - mywidget = None - if k == 'value': - for w in self.values: - if w._value == v: - mywidget = w - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - if k == 'value': - if not mywidget: - mywidget = Label(" ",cls=self.cls+".option.label") - self.top_selected.value = mywidget - - def add(self,w,value=None): - """Add a widget, value item to the Select. - -
Select.add(widget,value=None)
- -
-
widget
Widget or string to represent the item -
value
value for this item -
- - Example - - w = Select() - w.add("Goat") #adds a Label - w.add("Goat","goat") #adds a Label with the value goat - w.add(gui.Label("Cuzco"),"goat") #adds a Label with value goat - - """ - - if type(w) == str: w = Label(w,cls=self.cls+".option.label") - - w.style.align = -1 - btn = Button(w,cls=self.cls+".option") - btn.connect(CLICK,self._setvalue,w) - - self.options.tr() - self.options.add(btn) - - if (not self.firstOption): - self.firstOption = btn - - if value != None: w._value = value - else: w._value = w - if self.value == w._value: - self.top_selected.value = w - self.values.append(w) diff --git a/src/pgu/gui/slider.py b/src/pgu/gui/slider.py deleted file mode 100644 index f4fa623..0000000 --- a/src/pgu/gui/slider.py +++ /dev/null @@ -1,279 +0,0 @@ -"""All sliders and scroll bar widgets have the same parameters. - -
Slider(value,min,max,size)
-
-
value
initial value -
min
minimum value -
max
maximum value -
size
size of bar in pixels -
-""" -import pygame -from pygame.locals import * - -from const import * -import widget -import table -import basic -import pguglobals - -_SLIDER_HORIZONTAL = 0 -_SLIDER_VERTICAL = 1 - -class _slider(widget.Widget): - def __init__(self,value,orient,min,max,size,step=1,**params): - params.setdefault('cls','slider') - widget.Widget.__init__(self,**params) - self.min,self.max,self.value,self.orient,self.size,self.step = min,max,value,orient,size,step - - - def paint(self,s): - - self.value = self.value - r = pygame.rect.Rect(0,0,self.style.width,self.style.height) - if self.orient == _SLIDER_HORIZONTAL: - r.x = (self.value-self.min) * (r.w-self.size) / max(1,self.max-self.min); - r.w = self.size; - else: - r.y = (self.value-self.min) * (r.h-self.size) / max(1,self.max-self.min); - r.h = self.size; - - self.bar = r - - pguglobals.app.theme.render(s,self.style.bar,r) - - def event(self,e): - used = None - r = pygame.rect.Rect(0,0,self.style.width,self.style.height) - adj = 0 - if e.type == ENTER: self.repaint() - elif e.type == EXIT: self.repaint() - elif e.type == MOUSEBUTTONDOWN: - if self.bar.collidepoint(e.pos): - self.grab = e.pos[0],e.pos[1] - self.grab_value = self.value - else: - x,y,adj = e.pos[0],e.pos[1],1 - self.grab = None - self.repaint() - elif e.type == MOUSEBUTTONUP: - #x,y,adj = e.pos[0],e.pos[1],1 - self.repaint() - elif e.type == MOUSEMOTION: - if 1 in e.buttons and self.container.myfocus is self: - if self.grab != None: - rel = e.pos[0]-self.grab[0],e.pos[1]-self.grab[1] - if self.orient == _SLIDER_HORIZONTAL: - d = (r.w - self.size) - if d != 0: self.value = self.grab_value + ((self.max-self.min) * rel[0] / d) - else: - d = (r.h - self.size) - if d != 0: self.value = self.grab_value + ((self.max-self.min) * rel[1] / d) - else: - x,y,adj = e.pos[0],e.pos[1],1 - - elif e.type is KEYDOWN: - if self.orient == _SLIDER_HORIZONTAL and e.key == K_LEFT: - self.value -= self.step - used = True - elif self.orient == _SLIDER_HORIZONTAL and e.key == K_RIGHT: - self.value += self.step - used = True - elif self.orient == _SLIDER_VERTICAL and e.key == K_UP: - self.value -= self.step - used = True - elif self.orient == _SLIDER_VERTICAL and e.key == K_DOWN: - self.value += self.step - used = True - - if adj: - if self.orient == _SLIDER_HORIZONTAL: - d = self.size/2 - (r.w/(self.max-self.min+1))/2 - self.value = (x-d) * (self.max-self.min) / (r.w-self.size+1) + self.min - else: - d = self.size/2 - (r.h/(self.max-self.min+1))/2 - self.value = (y-d) * (self.max-self.min) / (r.h-self.size+1) + self.min - - self.pcls = "" - if self.container.myhover is self: self.pcls = "hover" - if (self.container.myfocus is self and 1 in pygame.mouse.get_pressed()): self.pcls = "down" - - return used - - - def __setattr__(self,k,v): - if k == 'value': - v = int(v) - v = max(v,self.min) - v = min(v,self.max) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - - if hasattr(self,'size'): - sz = min(self.size,max(self.style.width,self.style.height)) - sz = max(sz,min(self.style.width,self.style.height)) - self.__dict__['size'] = sz - - if hasattr(self,'max') and hasattr(self,'min'): - if self.max < self.min: self.max = self.min - -class VSlider(_slider): - """A verticle slider. - -
VSlider(value,min,max,size)
- """ - def __init__(self,value,min,max,size,step=1,**params): - params.setdefault('cls','vslider') - _slider.__init__(self,value,_SLIDER_VERTICAL,min,max,size,step,**params) - -class HSlider(_slider): - """A horizontal slider. - -
HSlider(value,min,max,size)
- """ - def __init__(self,value,min,max,size,step=1,**params): - params.setdefault('cls','hslider') - _slider.__init__(self,value,_SLIDER_HORIZONTAL,min,max,size,step,**params) - -class HScrollBar(table.Table): - """A horizontal scroll bar. - -
HScrollBar(value,min,max,size,step=1)
- """ - def __init__(self,value,min,max,size,step=1,**params): - params.setdefault('cls','hscrollbar') - - table.Table.__init__(self,**params) - - self.slider = _slider(value,_SLIDER_HORIZONTAL,min,max,size,step=step,cls=self.cls+'.slider') - - self.minus = basic.Image(self.style.minus) - self.minus.connect(MOUSEBUTTONDOWN,self._click,-1) - self.slider.connect(CHANGE,self.send,CHANGE) - - self.minus2 = basic.Image(self.style.minus) - self.minus2.connect(MOUSEBUTTONDOWN,self._click,-1) - - self.plus = basic.Image(self.style.plus) - self.plus.connect(MOUSEBUTTONDOWN,self._click,1) - - self.size = size - - def _click(self,value): - self.slider.value += self.slider.step*value - - def resize(self,width=None,height=None): - self.clear() - self.tr() - - w = self.style.width - h = self.slider.style.height - ww = 0 - - if w > (h*2 + self.minus.style.width+self.plus.style.width): - self.td(self.minus) - ww += self.minus.style.width - - self.td(self.slider) - - if w > (h*2 + self.minus.style.width+self.minus2.style.width+self.plus.style.width): - self.td(self.minus2) - ww += self.minus2.style.width - - if w > (h*2 + self.minus.style.width+self.plus.style.width): - self.td(self.plus) - ww += self.plus.style.width - - - #HACK: handle theme sizing properly - xt,xr,xb,xl = pguglobals.app.theme.getspacing(self.slider) - ww += xr+xl - - self.slider.style.width = self.style.width - ww - setattr(self.slider,'size',self.size * self.slider.style.width / max(1,self.style.width)) - return table.Table.resize(self,width,height) - - - def __setattr__(self,k,v): - if k in ('min','max','value','step'): - return setattr(self.slider,k,v) - self.__dict__[k]=v - - def __getattr__(self,k): - if k in ('min','max','value','step'): - return getattr(self.slider,k) - return table.Table.__getattr__(self,k) #self.__dict__[k] - -class VScrollBar(table.Table): - """A vertical scroll bar. - -
VScrollBar(value,min,max,size,step=1)
- """ - def __init__(self,value,min,max,size,step=1,**params): - params.setdefault('cls','vscrollbar') - - table.Table.__init__(self,**params) - - self.minus = basic.Image(self.style.minus) - self.minus.connect(MOUSEBUTTONDOWN,self._click,-1) - - self.minus2 = basic.Image(self.style.minus) - self.minus2.connect(MOUSEBUTTONDOWN,self._click,-1) - - self.plus = basic.Image(self.style.plus) - self.plus.connect(MOUSEBUTTONDOWN,self._click,1) - - self.slider = _slider(value,_SLIDER_VERTICAL,min,max,size,step=step,cls=self.cls+'.slider') - self.slider.connect(CHANGE,self.send,CHANGE) - - self.size = size - - def _click(self,value): - self.slider.value += self.slider.step*value - - def resize(self,width=None,height=None): - self.clear() - - h = self.style.height - w = self.slider.style.width - hh = 0 - - if h > (w*2 + self.minus.style.height+self.plus.style.height): - self.tr() - self.td(self.minus) - hh += self.minus.style.height - - self.tr() - self.td(self.slider) - - if h > (w*2 + self.minus.style.height+self.minus2.style.height+self.plus.style.height): - self.tr() - self.td(self.minus2) - hh += self.minus2.style.height - - if h > (w*2 + self.minus.style.height+self.plus.style.height): - self.tr() - self.td(self.plus) - hh += self.plus.style.height - - - #HACK: handle theme sizing properly - xt,xr,xb,xl = pguglobals.app.theme.getspacing(self.slider) - hh += xt+xb - - self.slider.style.height = self.style.height - hh - setattr(self.slider,'size',self.size * self.slider.style.height / max(1,self.style.height)) - return table.Table.resize(self,width,height) - - def __setattr__(self,k,v): - if k in ('min','max','value','step'): - return setattr(self.slider,k,v) - self.__dict__[k]=v - - def __getattr__(self,k): - if k in ('min','max','value','step'): - return getattr(self.slider,k) - return table.Table.__getattr__(self,k) diff --git a/src/pgu/gui/style.py b/src/pgu/gui/style.py deleted file mode 100644 index 3060928..0000000 --- a/src/pgu/gui/style.py +++ /dev/null @@ -1,41 +0,0 @@ -""" -""" - -import pguglobals - -class Style: - """The class used by widget for the widget.style - -

This object is used mainly as a dictionary, accessed via widget.style.attr, as opposed to - widget.style['attr']. It automatically grabs information from the theme via value = theme.get(widget.cls,widget.pcls,attr).

- - """ - def __init__(self,o,dict): - self.obj = o - for k,v in dict.items(): self.__dict__[k]=v - self._cache = {} - - def __getattr__(self,k): - key = self.obj.cls,self.obj.pcls,k - if key not in self._cache: - self._cache[key] = Style_get(self.obj.cls,self.obj.pcls,k) - v = self._cache[key] - if k in ( - 'border_top','border_right','border_bottom','border_left', - 'padding_top','padding_right','padding_bottom','padding_left', - 'margin_top','margin_right','margin_bottom','margin_left', - 'align','valign','width','height', - ): self.__dict__[k] = v - return v - - def __setattr__(self,k,v): - self.__dict__[k] = v - - -Style_cache = {} -def Style_get(cls,pcls,k): - key = cls,pcls,k - if key not in Style_cache: - Style_cache[key] = pguglobals.app.theme.get(cls,pcls,k) - return Style_cache[key] - diff --git a/src/pgu/gui/surface.py b/src/pgu/gui/surface.py deleted file mode 100644 index 9bd064d..0000000 --- a/src/pgu/gui/surface.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -""" -import pygame - -def subsurface(s,r): - """Return the subsurface of a surface, with some help, checks. - -
subsurface(s,r): return surface
- """ - r = pygame.Rect(r) - if r.x < 0 or r.y < 0: - raise "gui.subsurface: %d %d %s"%(s.get_width(),s.get_height(),r) - w,h = s.get_width(),s.get_height() - if r.right > w: - r.w -= r.right-w - if r.bottom > h: - r.h -= r.bottom-h - assert(r.w >= 0 and r.h >= 0) - return s.subsurface(r) - -class ProxySurface: - """ - A surface-like object which smartly handle out-of-area blitting. - -
ProxySurface(parent, rect, real_surface=None, offset=(0, 0))
- -

only one of parent and real_surface should be supplied (non None)

-
-
parent
a ProxySurface object -
real_surface
a pygame Surface object -
- - Variables - -
-
mysubsurface
a real and valid pygame.Surface object to be used - for blitting. -
x, y
if the proxy surface is lefter or higher than the parent, - x, y hold the diffs. -
offset
an optional feature which let you scroll the whole blitted - content. -
- """ - def __init__(self, parent, rect, real_surface, offset=(0, 0)): - self.offset = offset - self.x = self.y = 0 - if rect.x < 0: self.x = rect.x - if rect.y < 0: self.y = rect.y - self.real_surface = real_surface - if real_surface == None: - self.mysubsurface = parent.mysubsurface.subsurface( - parent.mysubsurface.get_rect().clip(rect)) - else: - self.mysubsurface = real_surface.subsurface( - real_surface.get_rect().clip(rect)) - rect.topleft = (0, 0) - self.rect = rect - - def blit(self, s, pos, rect=None): - if rect == None: rect = s.get_rect() - pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y) - self.mysubsurface.blit(s, pos, rect) - - def subsurface(self, rect): - r = pygame.Rect(rect).move(self.offset[0] + self.x, - self.offset[1] + self.y) - return ProxySurface(self, r, self.real_surface) - - def fill(self, color, rect=None): - if rect != None: self.mysubsurface.fill(color, rect) - else: self.mysubsurface.fill(color) - def get_rect(self): return self.rect - def get_width(self): return self.rect[2] - def get_height(self): return self.rect[3] - def get_abs_offset(): return self.rect[:2] - def get_abs_parent(): return self.mysubsurface.get_abs_parent() - def set_clip(self, rect=None): - if rect == None: self.mysubsurface.set_clip() - else: - rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]] - self.mysubsurface.set_clip(rect) - - - - - - -class xProxySurface: - """ - A surface-like object which smartly handle out-of-area blitting. - -
ProxySurface(parent, rect, real_surface=None, offset=(0, 0))
- -

only one of parent and real_surface should be supplied (non None)

-
-
parent
a ProxySurface object -
real_surface
a pygame Surface object -
- - Variables - -
-
mysubsurface
a real and valid pygame.Surface object to be used - for blitting. -
x, y
if the proxy surface is lefter or higher than the parent, - x, y hold the diffs. -
offset
an optional feature which let you scroll the whole blitted - content. -
- """ - def __init__(self, parent, rect, real_surface, offset=(0, 0)): - self.offset = offset - self.x = self.y = 0 - if rect[0] < 0: self.x = rect[0] - if rect[1] < 0: self.y = rect[1] - self.real_surface = real_surface - if real_surface == None: - self.mysubsurface = parent.mysubsurface.subsurface(parent.mysubsurface.get_rect().clip(rect)) - else: - self.mysubsurface = real_surface.subsurface(real_surface.get_rect().clip(rect)) - rect[0], rect[1] = 0, 0 - self.rect = rect - - def blit(self, s, pos, rect=None): - if rect == None: rect = s.get_rect() - pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y) - self.mysubsurface.blit(s, pos, rect) - - def subsurface(self, rect): return ProxySurface(self, pygame.Rect(rect).move(self.offset[0] + self.x, self.offset[1] + self.y),self.real_surface) - def fill(self, color, rect=None): - if rect != None: self.mysubsurface.fill(color, rect) - else: self.mysubsurface.fill(color) - def get_rect(self): return self.rect - def get_width(self): return self.rect[2] - def get_height(self): return self.rect[3] - def get_abs_offset(): return self.rect[:2] - def get_abs_parent(): return self.mysubsurface.get_abs_parent() - def set_clip(self, rect=None): - if rect == None: self.mysubsurface.set_clip() - else: - rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]] - self.mysubsurface.set_clip(rect) - diff --git a/src/pgu/gui/table.py b/src/pgu/gui/table.py deleted file mode 100644 index 6ff6c74..0000000 --- a/src/pgu/gui/table.py +++ /dev/null @@ -1,331 +0,0 @@ -""" -""" -from const import * -import container - -class Table(container.Container): - """A table style container. - -

If you know HTML, this should all work roughly how you would expect. If you are not - familiar with HTML, please read Tables in HTML Documents. Pay attention to TABLE, TR, TD related parts of the document.

- -
Table()
- - Example - - t = gui.Table() - - t.tr() - t.td(gui.Label("First Name"), align=-1) - t.td(gui.Input()) - - t.tr() - t.td(gui.Label("Last Name"), align=-1) - t.td(gui.Input()) - - - """ - - - def __init__(self, **params): - params.setdefault('cls','table') - container.Container.__init__(self, **params) - self._rows = [] - self._curRow = 0 - self._trok = False - - def getRows(self): - return len(self._rows) - - def getColumns(self): - if self._rows: - return len(self._rows[0]) - else: - return 0 - - def remove_row(self, n): #NOTE: won't work in all cases. - if n >= self.getRows(): - print "Trying to remove a nonexistant row:", n, "there are only", self.getRows(), "rows" - return - - for cell in self._rows[n]: - if isinstance(cell, dict) and cell["widget"] in self.widgets: - #print 'removing widget' - self.widgets.remove(cell["widget"]) - del self._rows[n] - #print "got here" - - for w in self.widgets: - if w.style.row > n: w.style.row -= 1 - - if self._curRow >= n: - self._curRow -= 1 - - #self.rect.w, self.rect.h = self.resize() - #self.repaint() - - self.chsize() - - def clear(self): - self._rows = [] - self._curRow = 0 - self._trok = False - - self.widgets = [] - - self.chsize() - - #print 'clear',self,self._rows - - def _addRow(self): - self._rows.append([None for x in xrange(self.getColumns())]) - - def tr(self): - """Start on the next row.""" - if not self._trok: - self._trok = True - return - self._curRow += 1 - if self.getRows() <= self._curRow: - self._addRow() - - def _addColumn(self): - if not self._rows: - self._addRow() - for row in self._rows: - row.append(None) - - def _setCell(self, w, col, row, colspan=1, rowspan=1): - #make room for the widget by adding columns and rows - while self.getColumns() < col + colspan: - self._addColumn() - while self.getRows() < row + rowspan: - self._addRow() - - #print w.__class__.__name__,col,row,colspan,rowspan - - #actual widget setting and modification stuff - w.container = self - w.style.row = row #HACK - to work with gal's list - w.style.col = col #HACK - to work with gal's list - self._rows[row][col] = {"widget":w, "colspan":colspan, "rowspan":rowspan} - self.widgets.append(self._rows[row][col]["widget"]) - - #set the spanned columns - #for acell in xrange(col + 1, col + colspan): - # self._rows[row][acell] = True - - #set the spanned rows and the columns on them - #for arow in xrange(row + 1, row + rowspan): - # for acell in xrange(col, col + colspan): #incorrect? - # self._rows[arow][acell] = True - - for arow in xrange(row, row + rowspan): - for acell in xrange(col, col + colspan): #incorrect? - if row != arow or col != acell: - self._rows[arow][acell] = True - - - def td(self, w, col=None, row=None, colspan=1, rowspan=1, **params): - """Add a widget to a table after wrapping it in a TD container. - -
Table.td(w,col=None,row=None,colspan=1,rowspan=1,**params)
- -
-
w
widget -
col
column -
row
row -
colspan
colspan -
rowspan
rowspan -
align
horizontal alignment (-1,0,1) -
valign
vertical alignment (-1,0,1) -
params
other params for the TD container, style information, etc -
- """ - - Table.add(self,_Table_td(w, **params), col=col, row=row, colspan=colspan, rowspan=rowspan) - - def add(self, w, col=None, row=None, colspan=1, rowspan=1): - """Add a widget directly into the table, without wrapping it in a TD container. - -
Table.add(w,col=None,row=None,colspan=1,rowspan=1)
- -

See Table.td for an explanation of the parameters.

- """ - self._trok = True - #if no row was specifically specified, set it to the current row - if row is None: - row = self._curRow - #print row - - #if its going to be a new row, have it be on the first column - if row >= self.getRows(): - col = 0 - - #try to find an open cell for the widget - if col is None: - for cell in xrange(self.getColumns()): - if col is None and not self._rows[row][cell]: - col = cell - break - - #otherwise put the widget in a new column - if col is None: - col = self.getColumns() - - self._setCell(w, col, row, colspan=colspan, rowspan=rowspan) - - self.chsize() - return - - def remove(self,w): - if hasattr(w,'_table_td'): w = w._table_td - row,col = w.style.row,w.style.col - cell = self._rows[row][col] - colspan,rowspan = cell['colspan'],cell['rowspan'] - - for arow in xrange(row , row + rowspan): - for acell in xrange(col, col + colspan): #incorrect? - self._rows[arow][acell] = False - self.widgets.remove(w) - self.chsize() - - - - def resize(self, width=None, height=None): - #if 1 or self.getRows() == 82: - #print '' - #print 'resize',self.getRows(),self.getColumns(),width,height - #import inspect - #for obj,fname,line,fnc,code,n in inspect.stack()[9:20]: - # print fname,line,':',fnc,code[0].strip() - - - #resize the widgets to their smallest size - for w in self.widgets: - w.rect.w, w.rect.h = w.resize() - - #calculate row heights and column widths - rowsizes = [0 for y in xrange(self.getRows())] - columnsizes = [0 for x in xrange(self.getColumns())] - for row in xrange(self.getRows()): - for cell in xrange(self.getColumns()): - if self._rows[row][cell] and self._rows[row][cell] is not True: - if not self._rows[row][cell]["colspan"] > 1: - columnsizes[cell] = max(columnsizes[cell], self._rows[row][cell]["widget"].rect.w) - if not self._rows[row][cell]["rowspan"] > 1: - rowsizes[row] = max(rowsizes[row], self._rows[row][cell]["widget"].rect.h) - - #distribute extra space if necessary for wide colspanning/rowspanning - for row in xrange(self.getRows()): - for cell in xrange(self.getColumns()): - if self._rows[row][cell] and self._rows[row][cell] is not True: - if self._rows[row][cell]["colspan"] > 1: - columns = xrange(cell, cell + self._rows[row][cell]["colspan"]) - totalwidth = 0 - for acol in columns: - totalwidth += columnsizes[acol] - if totalwidth < self._rows[row][cell]["widget"].rect.w: - for acol in columns: - columnsizes[acol] += _table_div(self._rows[row][cell]["widget"].rect.w - totalwidth, self._rows[row][cell]["colspan"],acol) - if self._rows[row][cell]["rowspan"] > 1: - rows = xrange(row, row + self._rows[row][cell]["rowspan"]) - totalheight = 0 - for arow in rows: - totalheight += rowsizes[arow] - if totalheight < self._rows[row][cell]["widget"].rect.h: - for arow in rows: - rowsizes[arow] += _table_div(self._rows[row][cell]["widget"].rect.h - totalheight, self._rows[row][cell]["rowspan"],arow) - - #make everything fill out to self.style.width, self.style.heigh, not exact, but pretty close... - w, h = sum(columnsizes), sum(rowsizes) - if w > 0 and w < self.style.width and len(columnsizes): - d = (self.style.width - w) - for n in xrange(0, len(columnsizes)): - v = columnsizes[n] - columnsizes[n] += v * d / w - if h > 0 and h < self.style.height and len(rowsizes): - d = (self.style.height - h) / len(rowsizes) - for n in xrange(0, len(rowsizes)): - v = rowsizes[n] - rowsizes[n] += v * d / h - - #set the widget's position by calculating their row/column x/y offset - cellpositions = [[[sum(columnsizes[0:cell]), sum(rowsizes[0:row])] for cell in xrange(self.getColumns())] for row in xrange(self.getRows())] - for row in xrange(self.getRows()): - for cell in xrange(self.getColumns()): - if self._rows[row][cell] and self._rows[row][cell] is not True: - x, y = cellpositions[row][cell] - w = sum(columnsizes[cell:cell+self._rows[row][cell]["colspan"]]) - h = sum(rowsizes[row:row+self._rows[row][cell]["rowspan"]]) - - widget = self._rows[row][cell]["widget"] - widget.rect.x = x - widget.rect.y = y - if 1 and (w,h) != (widget.rect.w,widget.rect.h): -# if h > 20: -# print widget.widget.__class__.__name__, (widget.rect.w,widget.rect.h),'=>',(w,h) - widget.rect.w, widget.rect.h = widget.resize(w, h) - - #print self._rows[row][cell]["widget"].rect - - #print columnsizes - #print sum(columnsizes) - #size = sum(columnsizes), sum(rowsizes); print size - - #return the tables final size - return sum(columnsizes),sum(rowsizes) - - -def _table_div(a,b,c): - v,r = a/b, a%b - if r != 0 and (c%b) self.style.width) or (self.style.height!=0 and w.rect.h > self.style.height): -# ww,hh = None,None -# if self.style.width: ww = self.style.width -# if self.style.height: hh = self.style.height -# w.rect.w,w.rect.h = w.resize(ww,hh) - - - #in the case that the widget is too big, we try to resize it - if (width != None and width < w.rect.w) or (height != None and height < w.rect.h): - w.rect.w,w.rect.h = w.resize(width,height) - - width = max(width,w.rect.w,self.style.width) #,self.style.cell_width) - height = max(height,w.rect.h,self.style.height) #,self.style.cell_height) - - dx = width-w.rect.w - dy = height-w.rect.h - w.rect.x = (self.style.align+1)*dx/2 - w.rect.y = (self.style.valign+1)*dy/2 - - return width,height diff --git a/src/pgu/gui/textarea.py b/src/pgu/gui/textarea.py deleted file mode 100644 index 667076a..0000000 --- a/src/pgu/gui/textarea.py +++ /dev/null @@ -1,287 +0,0 @@ -""" -""" -import pygame -from pygame.locals import * - -from const import * -import widget - -class TextArea(widget.Widget): - """A multi-line text input. - -
TextArea(value="",width = 120, height = 30, size=20)
- -
-
value
initial text -
size
size for the text box, in characters -
- - Example - - w = TextArea(value="Cuzco the Goat",size=20) - - w = TextArea("Marbles") - - w = TextArea("Groucho\nHarpo\nChico\nGummo\nZeppo\n\nMarx", 200, 400, 12) - - - """ - def __init__(self,value="",width = 120, height = 30, size=20,**params): - params.setdefault('cls','input') - params.setdefault('width', width) - params.setdefault('height', height) - - widget.Widget.__init__(self,**params) - self.value = value # The value of the TextArea - self.pos = len(str(value)) # The position of the cursor - self.vscroll = 0 # The number of lines that the TextArea is currently scrolled - self.font = self.style.font # The font used for rendering the text - self.cursor_w = 2 # Cursor width (NOTE: should be in a style) - w,h = self.font.size("e"*size) - if not self.style.height: self.style.height = h - if not self.style.width: self.style.width = w - - def resize(self,width=None,height=None): - if (width != None) and (height != None): - self.rect = pygame.Rect(self.rect.x, self.rect.y, width, height) - return self.rect.w, self.rect.h - - def paint(self,s): - - # TODO: What's up with this 20 magic number? It's the margin of the left and right sides, but I'm not sure how this should be gotten other than by trial and error. - max_line_w = self.rect.w - 20 - - # Update the line allocation for the box's value - self.doLines(max_line_w) - - # Make sure that the vpos and hpos of the cursor is set properly - self.updateCursorPos() - - # Make sure that we're scrolled vertically such that the cursor is visible - if (self.vscroll < 0): - self.vscroll = 0 - if (self.vpos < self.vscroll): - self.vscroll = self.vpos - elif ((self.vpos - self.vscroll + 1) * self.line_h > self.rect.h): - self.vscroll = - (self.rect.h / self.line_h - self.vpos - 1) - - # Blit each of the lines in turn - cnt = 0 - for line in self.lines: - line_pos = (0, (cnt - self.vscroll) * self.line_h) - if (line_pos[1] >= 0) and (line_pos[1] < self.rect.h): - s.blit( self.font.render(line, 1, self.style.color), line_pos ) - cnt += 1 - - # If the textarea is focused, then also show the cursor - if self.container.myfocus is self: - r = self.getCursorRect() - s.fill(self.style.color,r) - - # This function updates self.vpos and self.hpos based on self.pos - def updateCursorPos(self): - self.vpos = 0 # Reset the current line that the cursor is on - self.hpos = 0 - - line_cnt = 0 - char_cnt = 0 - - for line in self.lines: - line_char_start = char_cnt # The number of characters at the start of the line - - # Keep track of the character count for words - char_cnt += len(line) - - # If our cursor count is still less than the cursor position, then we can update our cursor line to assume that it's at least on this line - if (char_cnt > self.pos): - self.vpos = line_cnt - self.hpos = self.pos - line_char_start - - break # Now that we know where our cursor is, we exit the loop - - line_cnt += 1 - - if (char_cnt <= self.pos) and (len(self.lines) > 0): - self.vpos = len(self.lines) - 1 - self.hpos = len(self.lines[ self.vpos ] ) - - # Returns a rectangle that is of the size and position of where the cursor is drawn - def getCursorRect(self): - lw = 0 - if (len(self.lines) > 0): - lw, lh = self.font.size( self.lines[ self.vpos ][ 0:self.hpos ] ) - - r = pygame.Rect(lw, (self.vpos - self.vscroll) * self.line_h, self.cursor_w, self.line_h) - return r - - # This function sets the cursor position according to an x/y value (such as by from a mouse click) - def setCursorByXY(self, (x, y)): - self.vpos = ((int) (y / self.line_h)) + self.vscroll - if (self.vpos >= len(self.lines)): - self.vpos = len(self.lines) - 1 - - currentLine = self.lines[ self.vpos ] - - for cnt in range(0, len(currentLine) ): - self.hpos = cnt - lw, lh = self.font.size( currentLine[ 0:self.hpos + 1 ] ) - if (lw > x): - break - - lw, lh = self.font.size( currentLine ) - if (lw < x): - self.hpos = len(currentLine) - - self.setCursorByHVPos() - - # This function sets the cursor position by the horizontal/vertical cursor position. - def setCursorByHVPos(self): - line_cnt = 0 - char_cnt = 0 - - for line in self.lines: - line_char_start = char_cnt # The number of characters at the start of the line - - # Keep track of the character count for words - char_cnt += len(line) - - # If we're on the proper line - if (line_cnt == self.vpos): - # Make sure that we're not trying to go over the edge of the current line - if ( self.hpos >= len(line) ): - self.hpos = len(line) - 1 - # Set the cursor position - self.pos = line_char_start + self.hpos - break # Now that we've set our cursor position, we exit the loop - - line_cnt += 1 - - # Splits up the text found in the control's value, and assigns it into the lines array - def doLines(self, max_line_w): - self.line_h = 10 - self.lines = [] # Create an empty starter list to start things out. - - inx = 0 - line_start = 0 - while inx >= 0: - # Find the next breakable whitespace - # HACK: Find a better way to do this to include tabs and system characters and whatnot. - prev_word_start = inx # Store the previous whitespace - spc_inx = self.value.find(' ', inx+1) - nl_inx = self.value.find('\n', inx+1) - - if (min(spc_inx, nl_inx) == -1): - inx = max(spc_inx, nl_inx) - else: - inx = min(spc_inx, nl_inx) - - # Measure the current line - lw, self.line_h = self.font.size( self.value[ line_start : inx ] ) - - # If we exceeded the max line width, then create a new line - if (lw > max_line_w): - #Fall back to the previous word start - self.lines.append(self.value[ line_start : prev_word_start + 1 ]) - line_start = prev_word_start + 1 - # TODO: Check for extra-long words here that exceed the length of a line, to wrap mid-word - - # If we reached the end of our text - if (inx < 0): - # Then make sure we added the last of the line - if (line_start < len( self.value ) ): - self.lines.append( self.value[ line_start : len( self.value ) ] ) - # If we reached a hard line break - elif (self.value[inx] == "\n"): - # Then make a line break here as well. - newline = self.value[ line_start : inx + 1 ] - newline = newline.replace("\n", " ") # HACK: We know we have a newline character, which doesn't print nicely, so make it into a space. Comment this out to see what I mean. - self.lines.append( newline ) - - line_start = inx + 1 - else: - # Otherwise, we just continue progressing to the next space - pass - - def _setvalue(self,v): - self.__dict__['value'] = v - self.send(CHANGE) - - def event(self,e): - used = None - if e.type == KEYDOWN: - if e.key == K_BACKSPACE: - if self.pos: - self._setvalue(self.value[:self.pos-1] + self.value[self.pos:]) - self.pos -= 1 - elif e.key == K_DELETE: - if len(self.value) > self.pos: - self._setvalue(self.value[:self.pos] + self.value[self.pos+1:]) - elif e.key == K_HOME: - # Find the previous newline - newPos = self.value.rfind('\n', 0, self.pos) - if (newPos >= 0): - self.pos = newPos - elif e.key == K_END: - # Find the previous newline - newPos = self.value.find('\n', self.pos, len(self.value) ) - if (newPos >= 0): - self.pos = newPos - elif e.key == K_LEFT: - if self.pos > 0: self.pos -= 1 - used = True - elif e.key == K_RIGHT: - if self.pos < len(self.value): self.pos += 1 - used = True - elif e.key == K_UP: - self.vpos -= 1 - self.setCursorByHVPos() - elif e.key == K_DOWN: - self.vpos += 1 - self.setCursorByHVPos() - # The following return/tab keys are standard for PGU widgets, but I took them out here to facilitate multi-line text editing -# elif e.key == K_RETURN: -# self.next() -# elif e.key == K_TAB: -# pass - else: - #c = str(e.unicode) - try: - if (e.key == K_RETURN): - c = "\n" - elif (e.key == K_TAB): - c = " " - else: - c = (e.unicode).encode('latin-1') - if c: - self._setvalue(self.value[:self.pos] + c + self.value[self.pos:]) - self.pos += len(c) - except: #ignore weird characters - pass - self.repaint() - elif e.type == MOUSEBUTTONDOWN: - self.setCursorByXY(e.pos) - self.repaint() - - elif e.type == FOCUS: - self.repaint() - elif e.type == BLUR: - self.repaint() - - self.pcls = "" - if self.container.myfocus is self: self.pcls = "focus" - - return used - - def __setattr__(self,k,v): - if k == 'value': - if v == None: v = '' - v = str(v) - self.pos = len(v) - _v = self.__dict__.get(k,NOATTR) - self.__dict__[k]=v - if k == 'value' and _v != NOATTR and _v != v: - self.send(CHANGE) - self.repaint() - -# The first version of this code was done by Clint Herron, and is a modified version of input.py (by Phil Hassey). -# It is under the same license as the rest of the PGU library. \ No newline at end of file diff --git a/src/pgu/gui/theme.py b/src/pgu/gui/theme.py deleted file mode 100644 index 283c287..0000000 --- a/src/pgu/gui/theme.py +++ /dev/null @@ -1,485 +0,0 @@ -# theme.py - -""" -""" -import os, re -import pygame - -from const import * -import widget -import surface -from basic import parse_color, is_color - -__file__ = os.path.abspath(__file__) - -def _list_themes(dir): - d = {} - for entry in os.listdir(dir): - if os.path.exists(os.path.join(dir, entry, 'config.txt')): - d[entry] = os.path.join(dir, entry) - return d - -class Theme: - """Theme interface. - -

If you wish to create your own theme, create a class with this interface, and - pass it to gui.App via gui.App(theme=MyTheme()).

- - Default Theme - -
Theme(dirs='default')
-
-
dirs
Name of the theme dir to load a theme from. May be an absolute path to a theme, if pgu is not installed, or if you created your own theme. May include several dirs in a list if data is spread across several themes. -
- - Example - - - theme = gui.Theme("default") - theme = gui.Theme(["mytheme","mytheme2"]) - - """ - def __init__(self,dirs='default'): - self.config = {} - self.dict = {} - self._loaded = [] - self.cache = {} - self._preload(dirs) - pygame.font.init() - - def _preload(self,ds): - if not isinstance(ds, list): - ds = [ds] - for d in ds: - if d not in self._loaded: - self._load(d) - self._loaded.append(d) - - def _load(self, name): - #theme_dir = themes[name] - - #try to load the local dir, or absolute path - dnames = [name] - - #if the package isn't installed and people are just - #trying out the scripts or examples - dnames.append(os.path.join(os.path.dirname(__file__),"..","..","data","themes",name)) - - #if the package is installed, and the package is installed - #in /usr/lib/python2.3/site-packages/pgu/ - #or c:\python23\lib\site-packages\pgu\ - #the data is in ... lib/../share/ ... - dnames.append(os.path.join(os.path.dirname(__file__),"..","..","..","..","share","pgu","themes",name)) - dnames.append(os.path.join(os.path.dirname(__file__),"..","..","..","..","..","share","pgu","themes",name)) - dnames.append(os.path.join(os.path.dirname(__file__),"..","..","share","pgu","themes",name)) - for dname in dnames: - if os.path.isdir(dname): break - if not os.path.isdir(dname): - raise 'could not find theme '+name - - fname = os.path.join(dname,"config.txt") - if os.path.isfile(fname): - try: - f = open(fname) - for line in f.readlines(): - vals = line.strip().split() - if len(vals) < 3: continue - cls = vals[0] - del vals[0] - pcls = "" - if cls.find(":")>=0: - cls,pcls = cls.split(":") - attr = vals[0] - del vals[0] - self.config[cls+":"+pcls+" "+attr] = (dname, vals) - finally: - f.close() - fname = os.path.join(dname,"style.ini") - if os.path.isfile(fname): - import ConfigParser - cfg = ConfigParser.ConfigParser() - f = open(fname,'r') - cfg.readfp(f) - for section in cfg.sections(): - cls = section - pcls = '' - if cls.find(":")>=0: - cls,pcls = cls.split(":") - for attr in cfg.options(section): - vals = cfg.get(section,attr).strip().split() - self.config[cls+':'+pcls+' '+attr] = (dname,vals) - - is_image = re.compile('\.(gif|jpg|bmp|png|tga)$', re.I) - def _get(self,key): - if not key in self.config: return - if key in self.dict: return self.dict[key] - dvals = self.config[key] - dname, vals = dvals - #theme_dir = themes[name] - v0 = vals[0] - if v0[0] == '#': - v = parse_color(v0) - #if (len(v0) == 7): - # # Due to a bug in pygame 1.8 (?) we need to explicitly - # # specify the alpha value (otherwise it defaults to zero) - # v0 += "FF" - #v = pygame.color.Color(v0) - elif v0.endswith(".ttf") or v0.endswith(".TTF"): - v = pygame.font.Font(os.path.join(dname, v0),int(vals[1])) - elif self.is_image.search(v0) is not None: - v = pygame.image.load(os.path.join(dname, v0)) - else: - try: v = int(v0) - except: v = pygame.font.SysFont(v0, int(vals[1])) - self.dict[key] = v - return v - - def get(self,cls,pcls,attr): - """Interface method -- get the value of a style attribute. - -
Theme.get(cls,pcls,attr): return value
- -
-
cls
class, for example "checkbox", "button", etc. -
pcls
pseudo class, for example "hover", "down", etc. -
attr
attribute, for example "image", "background", "font", "color", etc. -
- -

returns the value of the attribute.

- -

This method is called from [[gui-style]].

- """ - - if not self._loaded: self._preload("default") - - o = cls+":"+pcls+" "+attr - - #if not hasattr(self,'_count'): - # self._count = {} - #if o not in self._count: self._count[o] = 0 - #self._count[o] += 1 - - if o in self.cache: - return self.cache[o] - - v = self._get(cls+":"+pcls+" "+attr) - if v: - self.cache[o] = v - return v - - pcls = "" - v = self._get(cls+":"+pcls+" "+attr) - if v: - self.cache[o] = v - return v - - cls = "default" - v = self._get(cls+":"+pcls+" "+attr) - if v: - self.cache[o] = v - return v - - v = 0 - self.cache[o] = v - return v - - def box(self,w,s): - style = w.style - - c = (0,0,0) - if style.border_color != 0: c = style.border_color - w,h = s.get_width(),s.get_height() - - s.fill(c,(0,0,w,style.border_top)) - s.fill(c,(0,h-style.border_bottom,w,style.border_bottom)) - s.fill(c,(0,0,style.border_left,h)) - s.fill(c,(w-style.border_right,0,style.border_right,h)) - - - def getspacing(self,w): - # return the top, right, bottom, left spacing around the widget - if not hasattr(w,'_spacing'): #HACK: assume spacing doesn't change re pcls - s = w.style - xt = s.margin_top+s.border_top+s.padding_top - xr = s.padding_right+s.border_right+s.margin_right - xb = s.padding_bottom+s.border_bottom+s.margin_bottom - xl = s.margin_left+s.border_left+s.padding_left - w._spacing = xt,xr,xb,xl - return w._spacing - - - def resize(self,w,m): - # Returns the rectangle expanded in each direction - def expand_rect(rect, left, top, right, bottom): - return pygame.Rect(rect.x - left, - rect.y - top, - rect.w + left + right, - rect.h + top + bottom) - - def func(width=None,height=None): - s = w.style - - pt,pr,pb,pl = s.padding_top,s.padding_right,s.padding_bottom,s.padding_left - bt,br,bb,bl = s.border_top,s.border_right,s.border_bottom,s.border_left - mt,mr,mb,ml = s.margin_top,s.margin_right,s.margin_bottom,s.margin_left - # Calculate the total space on each side - top = pt+bt+mt - right = pr+br+mr - bottom = pb+bb+mb - left = pl+bl+ml - ttw = left+right - tth = top+bottom - - ww,hh = None,None - if width != None: ww = width-ttw - if height != None: hh = height-tth - ww,hh = m(ww,hh) - - if width == None: width = ww - if height == None: height = hh - - #if the widget hasn't respected the style.width, - #style height, we'll add in the space for it... - width = max(width-ttw, ww, w.style.width) - height = max(height-tth, hh, w.style.height) - - #width = max(ww,w.style.width-tw) - #height = max(hh,w.style.height-th) - - r = pygame.Rect(left,top,width,height) - - w._rect_padding = expand_rect(r, pl, pt, pr, pb) - w._rect_border = expand_rect(w._rect_padding, bl, bt, br, bb) - w._rect_margin = expand_rect(w._rect_border, ml, mt, mr, mb) - - #w._rect_padding = pygame.Rect(r.x-pl,r.y-pt,r.w+pl+pr,r.h+pt+pb) - #r = w._rect_padding - #w._rect_border = pygame.Rect(r.x-bl,r.y-bt,r.w+bl+br,r.h+bt+bb) - #r = w._rect_border - #w._rect_margin = pygame.Rect(r.x-ml,r.y-mt,r.w+ml+mr,r.h+mt+mb) - - # align it within it's zone of power. - rect = pygame.Rect(left, top, ww, hh) - dx = width-rect.w - dy = height-rect.h - rect.x += (w.style.align+1)*dx/2 - rect.y += (w.style.valign+1)*dy/2 - - w._rect_content = rect - - return (w._rect_margin.w, w._rect_margin.h) - return func - - - def paint(self,w,m): - def func(s): -# if w.disabled: -# if not hasattr(w,'_disabled_bkgr'): -# w._disabled_bkgr = s.convert() -# orig = s -# s = w._disabled_bkgr.convert() - -# if not hasattr(w,'_theme_paint_bkgr'): -# w._theme_paint_bkgr = s.convert() -# else: -# s.blit(w._theme_paint_bkgr,(0,0)) -# -# if w.disabled: -# orig = s -# s = w._theme_paint_bkgr.convert() - - if w.disabled: - if (not (hasattr(w,'_theme_bkgr') and - w._theme_bkgr.get_width() == s.get_width() and - w._theme_bkgr.get_height() == s.get_height())): - w._theme_bkgr = s.copy() - orig = s - s = w._theme_bkgr - s.fill((0,0,0,0)) - s.blit(orig,(0,0)) - - if hasattr(w,'background'): - w.background.paint(surface.subsurface(s,w._rect_border)) - self.box(w,surface.subsurface(s,w._rect_border)) - r = m(surface.subsurface(s,w._rect_content)) - - if w.disabled: - s.set_alpha(128) - orig.blit(s,(0,0)) - -# if w.disabled: -# orig.blit(w._disabled_bkgr,(0,0)) -# s.set_alpha(128) -# orig.blit(s,(0,0)) - - w._painted = True - return r - return func - - def event(self,w,m): - def func(e): - rect = w._rect_content - if e.type == MOUSEBUTTONUP or e.type == MOUSEBUTTONDOWN: - sub = pygame.event.Event(e.type,{ - 'button':e.button, - 'pos':(e.pos[0]-rect.x,e.pos[1]-rect.y)}) - elif e.type == CLICK: - sub = pygame.event.Event(e.type,{ - 'button':e.button, - 'pos':(e.pos[0]-rect.x,e.pos[1]-rect.y)}) - elif e.type == MOUSEMOTION: - sub = pygame.event.Event(e.type,{ - 'buttons':e.buttons, - 'pos':(e.pos[0]-rect.x,e.pos[1]-rect.y), - 'rel':e.rel}) - else: - sub = e - r = m(sub) - return r - return func - - def update(self,w,m): - def func(s): - if w.disabled: return [] - r = m(surface.subsurface(s,w._rect_content)) - if type(r) == list: - dx,dy = w._rect_content.topleft - for rr in r: - rr.x,rr.y = rr.x+dx,rr.y+dy - return r - return func - - def open(self,w,m): - def func(widget=None,x=None,y=None): - if not hasattr(w,'_rect_content'): w.rect.w,w.rect.h = w.resize() #HACK: so that container.open won't resize again! - rect = w._rect_content - ##print w.__class__.__name__, rect - if x != None: x += rect.x - if y != None: y += rect.y - return m(widget,x,y) - return func - - #def open(self,w,m): - # def func(widget=None): - # return m(widget) - # return func - - def decorate(self,widget,level): - """Interface method -- decorate a widget. - -

The theme system is given the opportunity to decorate a widget methods at the - end of the Widget initializer.

- -
Theme.decorate(widget,level)
- -
-
widget
the widget to be decorated -
level
the amount of decoration to do, False for none, True for normal amount, 'app' for special treatment of App objects. -
- """ - - w = widget - if level == False: return - - if type(w.style.background) != int: - w.background = Background(w,self) - - if level == 'app': return - - for k,v in w.style.__dict__.items(): - if k in ('border','margin','padding'): - for kk in ('top','bottom','left','right'): - setattr(w.style,'%s_%s'%(k,kk),v) - - w.paint = self.paint(w,w.paint) - w.event = self.event(w,w.event) - w.update = self.update(w,w.update) - w.resize = self.resize(w,w.resize) - w.open = self.open(w,w.open) - - def render(self,s,box,r): - """Interface method - render a special widget feature. - -
Theme.render(s,box,r)
- -
-
s
pygame.Surface -
box
box data, a value returned from Theme.get, typically a pygame.Surface -
r
pygame.Rect with the size that the box data should be rendered -
- - """ - - if box == 0: return - - if is_color(box): - s.fill(box,r) - return - - x,y,w,h=r.x,r.y,r.w,r.h - ww,hh=box.get_width()/3,box.get_height()/3 - xx,yy=x+w,y+h - src = pygame.rect.Rect(0,0,ww,hh) - dest = pygame.rect.Rect(0,0,ww,hh) - - s.set_clip(pygame.Rect(x+ww,y+hh,w-ww*2,h-hh*2)) - src.x,src.y = ww,hh - for dest.y in xrange(y+hh,yy-hh,hh): - for dest.x in xrange(x+ww,xx-ww,ww): s.blit(box,dest,src) - - s.set_clip(pygame.Rect(x+ww,y,w-ww*3,hh)) - src.x,src.y,dest.y = ww,0,y - for dest.x in xrange(x+ww,xx-ww*2,ww): s.blit(box,dest,src) - dest.x = xx-ww*2 - s.set_clip(pygame.Rect(x+ww,y,w-ww*2,hh)) - s.blit(box,dest,src) - - s.set_clip(pygame.Rect(x+ww,yy-hh,w-ww*3,hh)) - src.x,src.y,dest.y = ww,hh*2,yy-hh - for dest.x in xrange(x+ww,xx-ww*2,ww): s.blit(box,dest,src) - dest.x = xx-ww*2 - s.set_clip(pygame.Rect(x+ww,yy-hh,w-ww*2,hh)) - s.blit(box,dest,src) - - s.set_clip(pygame.Rect(x,y+hh,xx,h-hh*3)) - src.y,src.x,dest.x = hh,0,x - for dest.y in xrange(y+hh,yy-hh*2,hh): s.blit(box,dest,src) - dest.y = yy-hh*2 - s.set_clip(pygame.Rect(x,y+hh,xx,h-hh*2)) - s.blit(box,dest,src) - - s.set_clip(pygame.Rect(xx-ww,y+hh,xx,h-hh*3)) - src.y,src.x,dest.x=hh,ww*2,xx-ww - for dest.y in xrange(y+hh,yy-hh*2,hh): s.blit(box,dest,src) - dest.y = yy-hh*2 - s.set_clip(pygame.Rect(xx-ww,y+hh,xx,h-hh*2)) - s.blit(box,dest,src) - - s.set_clip() - src.x,src.y,dest.x,dest.y = 0,0,x,y - s.blit(box,dest,src) - - src.x,src.y,dest.x,dest.y = ww*2,0,xx-ww,y - s.blit(box,dest,src) - - src.x,src.y,dest.x,dest.y = 0,hh*2,x,yy-hh - s.blit(box,dest,src) - - src.x,src.y,dest.x,dest.y = ww*2,hh*2,xx-ww,yy-hh - s.blit(box,dest,src) - - -class Background(widget.Widget): - def __init__(self,value,theme,**params): - params['decorate'] = False - widget.Widget.__init__(self,**params) - self.value = value - self.theme = theme - - def paint(self,s): - r = pygame.Rect(0,0,s.get_width(),s.get_height()) - v = self.value.style.background - if is_color(v): - s.fill(v) - else: - self.theme.render(s,v,r) diff --git a/src/pgu/gui/widget.py b/src/pgu/gui/widget.py deleted file mode 100644 index f0f4b13..0000000 --- a/src/pgu/gui/widget.py +++ /dev/null @@ -1,377 +0,0 @@ -""" -""" -import pygame - -import pguglobals -import style - -class SignalCallback: - # The function to call - func = None - # The parameters to pass to the function (as a list) - params = None - -class Widget: - """Template object - base for all widgets. - -
Widget(**params)
- -

A number of optional params may be passed to the Widget initializer.

- -
-
decorate
defaults to True. If true, will call theme.decorate(self) to allow the theme a chance to decorate the widget. -
style
a dict of style parameters. -
x, y, width, height
position and size parameters, passed along to style -
align, valign
alignment parameters, passed along to style -
font, color, background
other common parameters that are passed along to style -
cls
class name as used by Theme -
name
name of widget as used by Form. If set, will call form.add(self,name) to add the widget to the most recently created Form. -
focusable
True if this widget can receive focus via Tab, etc. Defaults to True. -
disabled
True of this widget is disabled. Defaults to False. -
value
initial value -
- - Example - Creating your own Widget -

This example shows which methods are template methods.

- - class Draw(gui.Widget): - def paint(self,s): - #paint the pygame.Surface - return - - def update(self,s): - #update the pygame.Surface and return the update rects - return [pygame.Rect(0,0,self.rect.w,self.rect.h)] - - def event(self,e): - #handle the pygame.Event - return - - def resize(self,width=None,height=None): - #return the width and height of this widget - return 256,256 - - """ - - # The name of the widget (or None if not defined) - name = None - - def __init__(self,**params): - #object.Object.__init__(self) - self.connects = {} - params.setdefault('decorate',True) - params.setdefault('style',{}) - params.setdefault('focusable',True) - params.setdefault('disabled',False) - - self.focusable = params['focusable'] - self.disabled = params['disabled'] - - self.rect = pygame.Rect(params.get('x',0),params.get('y',0),params.get('width',0),params.get('height',0)) - - s = params['style'] - #some of this is a bit "theme-ish" but it is very handy, so these - #things don't have to be put directly into the style. - for att in ('align','valign','x','y','width','height','color','font','background'): - if att in params: s[att] = params[att] - self.style = style.Style(self,s) - - self.cls = 'default' - if 'cls' in params: self.cls = params['cls'] - if 'name' in params: - import form - self.name = params['name'] - if hasattr(form.Form,'form') and form.Form.form != None: - form.Form.form.add(self) - self.form = form.Form.form - if 'value' in params: self.value = params['value'] - self.pcls = "" - - if params['decorate'] != False: - if (not pguglobals.app): - # TODO - fix this somehow - import app - print 'gui.widget: creating an App' - app.App() - pguglobals.app.theme.decorate(self,params['decorate']) - - def focus(self): - """Focus this Widget. - -
Widget.focus()
- """ - if getattr(self,'container',None) != None: - if self.container.myfocus != self: ## by Gal Koren - self.container.focus(self) - - def blur(self): - """Blur this Widget. - -
Widget.blur()
- """ - if getattr(self,'container',None) != None: self.container.blur(self) - - def open(self): - """Open this Widget as a modal dialog. - -
Widget.open()
- """ - #if getattr(self,'container',None) != None: self.container.open(self) - pguglobals.app.open(self) - - def close(self, w=None): - """Close this Widget (if it is a modal dialog.) - -
Widget.close()
- """ - #if getattr(self,'container',None) != None: self.container.close(self) - if (not w): - w = self - pguglobals.app.close(w) - - def resize(self,width=None,height=None): - """Template method - return the size and width of this widget. - -

Responsible for also resizing all sub-widgets.

- -
Widget.resize(width,height): return width,height
- -
-
width
suggested width -
height
suggested height -
- -

If not overridden, will return self.style.width, self.style.height

- """ - return self.style.width, self.style.height - - def chsize(self): - """Change the size of this widget. - -

Calling this method will cause a resize on all the widgets, - including this one.

- -
Widget.chsize()
- """ - - if not hasattr(self,'_painted'): return - - if not hasattr(self,'container'): return - - if pguglobals.app: - if pguglobals.app._chsize: - return - pguglobals.app.chsize() - return - - #if hasattr(app.App,'app'): - # w,h = self.rect.w,self.rect.h - # w2,h2 = self.resize() - # if w2 != w or h2 != h: - # app.App.app.chsize() - # else: - # self.repaint() - - - def update(self,s): - """Template method - update the surface - -
Widget.update(s): return list of pygame.Rect(s)
- -
-
s
pygame.Surface to update -
- -

return - a list of the updated areas as pygame.Rect(s).

- """ - return - - def paint(self,s): - """Template method - paint the surface - -
Widget.paint(s)
- -
-
s
pygame.Surface to paint -
- """ - return - - def repaint(self): - """Request a repaint of this Widget. - -
Widget.repaint()
- """ - if getattr(self,'container',None) != None: self.container.repaint(self) - def repaintall(self): - """Request a repaint of all Widgets. - -
Widget.repaintall()
- """ - if getattr(self,'container',None) != None: self.container.repaintall() - def reupdate(self): - """Request a reupdate of this Widget - -
Widget.reupdate()
- """ - if getattr(self,'container',None) != None: self.container.reupdate(self) - def next(self): - """Pass focus to next Widget. - -

Widget order determined by the order they were added to their container.

- -
Widget.next()
- """ - if getattr(self,'container',None) != None: self.container.next(self) - def previous(self): - """Pass focus to previous Widget. - -

Widget order determined by the order they were added to their container.

- -
Widget.previous()
- """ - - if getattr(self,'container',None) != None: self.container.previous(self) - - def get_abs_rect(self): - """Get the absolute rect of this widget on the App screen - -
Widget.get_abs_rect(): return pygame.Rect
- """ - x, y = self.rect.x, self.rect.y - x += self._rect_content.x - y += self._rect_content.y - c = getattr(self,'container',None) - while c: - x += c.rect.x - y += c.rect.y - if hasattr(c,'_rect_content'): - x += c._rect_content.x - y += c._rect_content.y - c = getattr(c,'container',None) - return pygame.Rect(x, y, self.rect.w, self.rect.h) - - def connect(self,code,func,*params): - """Connect a event code to a callback function. - -

There may be multiple callbacks per event code.

- -
Object.connect(code,fnc,value)
- -
-
code
event type [[gui-const]] -
fnc
callback function -
*values
values to pass to callback. Please note that callbacks may also have "magicaly" parameters. Such as: -
-
_event
receive the event -
_code
receive the event code -
_widget
receive the sending widget -
-
- - Example - - def onclick(value): - print 'click',value - - w = Button("PGU!") - w.connect(gui.CLICK,onclick,'PGU Button Clicked') - - """ - if (not code in self.connects): - self.connects[code] = [] - for cb in self.connects[code]: - if (cb.func == func): - # Already connected to this callback function - return - # Wrap the callback function and add it to the list - cb = SignalCallback() - cb.func = func - cb.params = params - self.connects[code].append(cb) - - # Remove signal handlers from the given event code. If func is specified, - # only those handlers will be removed. If func is None, all handlers - # will be removed. - def disconnect(self, code, func=None): - if (not code in self.connects): - return - if (not func): - # Remove all signal handlers - del self.connects[code] - else: - # Remove handlers that call 'func' - n = 0 - callbacks = self.connects[code] - while (n < len(callbacks)): - if (callbacks[n].func == func): - # Remove this callback - del callbacks[n] - else: - n += 1 - - def send(self,code,event=None): - """Send a code, event callback trigger. - -
Object.send(code,event=None)
- -
-
code
event code -
event
event -
- """ - if (not code in self.connects): - return - # Trigger all connected signal handlers - for cb in self.connects[code]: - func = cb.func - values = list(cb.params) - - nargs = func.func_code.co_argcount - names = list(func.func_code.co_varnames)[:nargs] - if hasattr(func,'im_class'): names.pop(0) - - args = [] - magic = {'_event':event,'_code':code,'_widget':self} - for name in names: - if name in magic.keys(): - args.append(magic[name]) - elif len(values): - args.append(values.pop(0)) - else: - break - args.extend(values) - func(*args) - - def _event(self,e): - if self.disabled: return - self.send(e.type,e) - return self.event(e) -# return -# import app -# if hasattr(app.App,'app'): -# app.App.app.events.append((self,e)) - - def event(self,e): - """Template method - called when an event is passed to this object. - -

Please note that if you use an event, returning the value True - will stop parent containers from also using the event. (For example, if - your widget handles TABs or arrow keys, and you don't want those to - also alter the focus.)

- -
-
e
event -
- """ - - return - - # Returns the top-level widget (usually the Desktop) by following the - # chain of 'container' references. - def get_toplevel(self): - top = self - while (getattr(top, "container", None)): - top = top.container - return top - diff --git a/src/pgu/hexvid.py b/src/pgu/hexvid.py deleted file mode 100644 index 2d4156d..0000000 --- a/src/pgu/hexvid.py +++ /dev/null @@ -1,127 +0,0 @@ -"""Hexagonal tile engine. - -

Note -- this engine is not finished. Sprites are not supported. It -can still be useful for using the level editor, and for rendering hex -terrains, however. If you are able to update it and use it in a real game, -help would be greatly appreciated!

- -

please note that this file is alpha, and is subject to modification in -future versions of pgu!

- -""" -print 'pgu.hexvid','This module is alpha, and is subject to change.' - -from pgu.vid import * -import pygame - - -class Hexvid(Vid): - """Create an hex vid engine. See [[vid]]""" - def update(self,screen): - return self.paint(screen) - - def paint(self,screen): - sw,sh = screen.get_width(),screen.get_height() - self.view.w,self.view.h = sw,sh - - tlayer = self.tlayer - blayer = self.blayer - #zlayer = self.zlayer - w,h = len(tlayer[0]),len(tlayer) - - #iso_w,iso_h,iso_z,tile_w,tile_h,base_w,base_h = self.iso_w,self.iso_h,self.iso_z,self.tile_w,self.tile_h,self.base_w,self.base_h - - tile_w,tile_h = self.tile_w,self.tile_h - tile_w2,tile_h2 = tile_w/2,tile_h/2 - - view = self.view - adj = self.adj = pygame.Rect(-self.view.x,-self.view.y,0,0) - - w,h = len(tlayer[0]),len(tlayer) - tiles = self.tiles - - #"" - if self.bounds == None: - tmp,y1 = self.tile_to_view((0,0)) - x1,tmp = self.tile_to_view((0,h+1)) - tmp,y2 = self.tile_to_view((w+1,h+1)) - x2,tmp = self.tile_to_view((w+1,0)) - self.bounds = pygame.Rect(x1,y1,x2-x1,y2-y1) - print self.bounds - #"" - - if self.bounds != None: self.view.clamp_ip(self.bounds) - - ox,oy = self.screen_to_tile((0,0)) - sx,sy = self.tile_to_view((ox,oy)) - dx,dy = sx - self.view.x,sy - self.view.y - - bot = 1 - - tile_wi = tile_w + tile_w/2 - tile_wi2 = tile_wi/2 - - #dx += tile_w/2 - - for i2 in xrange(-bot,self.view.h/tile_h2+bot*3): #NOTE: 3 seems a bit much, but it works. - tx,ty = ox + i2/2 + i2%2,oy + i2/2 - x,y = (i2%2)*tile_wi2 + dx,i2*tile_h2 + dy - - #to adjust for the -1 in i1 - x,tx,ty = x-tile_wi,tx-1,ty+1 - - x -= tile_w/2 - for i1 in xrange(-1,self.view.w/tile_wi+1): - if ty >= 0 and ty < h and tx >= 0 and tx < w: - if blayer != None: - n = blayer[ty][tx] - if n != 0: - t = tiles[n] - if t != None and t.image != None: - screen.blit(t.image,(x,y)) - n = tlayer[ty][tx] - if n != 0: - t = tiles[n] - if t != None and t.image != None: - screen.blit(t.image,(x,y)) - - - tx += 1 - ty -= 1 - x += tile_wi - - return [pygame.Rect(0,0,screen.get_width(),screen.get_height())] - - def view_to_tile(self,pos): - x,y = pos - #x = x + (self.tile_w*1/2) - - x,y = int(x*4/(self.tile_w*3)), y*2/self.tile_h - nx = (x + y) / 2 - ny = (y - x) / 2 - return nx,ny - - def tile_to_view(self,pos): - x,y = pos - nx = x - y - ny = x + y - nx,ny = int(nx*(self.tile_w*3)/4), ny*self.tile_h/2 - - #nx = nx - (self.tile_w*1/2) - return nx,ny - - def screen_to_tile(self,pos): #NOTE HACK : not sure if the 3/8 is right or not, but it is pretty close... - pos = pos[0]+self.view.x + self.tile_w*3/8,pos[1]+self.view.y - pos = self.view_to_tile(pos) - return pos - - def tile_to_screen(self,pos): - pos = self.tile_to_view(pos) - pos = pos[0]-self.view.x,pos[1]-self.view.y - return pos - - - def tga_load_tiles(self,fname,size,tdata={}): - Vid.tga_load_tiles(self,fname,size,tdata) - - self.tile_w,self.tile_h = size \ No newline at end of file diff --git a/src/pgu/high.py b/src/pgu/high.py deleted file mode 100644 index e05d22a..0000000 --- a/src/pgu/high.py +++ /dev/null @@ -1,154 +0,0 @@ -"""Classes for handling high score tables. -""" - -import os - -def High(fname,limit=10): - """Create a Highs object and returns the default high score table. - -
High(fname,limit=10)
- -
-
fname
filename to store high scores in -
limit
limit of scores to be recorded, defaults to 10 -
- """ - return Highs(fname,limit)['default'] - -class _Score: - def __init__(self,score,name,data=None): - self.score,self.name,self.data=score,name,data - -class _High: - """A high score table. These objects are passed to the user, but should not be created directly. - -

You can iterate them:

- - for e in myhigh: - print e.score,e.name,e.data - - -

You can modify them:

- - myhigh[0].name = 'Cuzco' - - -

You can find out their length:

- - print len(myhigh) - - """ - - def __init__(self,highs,limit=10): - self.highs = highs - self._list = [] - self.limit = limit - - def save(self): - """Save the high scores. - -
_High.save()
- """ - self.highs.save() - - def submit(self,score,name,data=None): - """Submit a high score to this table. - -
_High.submit(score,name,data=None)
- -

return -- the position in the table that the score attained. None if the score did not attain a position in the table.

- """ - n = 0 - for e in self._list: - if score > e.score: - self._list.insert(n,_Score(score,name,data)) - self._list = self._list[0:self.limit] - return n - n += 1 - if len(self._list) < self.limit: - self._list.append(_Score(score,name,data)) - return len(self._list)-1 - - def check(self,score): - """Check if a score will attain a position in the table. - -
_High.check(score)
- -

return -- the position the score will attain, else None

- """ - n = 0 - for e in self._list: - if score > e.score: - return n - n += 1 - if len(self._list) < self.limit: - return len(self._list) - - - def __iter__(self): - return self._list.__iter__() - - def __getitem__(self,key): - return self._list[key] - - def __len__(self): - return self._list.__len__() - - -class Highs: - """The high score object. - -
Highs(fname,limit=10)
-
    -
    fname
    filename to store high scores in -
    limit
    limit of scores to be recorded, defaults to 10 -
- -

You may access _High objects through this object:

- - - my_easy_hs = highs['easy'] - my_hard_hs = highs['hard'] - - - """ - def __init__(self,fname,limit=10): - self.fname = fname - self.limit = limit - self.load() - - def load(self): - """Re-load the high scores. - -
Highs.load()
- """ - - self._dict = {} - try: - f = open(self.fname) - for line in f.readlines(): - key,score,name,data = line.strip().split("\t") - if key not in self._dict: - self._dict[key] = _High(self,self.limit) - high = self._dict[key] - high.submit(int(score),name,data) - f.close() - except: - pass - - def save(self): - """Save the high scores. - -
Highs.save()
- """ - - f = open(self.fname,"w") - for key,high in self._dict.items(): - for e in high: - f.write("%s\t%d\t%s\t%s\n"%(key,e.score,e.name,str(e.data))) - f.close() - - def __getitem__(self,key): - if key not in self._dict: - self._dict[key] = _High(self,self.limit) - return self._dict[key] diff --git a/src/pgu/html.py b/src/pgu/html.py deleted file mode 100644 index 817c000..0000000 --- a/src/pgu/html.py +++ /dev/null @@ -1,571 +0,0 @@ -"""a html renderer -""" - -import sys -import htmllib -import re -import pygame -from pygame.locals import * - -from pgu import gui - -_amap = {'left':-1,'right':1,'center':0,None:None,'':None,} -_vamap = {'top':-1,'bottom':1,'center':0,'middle':0,None:None,'':None,} - -# Used by the HTML parser to load external resources (like images). This -# class loads content from the local file system. But you can pass your own -# resource loader to the HTML parser to find images by other means. -class ResourceLoader(object): - # Loads an image and returns it as a pygame image - def load_image(this, path): - return pygame.image.load(path) - -class _dummy: - pass - -class _flush: - def __init__(self): - self.style = _dummy() - self.style.font = None - self.style.color = None - self.cls = None - def add(self,w): pass - def space(self,v): pass - -class _hr(gui.Color): - def __init__(self,**params): - gui.Color.__init__(self,(0,0,0),**params) - def resize(self,width=None,height=None): - w,h = self.style.width,self.style.height - #if width != None: self.rect.w = width - #else: self.rect.w = 1 - - #xt,xr,xb,xl = self.getspacing() - - if width != None: w = max(w,width) - if height != None: h = max(h,height) - w = max(w,1) - h = max(h,1) - - return w,h #self.container.rect.w,h - - #self.rect.w = max(1,width,self.container.rect.w-(xl+xr)) - - #print self.rect - #self.rect.w = 1 - -class _html(htmllib.HTMLParser): - def init(self,doc,font,color,_globals,_locals,loader=None): - self.mystack = [] - self.document = doc - if (loader): - self.loader = loader - else: - # Use the default resource loader - self.loader = ResourceLoader() - self.myopen('document',self.document) - - self.myfont = self.font = font - self.mycolor = self.color = color - - self.form = None - - self._globals = _globals - self._locals = _locals - - def myopen(self,type_,w): - - self.mystack.append((type_,w)) - self.type,self.item = type_,w - - self.font = self.item.style.font - self.color = self.item.style.color - - if not self.font: self.font = self.myfont - if not self.color: self.color = self.mycolor - - def myclose(self,type_): - t = None - self.mydone() - while t != type_: - #if len(self.mystack)==0: return - t,w = self.mystack.pop() - t,w = self.mystack.pop() - self.myopen(t,w) - - def myback(self,type_): - if type(type_) == str: type_ = [type_,] - self.mydone() - #print 'myback',type_ - t = None - while t not in type_: - #if len(self.mystack)==0: return - t,w = self.mystack.pop() - self.myopen(t,w) - - def mydone(self): - #clearing out the last

- if not hasattr(self.item,'layout'): return - if len(self.item.layout._widgets) == 0: return - w = self.item.layout._widgets[-1] - if type(w) == tuple: - del self.item.layout._widgets[-1] - - - def start_b(self,attrs): self.font.set_bold(1) - def end_b(self): self.font.set_bold(0) - def start_i(self,attrs): self.font.set_italic(1) - def end_i(self): self.font.set_italic(0) - def start_u(self,attrs): self.font.set_underline(1) - def end_u(self): self.font.set_underline(0) - def start_br(self,attrs): self.do_br(attrs) - def do_br(self,attrs): self.item.br(self.font.size(" ")[1]) - def attrs_to_map(self,attrs): - k = None - r = {} - for k,v in attrs: r[k] = v - return r - - def map_to_params(self,r): - anum = re.compile("\D") - - params = {'style':{}} - style = params['style'] - - if 'bgcolor' in r: - style['background'] = gui.parse_color(r['bgcolor']) - if 'background' in r: - style['background'] = self.loader.load_image(r['background']) - if 'border' in r: style['border'] = int(r['border']) - - for k in ['width','height','colspan','rowspan','size','min','max']: - if k in r: params[k] = int(anum.sub("",r[k])) - - for k in ['name','value']: - if k in r: params[k] = r[k] - - if 'class' in r: params['cls'] = r['class'] - - if 'align' in r: - params['align'] = _amap[r['align']] - if 'valign' in r: - params['valign'] = _vamap[r['valign']] - - if 'style' in r: - for st in r['style'].split(";"): - #print st - if ":" in st: - #print st.split(":") - k,v = st.split(":") - k = k.replace("-","_") - k = k.replace(" ","") - v = v.replace(" ","") - if k == 'color' or k == 'border_color' or k == 'background': - v = gui.parse_color(v) - else: - v = int(anum.sub("",v)) - style[k] = v - return params - - def map_to_connects(self,e,r): - for k,evt in [('onclick',gui.CLICK),('onchange',gui.CHANGE)]: #blah blah blah - - if k in r: - #print k,r[k] - e.connect(evt,self.myexec,(e,r[k])) - - def start_p(self,attrs): - r = self.attrs_to_map(attrs) - align = r.get("align","left") - - self.check_p() - self.item.block(_amap[align]) - - def check_p(self): - if len(self.item.layout._widgets) == 0: return - if type(self.item.layout._widgets[-1]) == tuple: - w,h = self.item.layout._widgets[-1] - if w == 0: return - self.do_br(None) - - def end_p(self): - #print 'end p' - self.check_p() - - - def start_block(self,t,attrs,align=-1): - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) - if 'cls' in params: params['cls'] = t+"."+params['cls'] - else: params['cls'] = t - b = gui.Document(**params) - b.style.font = self.item.style.font - if 'align' in params: - align = params['align'] - self.item.block(align) - self.item.add(b) - self.myopen(t,b) - - - - def end_block(self,t): - self.myclose(t) - self.item.block(-1) - - def start_div(self,attrs): self.start_block('div',attrs) - def end_div(self): self.end_block('div') - def start_center(self,attrs): self.start_block('div',attrs,0) - def end_center(self): self.end_block('div') - - def start_h1(self,attrs): self.start_block('h1',attrs) - def end_h1(self): self.end_block('h1') - def start_h2(self,attrs): self.start_block('h2',attrs) - def end_h2(self): self.end_block('h2') - def start_h3(self,attrs): self.start_block('h3',attrs) - def end_h3(self): self.end_block('h3') - def start_h4(self,attrs): self.start_block('h4',attrs) - def end_h4(self): self.end_block('h4') - def start_h5(self,attrs): self.start_block('h5',attrs) - def end_h5(self): self.end_block('h5') - def start_h6(self,attrs): self.start_block('h6',attrs) - def end_h6(self): self.end_block('h6') - - def start_ul(self,attrs): self.start_block('ul',attrs) - def end_ul(self): self.end_block('ul') - def start_ol(self,attrs): - self.start_block('ol',attrs) - self.item.counter = 0 - def end_ol(self): self.end_block('ol') - def start_li(self,attrs): - self.myback(['ul','ol']) - cur = self.item - self.start_block('li',attrs) - if hasattr(cur,'counter'): - cur.counter += 1 - self.handle_data("%d. "%cur.counter) - else: - self.handle_data("- ") - #def end_li(self): self.end_block('li') #this isn't needed because of how the parser works - - def start_pre(self,attrs): self.start_block('pre',attrs) - def end_pre(self): self.end_block('pre') - def start_code(self,attrs): self.start_block('code',attrs) - def end_code(self): self.end_block('code') - - def start_table(self,attrs): - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) - - align = r.get("align","left") - self.item.block(_amap[align]) - - t = gui.Table(**params) - self.item.add(t) - - self.myopen('table',t) - - def start_tr(self,attrs): - self.myback('table') - self.item.tr() - - def _start_td(self,t,attrs): - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) - if 'cls' in params: params['cls'] = t+"."+params['cls'] - else: params['cls'] = t - b = gui.Document(cls=t) - - self.myback('table') - self.item.td(b,**params) - self.myopen(t,b) - - self.font = self.item.style.font - self.color = self.item.style.color - - def start_td(self,attrs): - self._start_td('td',attrs) - - def start_th(self,attrs): - self._start_td('th',attrs) - - def end_table(self): - self.myclose('table') - self.item.block(-1) - - def start_form(self,attrs): - r = self.attrs_to_map(attrs) - e = self.form = gui.Form() - e.groups = {} - - self._locals[r.get('id',None)] = e - - def start_input(self,attrs): - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) #why bother - #params = {} - - type_,name,value = r.get('type','text'),r.get('name',None),r.get('value',None) - f = self.form - if type_ == 'text': - e = gui.Input(**params) - self.map_to_connects(e,r) - self.item.add(e) - elif type_ == 'radio': - if name not in f.groups: - f.groups[name] = gui.Group(name=name) - g = f.groups[name] - del params['name'] - e = gui.Radio(group=g,**params) - self.map_to_connects(e,r) - self.item.add(e) - if 'checked' in r: g.value = value - elif type_ == 'checkbox': - if name not in f.groups: - f.groups[name] = gui.Group(name=name) - g = f.groups[name] - del params['name'] - e = gui.Checkbox(group=g,**params) - self.map_to_connects(e,r) - self.item.add(e) - if 'checked' in r: g.value = value - - elif type_ == 'button': - e = gui.Button(**params) - self.map_to_connects(e,r) - self.item.add(e) - elif type_ == 'submit': - e = gui.Button(**params) - self.map_to_connects(e,r) - self.item.add(e) - elif type_ == 'file': - e = gui.Input(**params) - self.map_to_connects(e,r) - self.item.add(e) - b = gui.Button(value='Browse...') - self.item.add(b) - def _browse(value): - d = gui.FileDialog(); - d.connect(gui.CHANGE,gui.action_setvalue,(d,e)) - d.open(); - b.connect(gui.CLICK,_browse,None) - - self._locals[r.get('id',None)] = e - - def start_object(self,attrs): - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) - code = "e = %s(**params)"%r['type'] - #print code - #print params - exec(code) - #print e - #print e.style.width,e.style.height - self.map_to_connects(e,r) - self.item.add(e) - - self._locals[r.get('id',None)] = e - - def start_select(self,attrs): - r = self.attrs_to_map(attrs) - params = {} - - name,value = r.get('name',None),r.get('value',None) - e = gui.Select(name=name,value=value,**params) - self.map_to_connects(e,r) - self.item.add(e) - self.myopen('select',e) - - def start_option(self,attrs): - r = self.attrs_to_map(attrs) - params = {} #style = self.map_to_style(r) - - self.myback('select') - e = gui.Document(**params) - self.item.add(e,value=r.get('value',None)) - self.myopen('option',e) - - - def end_select(self): - self.myclose('select') - - def start_hr(self,attrs): - self.do_hr(attrs) - def do_hr(self,attrs): - h = self.font.size(" ")[1]/2 - - r = self.attrs_to_map(attrs) - params = self.map_to_params(r) - params['style']['padding'] = h - print params - - self.item.block(0) - self.item.add(_hr(**params)) - self.item.block(-1) - - def anchor_begin(self,href,name,type_): - pass - - def anchor_end(self): - pass - - def start_title(self,attrs): self.myopen('title',_flush()) - def end_title(self): self.myclose('title') - - def myexec(self,value): - w,code = value - g = self._globals - l = self._locals - l['self'] = w - exec(code,g,l) - - def handle_image(self,src,alt,ismap,align,width,height): - try: - w = gui.Image(self.loader.load_image(src)) - if align != '': - self.item.add(w,_amap[align]) - else: - self.item.add(w) - except: - print 'handle_image: missing %s'%src - - def handle_data(self,txt): - if self.type == 'table': return - elif self.type in ('pre','code'): - txt = txt.replace("\t"," ") - ss = txt.split("\n") - if ss[-1] == "": del ss[-1] - for sentence in ss: - img = self.font.render(sentence,1,self.color) - w = gui.Image(img) - self.item.add(w) - self.item.block(-1) - return - - txt = re.compile("^[\t\r\n]+").sub("",txt) - txt = re.compile("[\t\r\n]+$").sub("",txt) - - tst = re.compile("[\t\r\n]+").sub("",txt) - if tst == "": return - - txt = re.compile("\s+").sub(" ",txt) - if txt == "": return - - if txt == " ": - self.item.space(self.font.size(" ")) - return - - for word in txt.split(" "): - word = word.replace(chr(160)," ") #  - #print self.item.cls - w = gui.Image(self.font.render(word,1,self.color)) - self.item.add(w) - self.item.space(self.font.size(" ")) - - -class HTML(gui.Document): - """a gui HTML object - -
HTML(data,globals=None,locals=None)
- -
-
data
html data -
globals
global variables (for scripting) -
locals
local variables (for scripting) -
loader
the resource loader -
- -

you may access html elements that have an id via widget[id]

- """ - def __init__(self,data,globals=None,locals=None,loader=None,**params): - gui.Document.__init__(self,**params) - # This ensures that the whole HTML document is left-aligned within - # the rendered surface. - self.style.align = -1 - - _globals,_locals = globals,locals - - if _globals == None: _globals = {} - if _locals == None: _locals = {} - self._globals = _globals - self._locals = _locals - - #font = gui.theme.get("label","","font") - p = _html(htmllib.AS_IS,0) - p.init(self,self.style.font,self.style.color,_globals,_locals, - loader=loader) - p.feed(data) - p.close() - p.mydone() - - - def __getitem__(self,k): - return self._locals[k] - - # Returns a box (pygame rectangle) surrounding all widgets in this document - def get_bounding_box(this): - minx = miny = sys.maxint - maxx = maxy = -sys.maxint - for e in this.layout.widgets: - minx = min(minx, e.rect.left) - miny = min(miny, e.rect.top) - maxx = max(maxx, e.rect.right+1) - maxy = max(maxy, e.rect.bottom+1) - return pygame.Rect(minx, miny, maxx-minx, maxy-miny) - - -def render_ext(font, rect, text, aa, color, bgcolor=(0,0,0,0), **params): - """Renders some html and returns the rendered surface, plus the - HTML instance that produced it. - """ - - htm = HTML(text, font=font, color=color, **params) - - if (rect == -1): - # Make the surface large enough to fit the rendered text - htm.resize(width=sys.maxint) - (width, height) = htm.get_bounding_box().size - # Now set the proper document width (computed from the bounding box) - htm.resize(width=width) - elif (type(rect) == int): - # Fix the width of the document, while the height is variable - width = rect - height = htm.resize(width=width)[1] - else: - # Otherwise the width and height of the document is fixed - (width, height) = rect.size - htm.resize(width=width) - - # Now construct a surface and paint to it - surf = pygame.Surface((width, height)).convert_alpha() - surf.fill(bgcolor) - htm.paint(surf) - return (surf, htm) - -def render(font, rect, text, aa, color, bgcolor=(0,0,0,0), **params): - """Renders some html - -
render(font,rect,text,aa,color,bgcolor=(0,0,0,0))
- """ - return render_ext(font, rect, text, aa, color, bgcolor, **params)[0] - -def rendertrim(font,rect,text,aa,color,bgcolor=(0,0,0,0),**params): - """render html, and make sure to trim the size - - rendertrim(font,rect,text,aa,color,bgcolor=(0,0,0,0)) - """ - # Render the HTML - (surf, htm) = render_ext(font, rect, text, aa, color, bgcolor, **params) - return surf.subsurface(htm.get_bounding_box()) - - -def write(s,font,rect,text,aa=0,color=(0,0,0), **params): - """write html to a surface - - write(s,font,rect,text,aa=0,color=(0,0,0)) - """ - htm = HTML(text, font=font, color=color, **params) - htm.resize(width=rect.w) - s = s.subsurface(rect) - htm.paint(s) - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/isovid.py b/src/pgu/isovid.py deleted file mode 100644 index d5048ec..0000000 --- a/src/pgu/isovid.py +++ /dev/null @@ -1,182 +0,0 @@ -"""Isometric tile engine. - -

Note -- this engine is not finished, any may not work for your -particular needs. If you are able to update it, help would be -greatly appreciated!

- -

please note that this file is alpha, and is subject to modification in -future versions of pgu!

- -""" -print 'pgu.isovid','This module is alpha, and is subject to change.' - -from pgu.vid import * -import pygame - -class Isovid(Vid): - """Create an iso vid engine. See [[vid]]""" - def update(self,screen): - return self.paint(screen) - - def paint(self,screen): - sw,sh = screen.get_width(),screen.get_height() - - tlayer = self.tlayer - blayer = self.blayer - zlayer = self.zlayer - w,h = len(tlayer[0]),len(tlayer) - - iso_w,iso_h,iso_z,tile_w,tile_h,base_w,base_h = self.iso_w,self.iso_h,self.iso_z,self.tile_w,self.tile_h,self.base_w,self.base_h - - base_h2 = base_h/2 - base_w2 = base_w/2 - - bot = tile_h/base_h2 - todo_max = sh/base_h2+bot - todo = [[] for y in xrange(0,todo_max)] - - self.view.w,self.view.h = sw,sh - view = self.view - adj = self.adj = pygame.Rect(-self.view.x,-self.view.y,0,0) - - for s in self.sprites: - self.sprite_calc_irect(s) - x,y = self.iso_to_view((s.rect.centerx,s.rect.centery)) - v = (y+adj.y)/base_h2 - 1 - if v >= 0 and v < todo_max: - todo[v].append((s.image,s.irect)) - #else: print 'doesnt fit',v - - w,h = len(tlayer[0]),len(tlayer) - tiles = self.tiles - - #"" - if self.bounds == None: - tmp,y1 = self.tile_to_view((0,0)) - x1,tmp = self.tile_to_view((0,h+1)) - tmp,y2 = self.tile_to_view((w+1,h+1)) - x2,tmp = self.tile_to_view((w+1,0)) - self.bounds = pygame.Rect(x1,y1,x2-x1,y2-y1) - #"" - - if self.bounds != None: self.view.clamp_ip(self.bounds) - - ox,oy = self.screen_to_tile((0,0)) - sx,sy = self.iso_to_view((ox*iso_w,oy*iso_h)) - dx,dy = sx - self.view.x,sy - self.view.y - - for i2 in xrange(-bot,self.view.h/base_h2+bot): - tx,ty = ox + i2/2 + i2%2,oy + i2/2 - x,y = (i2%2)*base_w2 + dx,i2*base_h2 + dy - - #to adjust for the -1 in i1 - x,tx,ty = x-base_w,tx-1,ty+1 - for i1 in xrange(-1,self.view.w/base_w+2): #NOTE: not sure why +2 - if ty >= 0 and ty < h and tx >= 0 and tx < w: - z = zlayer[ty][tx]*iso_z - if blayer != None: - n = blayer[ty][tx] - if n != 0: - t = tiles[n] - if t != None and t.image != None: - screen.blit(t.image,(x-base_w2,y+z)) - n = tlayer[ty][tx] - if n != 0: - t = tiles[n] - if t != None and t.image != None: - screen.blit(t.image,(x-base_w2,y-(t.image_h-base_h)+z)) - - tx += 1 - ty -= 1 - x += base_w - for img,irect in todo[y/base_h2]: - screen.blit(img,(irect.x+adj.x,irect.y+adj.y)) - - return [pygame.Rect(0,0,screen.get_width(),screen.get_height())] - - def iso_to_view(self,pos): - tlayer = self.tlayer - w,h = len(tlayer[0]),len(tlayer) - - x,y = pos - - #nx,ny = (h*self.iso_w + x - y)/2, (0 + x + y)/2 - nx,ny = (x - y)/2, (0 + x + y)/2 - - return (nx * self.base_w / self.iso_w), (ny * self.base_h / self.iso_h) - - def view_to_iso(self,pos): - tlayer = self.tlayer - w,h = len(tlayer[0]),len(tlayer) - - x,y = pos - - x,y = x*self.iso_w/self.base_w, y*self.iso_h/self.base_h - - #x -= (self.iso_w/2) * h - #x -= (self.iso_w/2) * h - - nx = (x+y) - ny = y*2-nx - - return nx,ny - - def tile_to_view(self,pos): - return self.iso_to_view((pos[0]*self.iso_w,pos[1]*self.iso_h)) - - def screen_to_tile(self,pos): - x,y = pos - x += self.view.x - y += self.view.y - x,y = self.view_to_iso((x,y)) - return x/self.iso_w,y/self.iso_h - - def tile_to_screen(self,pos): - x,y = self.iso_to_view((pos[0]*self.iso_w,pos[1]*self.iso_h)) - return x-self.view.x,y-self.view.y - - def tga_load_tiles(self,fname,size,tdata={}): - Vid.tga_load_tiles(self,fname,size,tdata) - - self.tile_w,self.tile_h = size - self.iso_w,self.iso_h,self.iso_z = self.tile_w,self.tile_w,1 - self.base_w,self.base_h = self.tile_w,self.tile_w/2 - - - - def resize(self,size,bg=0): - Vid.resize(self,size,bg) - - tlayer = self.tlayer - w,h = len(tlayer[0]),len(tlayer) - - self.zlayer = [[0 for x in xrange(0,w)] for y in xrange(0,h)] - - - - - def sprite_calc_irect(self,s): - tlayer = self.tlayer - w,h = len(tlayer[0]),len(tlayer) - zlayer = self.zlayer - - x,y = self.iso_to_view((s.rect.centerx,s.rect.centery)) - tx,ty = s.rect.centerx/self.iso_w,s.rect.centery/self.iso_h - z = 0 - if ty >= 0 and ty < h and tx >= 0 and tx < w: - z = zlayer[ty][tx]*self.iso_z - - nx,ny = x - s.shape.centerx, y - s.shape.centery + z - - s.irect.x,s.irect.y = nx,ny - - def run_codes(self,cdata,rect): - #HACK to make run_codes work - w,h = self.iso_w,self.iso_h - - img = self.tiles[0].image - - self.tiles[0].image = pygame.Surface((w,h)) - r = Vid.run_codes(self,cdata,rect) - self.tiles[0].image = img - return r diff --git a/src/pgu/layout.py b/src/pgu/layout.py deleted file mode 100644 index 75b6c9a..0000000 --- a/src/pgu/layout.py +++ /dev/null @@ -1,4 +0,0 @@ -print 'pgu.layout','Scheduled to be deprecated.' - -from pgu.gui.layout import * - diff --git a/src/pgu/text.py b/src/pgu/text.py deleted file mode 100644 index 1010a87..0000000 --- a/src/pgu/text.py +++ /dev/null @@ -1,61 +0,0 @@ -"""a collection of text rendering functions -""" -def write(s,font,pos,color,text,border=1): - """write text to a surface with a black border - -
write(s,font,pos,color,text,border=1)
- """ - i = font.render(text,1,(0,0,0)) - si = border - dirs = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] - for dx,dy in dirs: s.blit(i,(pos[0]+dx*si,pos[1]+dy*si)) - i = font.render(text,1,color) - s.blit(i,pos) - -def writec(s,font,color,text,border=1): - """write centered text to a surface with a black border - -
writec(s,font,color,text,border=1)
- """ - w,h = font.size(text) - x = (s.get_width()-w)/2 - y = (s.get_height()-h)/2 - write(s,font,(x,y),color,text,border) - -def writepre(s,font,rect,color,text): - """write preformatted text - -
writepre(s,font,rect,color,text)
- """ - r,c,txt = rect,color,text - txt = txt.replace("\t"," ") - i = font.render(" ",1,c) - sw,sh = i.get_width(),i.get_height() - y = r.top - for sentence in txt.split("\n"): - x = r.left - i = font.render(sentence,1,c) - s.blit(i,(x,y)) - y += sh - -def writewrap(s,font,rect,color,text): - """write wrapped text - -
writewrap(s,font,rect,color,text)
- """ - r,c,txt = rect,color,text - txt = txt.replace("\t"," ") - i = font.render(" ",1,c) - sw,sh = i.get_width(),i.get_height() - y = r.top - for sentence in txt.split("\n"): - x = r.left - for word in sentence.split(" "): - i = font.render(word,1,c) - iw,ih = i.get_width(),i.get_height() - if x+iw > r.right: x,y = r.left,y+sh - s.blit(i,(x,y)) - x += iw+sw - y += sh - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/tilevid.py b/src/pgu/tilevid.py deleted file mode 100644 index 00f730d..0000000 --- a/src/pgu/tilevid.py +++ /dev/null @@ -1,195 +0,0 @@ -"""Square tile based engine.""" - -from pgu.vid import * -import pygame - -class Tilevid(Vid): - """Based on [[vid]] -- see for reference.""" - def paint(self,s): - sw,sh = s.get_width(),s.get_height() - self.view.w,self.view.h = sw,sh - - tiles = self.tiles - tw,th = tiles[0].image.get_width(),tiles[0].image.get_height() - w,h = self.size - - if self.bounds != None: self.view.clamp_ip(self.bounds) - - ox,oy = self.view.x,self.view.y - tlayer = self.tlayer - blayer = self.blayer - alayer = self.alayer - sprites = self.sprites - - blit = s.blit - yy = - (self.view.y%th) - my = (oy+sh)/th - if (oy+sh)%th: my += 1 - - if blayer != None: - for y in xrange(oy/th,my): - if y >=0 and y < h: - trow = tlayer[y] - brow = blayer[y] - arow = alayer[y] - xx= - (self.view.x%tw) - mx = (ox+sw)/tw - #if (ox+sh)%tw: mx += 1 - for x in xrange(ox/tw,mx+1): - if x >=0and x=0 and y=0 and xTimer(fps) - """ - - def __init__(self,fps): - if fps == 0: - self.tick = self._blank - return - self.wait = 1000/fps - self.nt = pygame.time.get_ticks() - pygame.time.wait(0) - - def _blank(self): - pass - - def tick(self): - """Wait correct amount of time each frame. Call this once per frame. - -
Timer.tick()
- """ - self.ct = pygame.time.get_ticks() - if self.ct < self.nt: - pygame.time.wait(self.nt-self.ct) - self.nt+=self.wait - else: - self.nt = pygame.time.get_ticks()+self.wait - - -class Speedometer: - """A timer replacement that returns out FPS once a second. -
Speedometer()
- - Attributes -
-
fps
always set to the current FPS -
- """ - def __init__(self): - self.frames = 0 - self.st = pygame.time.get_ticks() - self.fps = 0 - - def tick(self): - """ Call this once per frame. - -
Speedometer.tick()
- """ - r = None - self.frames += 1 - self.ct = pygame.time.get_ticks() - if (self.ct - self.st) >= 1000: - r = self.fps = self.frames - #print "%s: %d fps"%(self.__class__.__name__,self.fps) - self.frames = 0 - self.st += 1000 - pygame.time.wait(0) #NOTE: not sure why, but you gotta call this now and again - return r - - - -# vim: set filetype=python sts=4 sw=4 noet si : diff --git a/src/pgu/vid.py b/src/pgu/vid.py deleted file mode 100644 index 6890e5d..0000000 --- a/src/pgu/vid.py +++ /dev/null @@ -1,560 +0,0 @@ -"""Sprite and tile engine. - -

[[tilevid]], [[isovid]], [[hexvid]] are all subclasses of -this interface.

- -

Includes support for:

- -
    -
  • Foreground Tiles -
  • Background Tiles -
  • Sprites -
  • Sprite-Sprite Collision handling -
  • Sprite-Tile Collision handling -
  • Scrolling -
  • Loading from PGU tile and sprite formats (optional) -
  • Set rate FPS (optional) -
- -

This code was previously known as the King James Version (named after the -Bible of the same name for historical reasons.)

-""" - -import pygame -from pygame.rect import Rect -from pygame.locals import * -import math - -class Sprite: - """The object used for Sprites. - -
Sprite(ishape,pos)
- -
-
ishape
an image, or an image, rectstyle. The rectstyle will - describe the shape of the image, used for collision - detection. -
pos
initial (x,y) position of the Sprite. -
- - Attributes -
-
rect
the current position of the Sprite -
_rect
the previous position of the Sprite -
groups
the groups the Sprite is in -
agroups
the groups the Sprite can hit in a collision -
hit
the handler for hits -- hit(g,s,a) -
loop
the loop handler, called once a frame -
- """ - def __init__(self,ishape,pos): - if not isinstance(ishape, tuple): - ishape = ishape,None - image,shape = ishape - if shape == None: - shape = pygame.Rect(0,0,image.get_width(),image.get_height()) - if isinstance(shape, tuple): shape = pygame.Rect(shape) - self.image = image - self._image = self.image - self.shape = shape - self.rect = pygame.Rect(pos[0],pos[1],shape.w,shape.h) - self._rect = pygame.Rect(self.rect) - self.irect = pygame.Rect(pos[0]-self.shape.x,pos[1]-self.shape.y, - image.get_width(),image.get_height()) - self._irect = pygame.Rect(self.irect) - self.groups = 0 - self.agroups = 0 - self.updated = 1 - - def setimage(self,ishape): - """Set the image of the Sprite. - -
Sprite.setimage(ishape)
- -
-
ishape
an image, or an image, rectstyle. The rectstyle will - describe the shape of the image, used for collision detection. -
- """ - if not isinstance(ishape, tuple): - ishape = ishape,None - image,shape = ishape - if shape == None: - shape = pygame.Rect(0,0,image.get_width(),image.get_height()) - if isinstance(shape, tuple): - shape = pygame.Rect(shape) - self.image = image - self.shape = shape - self.rect.w,self.rect.h = shape.w,shape.h - self.irect.w,self.irect.h = image.get_width(),image.get_height() - self.updated = 1 - - -class Tile: - """Tile Object used by TileCollide. - -
Tile(image=None)
-
-
image
an image for the Tile. -
- - Attributes -
-
agroups
the groups the Tile can hit in a collision -
hit
the handler for hits -- hit(g,t,a) -
- """ - def __init__(self,image=None): - self.image = image - self.agroups = 0 - - def __setattr__(self,k,v): - if k == 'image' and v != None: - self.image_h = v.get_height() - self.image_w = v.get_width() - self.__dict__[k] = v - -class _Sprites(list): - def __init__(self): - list.__init__(self) - self.removed = [] - - def append(self,v): - list.append(self,v) - v.updated = 1 - - def remove(self,v): - list.remove(self,v) - v.updated = 1 - self.removed.append(v) - -class Vid: - """An engine for rendering Sprites and Tiles. - -
Vid()
- - Attributes -
-
sprites
a list of the Sprites to be displayed. You may append and - remove Sprites from it. -
images
a dict for images to be put in. -
size
the width, height in Tiles of the layers. Do not modify. -
view
a pygame.Rect of the viewed area. You may change .x, .y, - etc to move the viewed area around. -
bounds
a pygame.Rect (set to None by default) that sets the bounds - of the viewable area. Useful for setting certain borders - as not viewable. -
tlayer
the foreground tiles layer -
clayer
the code layer (optional) -
blayer
the background tiles layer (optional) -
groups
a hash of group names to group values (32 groups max, as a tile/sprites - membership in a group is determined by the bits in an integer) -
- """ - - def __init__(self): - self.tiles = [None for x in xrange(0,256)] - self.sprites = _Sprites() - self.images = {} #just a store for images. - self.layers = None - self.size = None - self.view = pygame.Rect(0,0,0,0) - self._view = pygame.Rect(self.view) - self.bounds = None - self.updates = [] - self.groups = {} - - - def resize(self,size,bg=0): - """Resize the layers. - -
Vid.resize(size,bg=0)
- -
-
size
w,h in Tiles of the layers -
bg
set to 1 if you wish to use both a foreground layer and a - background layer -
- """ - self.size = size - w,h = size - self.layers = [[[0 for x in xrange(0,w)] for y in xrange(0,h)] - for z in xrange(0,4)] - self.tlayer = self.layers[0] - self.blayer = self.layers[1] - if not bg: self.blayer = None - self.clayer = self.layers[2] - self.alayer = self.layers[3] - - self.view.x, self.view.y = 0,0 - self._view.x, self.view.y = 0,0 - self.bounds = None - - self.updates = [] - - def set(self,pos,v): - """Set a tile in the foreground to a value. - -

Use this method to set tiles in the foreground, as it will make - sure the screen is updated with the change. Directly changing - the tlayer will not guarantee updates unless you are using .paint() -

- -
Vid.set(pos,v)
- -
-
pos
(x,y) of tile -
v
value -
- """ - if self.tlayer[pos[1]][pos[0]] == v: return - self.tlayer[pos[1]][pos[0]] = v - self.alayer[pos[1]][pos[0]] = 1 - self.updates.append(pos) - - def get(self,pos): - """Get the tlayer at pos. - -
Vid.get(pos): return value
- -
-
pos
(x,y) of tile -
- """ - return self.tlayer[pos[1]][pos[0]] - - def paint(self,s): - """Paint the screen. - -
Vid.paint(screen): return [updates]
- -
-
screen
a pygame.Surface to paint to -
- -

returns the updated portion of the screen (all of it)

- """ - return [] - - def update(self,s): - """Update the screen. - -
Vid.update(screen): return [updates]
- -
-
screen
a pygame.Rect to update -
- -

returns a list of updated rectangles.

- """ - self.updates = [] - return [] - - def tga_load_level(self,fname,bg=0): - """Load a TGA level. - -
Vid.tga_load_level(fname,bg=0)
- -
-
g
a Tilevid instance -
fname
tga image to load -
bg
set to 1 if you wish to load the background layer -
- """ - if type(fname) == str: img = pygame.image.load(fname) - else: img = fname - w,h = img.get_width(),img.get_height() - self.resize((w,h),bg) - for y in range(0,h): - for x in range(0,w): - t,b,c,_a = img.get_at((x,y)) - self.tlayer[y][x] = t - if bg: self.blayer[y][x] = b - self.clayer[y][x] = c - - def tga_save_level(self,fname): - """Save a TGA level. - -
Vid.tga_save_level(fname)
- -
-
fname
tga image to save to -
- """ - w,h = self.size - img = pygame.Surface((w,h),SWSURFACE,32) - img.fill((0,0,0,0)) - for y in range(0,h): - for x in range(0,w): - t = self.tlayer[y][x] - b = 0 - if self.blayer: - b = self.blayer[y][x] - c = self.clayer[y][x] - _a = 0 - img.set_at((x,y),(t,b,c,_a)) - pygame.image.save(img,fname) - - - - def tga_load_tiles(self,fname,size,tdata={}): - """Load a TGA tileset. - -
Vid.tga_load_tiles(fname,size,tdata={})
- -
-
g
a Tilevid instance -
fname
tga image to load -
size
(w,h) size of tiles in pixels -
tdata
tile data, a dict of tile:(agroups, hit handler, config) -
- """ - TW,TH = size - if type(fname) == str: img = pygame.image.load(fname).convert_alpha() - else: img = fname - w,h = img.get_width(),img.get_height() - - n = 0 - for y in range(0,h,TH): - for x in range(0,w,TW): - i = img.subsurface((x,y,TW,TH)) - tile = Tile(i) - self.tiles[n] = tile - if n in tdata: - agroups,hit,config = tdata[n] - tile.agroups = self.string2groups(agroups) - tile.hit = hit - tile.config = config - n += 1 - - - def load_images(self,idata): - """Load images. - -
Vid.load_images(idata)
- -
-
idata
a list of (name, fname, shape) -
- """ - for name,fname,shape in idata: - self.images[name] = pygame.image.load(fname).convert_alpha(),shape - - def run_codes(self,cdata,rect): - """Run codes. - -
Vid.run_codes(cdata,rect)
- -
-
cdata
a dict of code:(handler function, value) -
rect
a tile rect of the parts of the layer that should have - their codes run -
- """ - tw,th = self.tiles[0].image.get_width(),self.tiles[0].image.get_height() - - x1,y1,w,h = rect - clayer = self.clayer - t = Tile() - for y in range(y1,y1+h): - for x in range(x1,x1+w): - n = clayer[y][x] - if n in cdata: - fnc,value = cdata[n] - t.tx,t.ty = x,y - t.rect = pygame.Rect(x*tw,y*th,tw,th) - fnc(self,t,value) - - - def string2groups(self,str): - """Convert a string to groups. - -
Vid.string2groups(str): return groups
- """ - if str == None: return 0 - return self.list2groups(str.split(",")) - - def list2groups(self,igroups): - """Convert a list to groups. -
Vid.list2groups(igroups): return groups
- """ - for s in igroups: - if not s in self.groups: - self.groups[s] = 2**len(self.groups) - v = 0 - for s,n in self.groups.items(): - if s in igroups: v|=n - return v - - def groups2list(self,groups): - """Convert a groups to a list. -
Vid.groups2list(groups): return list
- """ - v = [] - for s,n in self.groups.items(): - if (n&groups)!=0: v.append(s) - return v - - def hit(self,x,y,t,s): - tiles = self.tiles - tw,th = tiles[0].image.get_width(),tiles[0].image.get_height() - t.tx = x - t.ty = y - t.rect = Rect(x*tw,y*th,tw,th) - t._rect = t.rect - if hasattr(t,'hit'): - t.hit(self,t,s) - - def loop(self): - """Update and hit testing loop. Run this once per frame. -
Vid.loop()
- """ - self.loop_sprites() #sprites may move - self.loop_tilehits() #sprites move - self.loop_spritehits() #no sprites should move - for s in self.sprites: - s._rect = pygame.Rect(s.rect) - - def loop_sprites(self): - as_ = self.sprites[:] - for s in as_: - if hasattr(s,'loop'): - s.loop(self,s) - - def loop_tilehits(self): - tiles = self.tiles - tw,th = tiles[0].image.get_width(),tiles[0].image.get_height() - - layer = self.layers[0] - - as_ = self.sprites[:] - for s in as_: - self._tilehits(s) - - def _tilehits(self,s): - tiles = self.tiles - tw,th = tiles[0].image.get_width(),tiles[0].image.get_height() - layer = self.layers[0] - - for _z in (0,): - if s.groups != 0: - - _rect = s._rect - rect = s.rect - - _rectx = _rect.x - _recty = _rect.y - _rectw = _rect.w - _recth = _rect.h - - rectx = rect.x - recty = rect.y - rectw = rect.w - recth = rect.h - - rect.y = _rect.y - rect.h = _rect.h - - hits = [] - ct,cb,cl,cr = rect.top,rect.bottom,rect.left,rect.right - #nasty ol loops - y = ct/th*th - while y < cb: - x = cl/tw*tw - yy = y/th - while x < cr: - xx = x/tw - t = tiles[layer[yy][xx]] - if (s.groups & t.agroups)!=0: - #self.hit(xx,yy,t,s) - d = math.hypot(rect.centerx-(xx*tw+tw/2), - rect.centery-(yy*th+th/2)) - hits.append((d,t,xx,yy)) - - x += tw - y += th - - hits.sort() - #if len(hits) > 0: print self.frame,hits - for d,t,xx,yy in hits: - self.hit(xx,yy,t,s) - - #switching directions... - _rect.x = rect.x - _rect.w = rect.w - rect.y = recty - rect.h = recth - - hits = [] - ct,cb,cl,cr = rect.top,rect.bottom,rect.left,rect.right - #nasty ol loops - y = ct/th*th - while y < cb: - x = cl/tw*tw - yy = y/th - while x < cr: - xx = x/tw - t = tiles[layer[yy][xx]] - if (s.groups & t.agroups)!=0: - d = math.hypot(rect.centerx-(xx*tw+tw/2), - rect.centery-(yy*th+th/2)) - hits.append((d,t,xx,yy)) - #self.hit(xx,yy,t,s) - x += tw - y += th - - hits.sort() - #if len(hits) > 0: print self.frame,hits - for d,t,xx,yy in hits: - self.hit(xx,yy,t,s) - - #done with loops - _rect.x = _rectx - _rect.y = _recty - - - def loop_spritehits(self): - as_ = self.sprites[:] - - groups = {} - for n in range(0,31): - groups[1<>= 1 - n <<= 1 - - for s in as_: - if s.agroups!=0: - rect1,rect2 = s.rect,Rect(s.rect) - #if rect1.centerx < 320: rect2.x += 640 - #else: rect2.x -= 640 - g = s.agroups - n = 1 - while g: - if (g&1)!=0: - for b in groups[n]: - if (s != b and (s.agroups & b.groups)!=0 - and s.rect.colliderect(b.rect)): - s.hit(self,s,b) - - g >>= 1 - n <<= 1 - - - def screen_to_tile(self,pos): - """Convert a screen position to a tile position. -
Vid.screen_to_tile(pos): return pos
- """ - return pos - - def tile_to_screen(self,pos): - """Convert a tile position to a screen position. -
Vid.tile_to_screen(pos): return pos
- """ - return pos - -# vim: set filetype=python sts=4 sw=4 noet si :