# As part of the Pitcher's Duel Project, I am conducting a comparative
# analysis of pygame GUI modules, and publishing the results on my blog.
# The comparison consists of implementing the same sample interface on
# each of the various GUIs.
#
# This code implements the interface using the Albow GUI library. For
# details on this library, see:
# http://www.cosc.canterbury.ac.nz/greg.ewing/python/Albow/
#
# The module author is: Gregory Ewing
#
# This source code is the work of David Keeney, dkeeney at travelbyroad dot net
#

# Import Modules
import pygame
from pygame.locals import *
import time
import math

# import gui stuff
from albow import widget, controls, fields
from newroot import NewRootWidget

screenSize = (640, 430)

# define the necessary callback functions.
# these are invoked by the gui widgets
#
def logAction(ed, text):
  """Add the text to the 'edit' window (callback function)"""
  ed.items.append(text)
  ed.text = '\n'.join(ed.items[-10:])
  ed.invalidate() # mark as dirty

# these classes extend the Albow classes slightly, to
# add writing to the log widget
class LoggingRadioButton(controls.RadioButton, controls.ButtonBase):
    pass

class LoggingCheckBox(controls.CheckBox, controls.ButtonBase):
    pass

class LoggingTextField(fields.TextField, controls.ButtonBase):
    def __init__(self, width=None, **kws):
        fields.TextField.__init__(self, width, **kws)
        self._prevText = self.text

    def attention_lost(self):
        if self.text != self._prevText:
            self.action()
            self._prevText = self.text

widget.Widget.fg_color = (10,0,10)
controls.Button.fg_color = (100,75,0)

# the body of the program is here
#
def main():
  """This function is called when the program starts. It initializes
  everything it needs, then runs in a loop until the function returns.
  """

  #Initialize Everything
  pygame.init()
  screen = pygame.display.set_mode(screenSize)
  pygame.display.set_caption('GUI Test - Albow')
  pygame.time.set_timer(pygame.USEREVENT, 200)

  # create GUI object
  gui = NewRootWidget(screen)
  gui.run_start(None)

  # create page label
  lbl = controls.Label('Pygame GUI Test Page - Albow', fg_color=(75,150,0))
  lbl.topleft = 29, 13
  gui.add(lbl)

  # create progress bar label
  #  progress bar itself is not implemented
  lbl4 = controls.Label('Progress Bar')
  lbl4.topleft = 356, 355
  gui.add(lbl4)

  # create edit box
  ed = controls.Label('\n'.join(('',)*15), width=250)
  ed.border_color = (10,0,10)
  ed.border_width = 1
  ed.margin = 15
  ed.topleft = 377, 22
  gui.add(ed)
  ed.items = [] #(250, 320)
  logAction(ed,'top line of input')
  logAction(ed,'second line of input')
  ed.text = '\n'.join(ed.items[-10:])

  # create CheckBoxes and add to gui
  cb1Val = [False,True,None]
  cb1 = LoggingCheckBox()
  cb1.action = lambda: logAction(ed, 'Check Box #1 clicked %s'%cb1.ref.get())
  cb1.ref = controls.ItemRef(cb1Val,0)
  cb1.topleft = 42, 45
  cb1L = controls.Label('Check box #1')
  cb1L.topleft = 62, 45
  gui.add((cb1, cb1L))
  cb2 = LoggingCheckBox()
  cb2.action = lambda: logAction(ed, 'Check Box #2 clicked %s'%cb2.ref.get())
  cb2.ref = controls.ItemRef(cb1Val,1)
  cb2.topleft = 42, 75
  cb2L = controls.Label('Check box #2')
  cb2L.topleft = 62, 75
  gui.add((cb2, cb2L))
  cb3 = LoggingCheckBox()
  cb3.action = lambda: logAction(ed, 'Check Box #3 clicked %s'%cb3.ref.get())
  cb3.topleft = 42, 103
  cb3.ref = controls.ItemRef(cb1Val,2)
  cb3L = controls.Label('Check box #3')
  cb3L.topleft = 62, 103
  gui.add((cb3, cb3L))

  # create radio buttons, put in table, and add to gui
  rb1Val = [None]
  rb1Ref = controls.ItemRef(rb1Val,0)
  rb1 = LoggingRadioButton()
  rb1.ref = rb1Ref
  rb1.setting = 1
  rb1.topleft = 200, 45
  rb1.action = lambda: logAction(ed, 'Radio Button #1 clicked %s'%rb1.ref.get())
  rb1L = controls.Label('Radio Button #1')
  rb1L.topleft = 220, 45
  gui.add((rb1, rb1L))
  rb2 = LoggingRadioButton()
  rb2.ref = rb1Ref
  rb2.setting = 2
  rb2.topleft = 200, 75
  rb2.action = lambda: logAction(ed, 'Radio Button #2 clicked %s'%rb2.ref.get())
  rb2L = controls.Label('Radio Button #2')
  rb2L.topleft = 220, 75
  gui.add((rb2, rb2L))
  rb3 = LoggingRadioButton()
  rb3.topleft = 200, 103
  rb3.ref = rb1Ref
  rb3.setting = 3
  rb3.action = lambda: logAction(ed, 'Radio Button #3 clicked %s'%rb3.ref.get())
  rb3L = controls.Label('Radio Button #3')
  rb3L.topleft = 220, 103
  gui.add((rb3, rb3L))

  # create txt box label
  lbl2 = controls.Label('Text Box')
  lbl2.topleft = 31, 145
  gui.add(lbl2)
  # create text box
  en = LoggingTextField('                                ')
  en.border_color = (0,0,0)
  en.topleft = 31, 170
  en.action = lambda: logAction(ed, 'Text field value changed %d'%len(en.text))
  gui.add(en)

  # add button
  btn1 = controls.Button('Button 1', action=lambda: logAction(ed,'Button 1 Clicked'))
  btn1.topleft = 30, 250
  gui.add(btn1)
  btn2 = controls.Button('Button 2', action=lambda: logAction(ed,'Button 2 Clicked'))
  btn2.topleft = 130, 250
  gui.add(btn2)
  btn3 = controls.Button('Button 3', action=lambda: logAction(ed,'Button 3 Clicked'))
  btn3.topleft = 30, 290
  gui.add(btn3)
  btn4 = controls.Button('Button 4', action=lambda: logAction(ed,'Button 4 Clicked'))
  btn4.topleft = 130, 290
  gui.add(btn4)

  # add image map
  imap = controls.ImageButton("clear.png", action=lambda: logAction(ed, 'ImageMap Clicked '))
  imap.topleft = 31, 340
  gui.add(imap)

  # make some insensitive
  btn2.enabled = False
  cb3.enabled = False

  #Main Loop
  while 1:

    #Handle Input Events
    for event in pygame.event.get():
      if event.type == QUIT:
          return
      elif event.type == KEYDOWN and event.key == K_ESCAPE:
          return

      # pass event to gui
      gui.process_input((event,))

      # clear background, and draw clock-spinner
      screen.fill((250, 250, 250))
      radius = 30
      spinPos = 240, 362
      sp2 = spinPos[0]+1, spinPos[1]
      progressAngle = int(time.time() % 15 * 24 - 90) #60
      pygame.draw.circle(screen, (180, 180, 180), spinPos, radius, 0)
      for angle in range(-90, progressAngle):
        a = angle*math.pi/180
        tgt = radius*math.cos(a)+spinPos[0], radius*math.sin(a)+spinPos[1]
        pygame.draw.line(screen, (254,254,254), spinPos, tgt, 2)
        pygame.draw.circle(screen, (0,0,0), spinPos, radius, 2)
        pygame.draw.circle(screen, (0,0,0), spinPos, radius+1, 3)
        pygame.draw.circle(screen, (0,0,0), sp2, radius, 2)
        pygame.draw.circle(screen, (0,0,0), sp2, radius+1, 3)
        pygame.draw.line(screen, (0,0,0), spinPos, tgt, 2)
        tgt = spinPos[0], spinPos[1]-radius
        pygame.draw.line(screen, (0,0,0), spinPos, tgt, 2)

      # Draw GUI
      gui.draw_gui()

      pygame.display.flip()

main()

Edited to include ButtonBase, and uncomment cb3.enabled line.
Advertisements