#############################################################################
## 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