############################################################################# ## This file is part of TunnelHack II. ## ##-------------------------------------------------------------------------## ## Copyright 2007-2008 Bryce Schroeder ## ## bryce.schroeder@gmail.com ## ## http://www.ferazelhosting.net/~bryce/ ## ##-------------------------------------------------------------------------## ## This program is free software: you can redistribute it and/or modify ## ## it under the terms of the GNU General Public License as published by ## ## the Free Software Foundation, either version 3 of the License, or ## ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## ## along with this program. If not, see . ## ############################################################################# from .interface import IObj from .g import g import pygame, math STEPS = 20 MUL = [math.sin(math.pi/2/STEPS * x) for x in xrange(STEPS, 0, -1)] class IHealthBar(IObj): def init(self): self._scrollval = self._ticks = self._start = self._delta = 0 self._flashticks = 0 self._flashing = False def set_value(self, v, scroll=True, flashfirst=False): IObj.set_value(self, v) if scroll: self._ticks = STEPS self._delta = float(v) / self.p.maximum - self._scrollval self._start = self._scrollval else: self._scrollval = float(v) / self.p.maximum if flashfirst: self._flashticks = 30 self._flashing = True def animate(self): if self._flashticks: self._flashticks -= 1 if self._flashticks % 10 == 0: self._flashing = not self._flashing return True elif self._ticks: self._ticks -= 1 self._scrollval = self._start + self._delta * MUL[self._ticks] return True def render_self(self, theme, target, px, py): height = self.p.h * 16 if height < 2: raise NotImplementedError("IHealthBar requires height >= 2") theme.blit((14, 3), target, px, py) theme.blit((14, 5), target, px, py + (self.p.h - 1) * 16) for x in xrange(1, self.p.h - 1): theme.blit((14, 4), target, px, py + x * 16) if self._flashing: return color = self.p.color lt_color = [min(x + 32, 255) for x in color] dk_color = [max(x - 32, 0) for x in color] bar_height = int(math.ceil(self._scrollval * (height - 6))) target.lock() if bar_height > 0: pygame.draw.line(target, dk_color, (px + 4, py + height - 4), (px + 10, py + height - 4)) if bar_height == 3: pygame.draw.line(target, lt_color, (px + 4, py + height - 3 - bar_height), (px + 10, py + height - 3 - bar_height)) pygame.draw.line(target, color, (px + 4, py + height - 2 - bar_height), (px + 10, py + height - 2 - bar_height)) pygame.draw.line(target, lt_color, (px + 3, py + height - 2 - bar_height), (px + 3, py + height - 5)) pygame.draw.line(target, dk_color, (px + 11, py + height - 2 - bar_height), (px + 11, py + height - 5)) elif bar_height == 2: pygame.draw.line(target, lt_color, (px + 3, py + height - 3 - bar_height), (px + 11, py + height - 3 - bar_height)) elif bar_height >= 4: pygame.draw.line(target, lt_color, (px + 4, py + height - 3 - bar_height), (px + 10, py + height - 3 - bar_height)) pygame.draw.rect(target, color, (px + 4, py + height - 2 - bar_height, 7, bar_height - 2)) pygame.draw.line(target, lt_color, (px + 3, py + height - 2 - bar_height), (px + 3, py + height - 5)) pygame.draw.line(target, dk_color, (px + 11, py + height - 2 - bar_height), (px + 11, py + height - 5)) target.unlock() class IProgressBar(IObj): def init(self): self.progress=0 def render_self(self, theme, target, px, py): width = self.p['w'] self.progress=(((width-2)*4+7)*self.value)/100 theme.blit((10,5),target,px,py) for x in xrange(1,width-1): theme.blit((11,5),target,px+16*x,py) theme.blit((12,5),target,px+16*(width-1),py) for x in xrange(0,self.progress): if self.state in [self.FOCUSED,self.CLICKED]: theme.blit((9,5),target,(px+4*x-3),py) else: theme.blit((8,5),target,(px+4*x-3),py) class IControlBar(IHealthBar): def handle_click(self,x,y): self.value=y*100//(16*(self.p['h']-2)+28) class IRender_Bar(IObj): def init(self): self.progress=0 hieght=0 def render_self(self, theme, target, px, py): hieght = self.p['h']-1 theme.blit((0,7),target,px,py) for x in xrange(1,hieght-1): theme.blit((0,8),target,px,py+16*(x)) theme.blit((0,13),target,px,py+16*(hieght-1)) theme.blit((0,12),target,px,py+16*hieght) if self.state in [self.FOCUSED,self.CLICKED]: theme.blit((0,11),target,(px),py+self.progress) else: theme.blit((0,10),target,(px),py+self.progress) def handle_mouse(self,x,y): if not self.state in[self.CLICKED, self.TOGGLED]: return if y>7 and y<(16*(self.p['h']-3)+26): self.progress=y-7 if y>(self.p['h']*16-8): self.progress=self.p['h']*16-15 elif y<=7: self.progress=0 self.dirty=True class IScroll_Bar(IRender_Bar): def handle_click(self,x,y): if y<=7: self.progress=0 elif y>7 and y<(16*(self.p['h']-1)-8): self.progress=y-7 elif y<(16*(self.p['h']-3)+32): self.progress=(self.p['h']-1)*16-15 elif y>=(16*(self.p['h']-3)+32) and y<(16*(self.p['h']-3)+37): if self.progress>5: self.progress-=5 else: self.progress=0 elif y>=(16*(self.p['h']-3)+37) and y<(16*(self.p['h']-3)+42): if self.progress<(self.p['h']-1)*16-20: self.progress+=5 else: self.progress=(self.p['h']-1)*16-15 class ISnapping_Bar(IRender_Bar): def handle_click(self,x,y): count=self.p['c']-1 space=(16*(self.p['h']-3)+28) unit=(space-12)/count if y0: self.progress-=unit elif y