from eduGames import * from pygame.font import * import os if os.name != "nt": try: import olpcgames except: pass class CongratsWindow(ImageControl): (OPEN, CLOSED) = (0,1) def __init__(self, game): ImageControl.__init__(self, game, 0, 0, game.makePath("congrats_backg.png"), "", 1) self.setX(self.game.settings["screenWidth"]/2 + self.game.xMargin - self.getWidth()/2) self.setY(self.game.settings["screenHeight"]/2 + self.game.yMargin - self.getHeight()/2) self.__state = CongratsWindow.CLOSED self.congratsLabel = None self.counter = -1 self.congratsTexts = ( "Congratulations", "Good", "Great", "Correct", "Excellent" ) def open(self): if not self.__state == CongratsWindow.CLOSED: return self.__state = CongratsWindow.OPEN self.game.getUiMgr().shiftLayers(20) self.game.filter.filterOn() self.game.getUiMgr().addControl(self) self.createNextButton() self.createCongratsLabel() def close(self): if not self.__state == CongratsWindow.OPEN: return self.__state = CongratsWindow.CLOSED self.game.getUiMgr().removeControl(self) self.game.getUiMgr().shiftLayers(-20) self.game.filter.filterOff() self.game.getUiMgr().removeControl(self.nextButton) self.game.getUiMgr().removeControl(self.congratsLabel) self.nextButton = None def createNextButton(self): self.nextButton = ImageControl(self.game, 0, 0, self.game.makePath("congrats_btn_next.png"), "", 2) self.nextButton.type = "nextButton" xNextButton = self.getX() + self.getWidth()/2 - self.nextButton.getWidth() yNextButton = self.getY() + self.getHeight() - self.nextButton.getHeight() -20 self.nextButton.setX(xNextButton) self.nextButton.setY(yNextButton) self.game.getUiMgr().addControl(self.nextButton) def createCongratsLabel(self): font = Font(self.game.makePath("niobbl_.ttf"), 30) self.congratsLabel = Label(self.game, 350, 400, 400, 50, font, self.congratsMessage(), 0) self.congratsLabel.color = (78,113,16) self.congratsLabel.background = None self.game.getUiMgr().addControl(self.congratsLabel) def isOpen(self): return self.__state == CongratsWindow.OPEN def currentCongratsMessage(self): return self.congratsTexts[self.counter%len(self.congratsTexts)] + "!" def congratsMessage(self): self.counter += 1 return self.congratsTexts[self.counter%len(self.congratsTexts)] + "!" class WelcomeWindow(ImageControl): (OPEN, CLOSED) = (0,1) def __init__(self, game): ImageControl.__init__(self, game, 0, 0, game.makePath("Pant_WELCOME.png"), "", 1) self.setX(self.game.settings["screenWidth"]/2 + self.game.xMargin - self.getWidth()/2) self.setY(self.game.settings["screenHeight"]/2 + self.game.yMargin - self.getHeight()/2) self.__state = WelcomeWindow.CLOSED self.counter = -1 def open(self): if not self.__state == WelcomeWindow.CLOSED: return self.__state = WelcomeWindow.OPEN self.game.getUiMgr().shiftLayers(20) # self.game.filter.filterOn() self.game.getUiMgr().addControl(self) self.createOkButton() def close(self): if not self.__state == WelcomeWindow.OPEN: return self.__state = WelcomeWindow.CLOSED self.game.getUiMgr().removeControl(self) self.game.getUiMgr().shiftLayers(-20) # self.game.filter.filterOff() self.game.getUiMgr().removeControl(self.okButton) self.okButton = None def createOkButton(self): self.okButton = ImageControl(self.game, 0, 0, self.game.makePath("Btn_WELCOME_ok.png"), "", 2) self.okButton.type = "okButton" xOkButton = self.getX() + self.getWidth()/2 - self.okButton.getWidth() + 50 yOkButton = self.getY() + self.getHeight() - self.okButton.getHeight() -27 self.okButton.setX(xOkButton) self.okButton.setY(yOkButton) self.game.getUiMgr().addControl(self.okButton) def isOpen(self): return self.__state == WelcomeWindow.OPEN class MessageWindow(SingleColorControlWithBorder): (OPEN, CLOSED) = (0,1) def __init__(self, game): SingleColorControlWithBorder.__init__(self, game, 0, 0, 0, 0, (255,255,255), 10) self.__state = MessageWindow.CLOSED self.nextButton = None self.exitButton = None self.nextButton = None def open(self, rect, exitButton = False, nextButton = False): if not self.__state == MessageWindow.CLOSED: return self.__state = MessageWindow.OPEN self.setX(rect.x) self.setY(rect.y) self.setWidth(rect.width) self.setHeight(rect.height) self.game.getUiMgr().shiftLayers(20) self.game.filter.filterOn() self.game.getUiMgr().addControl(self) if exitButton: self.createExitButton() if nextButton: self.createNextButton() def close(self): if not self.__state == MessageWindow.OPEN: return self.__state = MessageWindow.CLOSED self.game.getUiMgr().removeControl(self) self.game.getUiMgr().shiftLayers(-20) self.game.filter.filterOff() if not self.exitButton is None: self.game.getUiMgr().removeControl(self.exitButton) self.exitButton = None if not self.nextButton is None: self.game.getUiMgr().removeControl(self.nextButton) self.nextButton = None def createExitButton(self): self.exitButton = ImageControl(self.game, 0, 0, self.game.makePath("btn_quit.png"), "", 2) xExitButton = self.getX() + self.getWidth() - self.exitButton.getWidth() -20 yExitButton = self.getY() + 20 self.exitButton.setX(xExitButton) self.exitButton.setY(yExitButton) self.game.getUiMgr().addControl(self.exitButton) def createNextButton(self): self.nextButton = ImageControl(self.game, 0, 0, self.game.makePath("btn_next.png"), "", 2) self.nextButton.type = "nextButton" xNextButton = self.getX() + self.getWidth() - self.nextButton.getWidth() -20 yNextButton = self.getY() + self.getHeight() - self.nextButton.getHeight() -20 self.nextButton.setX(xNextButton) self.nextButton.setY(yNextButton) self.game.getUiMgr().addControl(self.nextButton) def isOpen(self): return self.__state == MessageWindow.OPEN class Menu(Control): (CLOSED, OPEN) = (0,1) def __init__(self, game, mainControl, backgroundControl): Control.__init__(self, game, mainControl.getX(), mainControl.getY(), mainControl.getWidth(), mainControl.getHeight(), "") #mainControl is what you click to open the menu. #A submenu is an item of the menu. The item itself is the submenu's mainControl. #The background is what's behind the submenus's mainControls. self.mainControl = mainControl self.submenus = [] self.background = backgroundControl game.getUiMgr().addControl(self.mainControl) if not self.background is None: game.getUiMgr().addControl(self.background) self.background.makeInvisible() self.item = None self.state = self.CLOSED self.stateChanged = True self.type = "menu" self.parent = None self.hasMemory = True # self.openSubmenu = None self.memory =[] def click(self): self.revertState() def __changeSubmenusVisibility(self, visible): for menu in self.submenus: if visible: menu.makeVisible() else: menu.makeInvisible() def makeInvisible(self): Control.makeInvisible(self) self.mainControl.makeInvisible() if not self.background is None: self.background.makeInvisible() self.__changeSubmenusVisibility(False) def makeVisible(self): Control.makeVisible(self) self.mainControl.makeVisible() def addSubmenu(self, menu): self.submenus.append(menu) menu.makeInvisible() def open(self): self.__setState(self.OPEN) def close(self): self.state = self.CLOSED self.stateChanged = True def __closeSiblings(self): if not self.parent is None: for sibling in self.parent.submenus: if not sibling is self: sibling.close() def revertState(self): if self.isOpen(): self.__setState(self.CLOSED) else: self.__setState(self.OPEN) def __setState(self, state): if self.state == state: return self.state = state if self.state == self.OPEN: self.__closeSiblings() self.stateChanged = True def isOpen(self): return self.state == self.OPEN def isClosed(self): return self.state == self.CLOSED def closeSubmenus(self): for submenu in self.submenus: submenu.close() submenu.makeInvisible() def memorizeState(self): self.__getOpenSubmenus(self.memory) def __getOpenSubmenus(self, list): if len(self.submenus) == 0: return for submenu in self.submenus: if submenu.isOpen(): list.append(submenu) submenu.__getOpenSubmenus(list) def __restoreMemory(self): for menu in self.memory: menu.open() self.memory = [] def turnHoverOn(self): self.mainControl.textColor = (255, 255, 255) self.markChanges() def turnHoverOff(self): self.mainControl.textColor = (0,0,0) self.markChanges() def update(self): if self.stateChanged: if self.isOpen(): if self.hasMemory and self.parent is None: self.__restoreMemory() if not self.background is None: self.background.makeVisible() self.__changeSubmenusVisibility(True) self.mainControl.open() self.turnHoverOff() else: if self.hasMemory and self.parent is None: self.memorizeState() if not self.background is None: self.background.makeInvisible() self.closeSubmenus() self.mainControl.close() for m in self.submenus: #I actually don't like this, but I think I have no choice. m.update() self.stateChanged = False class Archiver(ImageControl): (CLOSED, HOVERED_ON, OPEN) = (0,1,2) def click(self): pass def __init__(self, game, x, y, directory = ""): if directory == "": path = os.path.join(game.settings["resourcesDir"], "btn_archivero.png") else: path = os.path.join(directory, "btn_archivero.png") ImageControl.__init__(self, game, x, y, path, "", 3) self.state = self.CLOSED self.previousState = self.CLOSED self.changed = True def setState(self, state): pass def hover(self): self.__changeState(self.HOVERED_ON) def open(self): self.__changeState(self.OPEN) def closeCompletely(self): self.__changeState(self.CLOSED) def close(self): #This is "close" in the sense of the menu. if self.isOpen(): if self.previousState == self.HOVERED_ON or self.previousState == self.CLOSED: self.restorePreviousState() def __changeState(self, newState): if self.state == newState: return self.previousState = self.state self.state = newState self.changed = True def isOpen(self): return self.state == self.OPEN def isUnderMouseHover(self): return self.state == self.HOVERED_ON def update(self): ImageControl.update(self) if self.changed: self.setImageDivisionIndex(self.state) self.changed = False def restorePreviousState(self): self.__changeState(self.previousState) class DirectoryTreeNode: def __init__(self, path, name = "", level = 1): self.children = [] self.parent = None self.path = path self.name = path self.level = level self.isDir = False self.menu = None self.__numberOfActivities = -1 self.__finishedActivities = 0 if name != "": self.name = name if os.path.isdir(path): self.isDir = True children = [c for c in os.listdir(path) if os.path.isdir(os.path.join(path, c))] children.sort() for ch in children: if not ch == "sounds" and not ch == "images": childDirName = os.path.split(path)[1] child = DirectoryTreeNode(os.path.join(path, ch), ch, level + 1) child.parent = self self.children.append(child) def getGameEngineName(self): return self.name[1:] def getActivityTypeName(self): engineName = self.getGameEngineName().upper() if engineName == "SORT": return "Sort" if engineName == "PAINT": return "Paint" if engineName == "COLORPAINT": return "Paint" if engineName == "MATCH": return "Match" if engineName == "DRAGNDROP" or engineName == "DRAG": return "Drag" if engineName == "MULTIPLEC" or engineName == "YESANDNO": return "Yes and No" if engineName == "CONCENTRATE" or engineName == "CONCENTRATION": return "Concentration" def getNumberOfActivities(self): if self.__numberOfActivities == -1: self.__numberOfActivities = 0 if self.level == 4: #belongs to the level of activities self.__numberOfActivities = 1 else: for c in self.children: self.__numberOfActivities += c.getNumberOfActivities() return self.__numberOfActivities def isFinished(self): #PRECONDITION: this node (self) must have level 4 ret = False dataFilePath = self.getDataFilePath() dataFile = open(dataFilePath, "r") dataFileText = dataFile.readlines() for line in dataFileText: line = line.strip() if line == "finished = 1": ret = True dataFile.close() return ret def getNumberOfFinishedActivities(self): self.__finishedActivities = 0 try: if self.level == 4: dataFilePath = self.getDataFilePath() dataFile = open(dataFilePath, "r") dataFileText = dataFile.readlines() for line in dataFileText: line = line.strip() if line == "finished = 1": self.__finishedActivities += 1 dataFile.close() else: for c in self.children: self.__finishedActivities += c.getNumberOfFinishedActivities() return self.__finishedActivities except: return 0 def isFirstActivityOfUnit(self): if self.level == 4: #is activity unit = self.parent index = unit.children.index(self) if index == 0: return True else: return False def getUnit(self): if self.level == 4: #is activity unit = self.parent return unit def getNextActivity(self): if self.level == 4: unit = self.parent index = unit.children.index(self) indexNextActivity = (index + 1)%len(unit.children) if indexNextActivity > 0: return unit.children[indexNextActivity] else: return unit.getNextActivity() if self.level == 3: #unit level = self.parent index = level.children.index(self) indexNextUnit = (index + 1)%len(level.children) if indexNextUnit > 0: nextUnit = level.children[indexNextUnit] if len(nextUnit.children) > 0: return nextUnit.children[0] else: return nextUnit.getNextActivity() else: return level.getNextActivity() if self.level == 2: #level root = self.parent index = root.children.index(self) indexNextLevel = (index +1)%len(root.children) if indexNextLevel > 0: nextLevel = root.children[indexNextLevel] if len(nextLevel.children) > 0: firstUnit = nextLevel.children[0] if len(firstUnit.children) > 0: return firstUnit.children[0] else: return firstUnit.getNextActivity() else: return nextLevel.getNextActivity() else: return None def getPreviousActivity(self): if self.level == 4: unit = self.parent index = unit.children.index(self) indexPreviousActivity = index - 1 if indexPreviousActivity > -1: return unit.children[indexPreviousActivity] else: return unit.getPreviousActivity() if self.level == 3: level = self.parent index = level.children.index(self) indexPreviousUnit = index - 1 if indexPreviousUnit > -1: previousUnit = level.children[indexPreviousUnit] previousUnitNumChildren = len(previousUnit.children) if previousUnitNumChildren > 0: return previousUnit.children[previousUnitNumChildren - 1] else: return previousUnit.getPreviousActivity() else: return level.getPreviousActivity() if self.level == 2: root = self.parent index = root.children.index(self) indexPreviousLevel = index - 1 if indexPreviousLevel > -1: previousLevel = root.children[indexPreviousLevel] previousLevelNumChildren = len(previousLevel.children) if previousLevelNumChildren > 0: lastUnit = previousLevel.children[previousLevelNumChildren - 1] lastUnitNumChildren = len(lastUnit.children) if lastUnitNumChildren > 0: return lastUnit.children[lastUnitNumChildren - 1] else: return lastUnit.getPreviousActivity() else: return None def getDataFilePath(self): if os.name == "nt": dataFilePath = os.path.join(self.path, "data.txt") else: unit = self.parent level = unit.parent root = level.parent levelNumber = root.children.index(level) + 1 unitNumber = level.children.index(unit) + 1 activityNumber = unit.children.index(self) + 1 fileName = "data" + str(levelNumber) + "-" + str(unitNumber) + "-" + str(activityNumber) + ".txt" try: dataFilePath = os.path.join(olpcgames.util.get_activity_root(), fileName) except: dataFilePath = os.path.join(self.path, "data.txt") return dataFilePath def resetScore(self): if self.level == 4: dataFilePath = self.getDataFilePath() try: dataFile = open(dataFilePath, "r") dataFileText = dataFile.read() dataFile.close() except: dataFileText = "" dataFileText = dataFileText.replace("finished = 1", "finished = 0") dataFile = open(dataFilePath, "w") dataFile.write(dataFileText) dataFile.close() else: for c in self.children: c.resetScore() class MenuLevelItem(Control): def __init__(self, game, bodyImagePath, iconPath, iconPosition = (5,2)): Control.__init__(self, game) self.buttonBody = ImageControl(game, 0, 0, bodyImagePath, "", 2) self.__iconDeltaX = iconPosition[0] self.__iconDeltaY = iconPosition[1] self.icon = ImageControl(game, self.getX()+self.__iconDeltaX, self.getY()+self.__iconDeltaY, iconPath, "", 1) self.setHeight(self.buttonBody.getHeight()) self.setWidth(self.buttonBody.getWidth()) self.text = "" self.font = Font(game.makePath("Helvetica LT Condensed Black.ttf"), 15) #self.font = Font(game.makePath("niobrg_.ttf"), 15) self.textColor = (255,255,255) self.setLayer(1) self.tick = ImageControl(game, 0, 0, game.makePath("tick.png"), "", 1) self.tick.setColorKey((255,255,255)) self.__ticked = False def markAsDone(self): self.__ticked = True def open(self): self.buttonBody.setImageDivisionIndex(1) def close(self): self.buttonBody.setImageDivisionIndex(0) def setX(self, newX): Control.setX(self, newX) self.buttonBody.setX(newX) self.icon.setX(newX + self.__iconDeltaX) self.tick.setX(newX + 120) def setY(self, newY): Control.setY(self, newY) self.buttonBody.setY(newY) self.icon.setY(newY + self.__iconDeltaY) self.tick.setY(newY + 3) def show(self, surface): dirtyRect = self.game.getDirtyRect() myRect = self.getRect() if dirtyRect.colliderect(myRect): self.buttonBody.show(surface) self.icon.show(surface) if self.__ticked: self.tick.show(surface) if self.text != "": textRect = Rect(self.getX()+ self.__iconDeltaX + self.icon.getWidth(), self.getY() + self.getHeight()/3, self.getWidth() - self.icon.getWidth()-self.__iconDeltaX, self.getHeight()/3) text = self.font.render(self.text, True, self.textColor) surface.blit(text, textRect) class HeadUpDisplay(): def __init__(self, game): self.game = game self.xMargin = game.xMargin self.yMargin = game.yMargin self.levelMarker = None self.cabezalBase = None self.actTypeNameLabel = None self.unitNameLabel = None self.unitMarker = None def show(self, levelNumber, unitName, activityTypeName): self.showLevelNumber(levelNumber) self.showCabezalBase() self.showActTypeName(activityTypeName) self.showUnitName(unitName) self.showUnitMarker() def makePath(self, fileName): return self.game.makePath(fileName) def showLevelNumber(self, levelNumber): fileName = "lvl_marker_" + str(levelNumber) + ".png" self.levelMarker = ImageControl(self.game, 50 + self.xMargin, 50 + self.yMargin, self.makePath(fileName), "", 1) self.levelMarker.setLayer(7) self.game.getUiMgr().addControl(self.levelMarker) def hide(self): self.game.getUiMgr().removeControl(self.levelMarker) self.game.getUiMgr().removeControl(self.cabezalBase) self.game.getUiMgr().removeControl(self.actTypeNameLabel) self.game.getUiMgr().removeControl(self.unitNameLabel) self.game.getUiMgr().removeControl(self.unitMarker) def showCabezalBase(self): self.cabezalBase = ImageControl(self.game, 70 + self.xMargin, 50 + self.yMargin, self.makePath("cabezal_base.png"), "", 1) self.game.getUiMgr().addControl(self.cabezalBase) self.cabezalBase.setLayer(8) def showUnitName(self, unitName): font = Font(self.makePath("niobrg_.ttf"), 30) #self.unitNameLabel = Label(self.game, 400, 80, 400, 50, font, unitName.upper(), 5) self.unitNameLabel = Label(self.game, self.game.settings["unitNameLabelX"], self.game.settings["unitNameLabelY"], 400, 50, font, unitName.upper(), 5) self.unitNameLabel.background = None self.game.getUiMgr().addControl(self.unitNameLabel) def showActTypeName(self, actTypeName): font = Font(self.makePath("niobbl_.ttf"), 30) #self.actTypeNameLabel = Label(self.game, 720, 80, 400, 50, font, actTypeName.upper(), 5) self.actTypeNameLabel = Label(self.game, self.game.settings["actTypeNameX"], self.game.settings["actTypeNameY"], 400, 50, font, actTypeName.upper(), 5) self.actTypeNameLabel.color = (0,0,0) self.actTypeNameLabel.background = None self.game.getUiMgr().addControl(self.actTypeNameLabel) def showUnitMarker(self): unit = self.game.currentNode.parent fileName = os.path.join(unit.path, "unitMarker.png") self.unitMarker = ImageControl(self.game, 550 + self.xMargin, 50 + self.yMargin, fileName, "", 1) self.game.getUiMgr().addControl(self.unitMarker)