示例#1
0
文件: ui.py 项目: forana/weekend-ui
	def __init__(self,config,screen):
		self.reset(config)
		self.imageLoader = ImageLoader()
		self.screen = screen
示例#2
0
文件: ui.py 项目: forana/weekend-ui
class Display:
	def __init__(self,config,screen):
		self.reset(config)
		self.imageLoader = ImageLoader()
		self.screen = screen

	def setDefaultNav(self):
		self.x = 0
		self.y = 0
		self.scroll = 0

	def loadConfig(self,config):
		self.error = config.error
		self.theme = Theme(config)
		self.commandBases = config.get("bases",{})
		self.rootMenu = self._loadMenu(config.get("entries"),"home")

	def _loadMenu(self,menudict,defaultName = DEFAULT_MENU_NAME):
		if menudict is not None:
			menus = []
			if "menus" in menudict:
				for menu in menudict["menus"]:
					menus.append(self._loadMenu(menu))
			actions = []
			if "commands" in menudict:
				for command in menudict["commands"]:
					base = self.commandBases[command["base"]]
					args = command["args"] if "args" in command else []
					name = command["name"] if "name" in command else " ".join([base]+args)
					icon = command["icon"] if "icon" in command else None
					actions.append(Action(name, Command(base,args), icon))
			name = menudict["name"] if "name" in menudict else defaultName
			iconImagePath = menudict["icon"] if "icon" in menudict else None
			return Menu(name, menus + actions, iconImagePath)

	def reset(self,config):
		self.loadConfig(config)
		self.setDefaultNav()
		self.currentMenu = self.rootMenu
		self.menuStack = []
		self.dirty = True

	def home(self):
		self.menuStack = []
		self.currentMenu = self.rootMenu
		self.setDefaultNav()

	def navigate(self,menu):
		self.menuStack.append(self.currentMenu)
		self.currentMenu = menu
		self.setDefaultNav()

	"""
		Return true if successfully went back a screen, otherwise false.
	"""
	def back(self):
		if len(self.menuStack)>0:
			self.currentMenu = self.menuStack.pop()
			self.setMenuNav()
			return True
		return False

	#TODO
	def move(self,xmod,ymod):
		self.x += xmod
		if self.x >= self.theme.horizontalTiles:
			self.x = 0
		elif self.x < 0:
			self.x = self.theme.horizontalTiles -1
		self.y += ymod
		ymax = int(math.ceil(len(self.currentMenu.entries)*1.0/self.theme.horizontalTiles)) -1
		scrollMax = max(0,ymax - self.theme.verticalTiles + 1)
		lastRowCount = (len(self.currentMenu.entries) % self.theme.horizontalTiles) - 1
		if self.y < 0:
			self.y = ymax
			self.scroll = scrollMax
		elif self.y > ymax:
			self.y = 0
			self.scroll = 0
		elif self.y < self.scroll:
			self.scroll-=1
		elif self.y >= self.scroll + self.theme.verticalTiles:
			self.scroll+=1

		if self.y==ymax and self.x>lastRowCount and lastRowCount>=0:
			self.x=lastRowCount

		self.dirty = True

	def activateEntry(self):
		index = self.y*self.theme.verticalTiles + (self.x if self.y==0 else self.x+self.y)
		self.currentMenu.entries[index].activate(self)

	def checkDirty(self):
		ret = self.dirty
		self.dirty = False
		return ret

	def render(self):
		self.screen.fill(self.theme.bgColor)
		if self.error is not None:
			errorTextImage = pygame.font.SysFont(None,32).render(self.error, True, self.theme.fgColor)
			self.screen.blit(errorTextImage,ERROR_TEXT_OFFSET)
		else:
			if self.theme.bgImage is not None:
				self.screen.blit(self.imageLoader.getScaled(self.theme.bgImage,(self.screen.get_width(),self.screen.get_height())),(0,0))
			# entries
			boxWidth = int(math.floor((self.screen.get_width() - 2*self.theme.windowPadding - self.theme.scrollWidth) * 1.0 / self.theme.horizontalTiles))
			boxHeight = int(math.floor((self.screen.get_height() - 2*self.theme.windowPadding) * 1.0 / self.theme.verticalTiles))
			size = (boxWidth - 2*self.theme.boxPadding, boxHeight - 2*self.theme.boxPadding)
			h = 0
			v = 0
			for entry in self.currentMenu.entries:
				pos = (h*boxWidth + self.theme.boxPadding + self.theme.windowPadding, (v-self.scroll)*boxHeight + self.theme.boxPadding + self.theme.windowPadding)
				if h==self.x and v==self.y:
					self.screen.fill(self.theme.selectColor,pygame.Rect((h*boxWidth + self.theme.windowPadding,(v-self.scroll)*boxHeight + self.theme.windowPadding),(boxWidth,boxHeight)))
				image = None
				text = entry.name
				if entry.iconImageFile is not None:
					try:
						image = self.imageLoader.getScaled(entry.iconImageFile,size)
					except pygame.error as e:
						text = str(e)
						print e
				if image is None:
					image = pygame.font.SysFont(None,32).render(text, True, self.theme.bgColor)
				self.screen.fill(self.theme.fgColor,pygame.Rect(pos,size))
				self.screen.blit(image,pos,pygame.Rect((0,0),size))
				h+=1
				if h >= self.theme.horizontalTiles:
					h=0
					v+=1
			# scroll bar
			numRows = math.ceil(len(self.currentMenu.entries)*1.0/self.theme.horizontalTiles)
			scrollUnit = (self.screen.get_height() - 2.0*self.theme.windowPadding)/numRows
			pos = (self.screen.get_width()-self.theme.windowPadding-self.theme.scrollWidth, self.theme.windowPadding + self.scroll*scrollUnit)
			size = (self.theme.scrollWidth, scrollUnit*min(self.theme.verticalTiles,numRows))
			self.screen.fill(self.theme.fgColor, pygame.Rect(pos,size))