Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jul 5th, 2005, 10:47 PM   #1
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,888
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
Buttons!!

So yeah ... I got tired of trying to get wxpython and pygtk to work for me and make me those buttons, so I did something even better!!

import os, pygame, time, random, sys
from pygame.locals import *

if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'

def video_settings():
    pygame.init()
    pygame.display.set_caption('Soulodine v 0.2')
    screen = pygame.display.set_mode((800, 500))
    return screen

class Button(object):
    def __init__(self,screen,topleftrect,text):
        self.highlight = 'F'
        self.left1 =pygame.image.load('button_left_1.bmp')
        self.middle1=pygame.image.load('button_middle_1.bmp')
        self.right1=pygame.image.load('button_right_1.bmp')
        self.left3=pygame.image.load('button_left_3.bmp')
        self.middle3=pygame.image.load('button_middle_3.bmp')
        self.right3=pygame.image.load('button_right_3.bmp')
        self.left2=pygame.image.load('button_left_2.bmp')
        self.middle2=pygame.image.load('button_middle_2.bmp')
        self.right2=pygame.image.load('button_right_2.bmp')
        self.screen = screen
        self.co1 = (topleftrect)
        self.co2 = (topleftrect[0]+40+int(5.7*len(text)), topleftrect[1]+30)
        self.text = text

        self.draw()
        
    def draw(self):
        
        screen = self.screen

        if self.highlight == 'T':
            left=self.left1
            middle=self.middle1
            right=self.right1
        elif self.highlight == 'F':
            left=self.left2
            middle=self.middle2
            right=self.right2
        elif self.highlight == 'PRESS':
            left=self.left3
            middle=self.middle3
            right=self.right3  

        screen.blit(left,(self.co1))
        for a in range(self.co2[0]-self.co1[0]-5):
            screen.blit(middle,(self.co1[0]+5+a,self.co1[1]))
        screen.blit(right,(self.co2[0]-5,self.co1[1]))

        pygame.font.init()
        font=pygame.font.Font(None,17)
        text=font.render(self.text,2,(0,0,0))
        textpos=(self.co1[0]+20,self.co1[1]+8)
        
        screen.blit(text,textpos)
        pygame.display.flip()

        if self.highlight == 'PRESS':
            time.sleep(0.02)
            self.highlight = 'T'

    def Update(self, event, clicktype='LEFTCLICK'):
        if clicktype == 'LEFTCLICK':
            mousebutton = 1
        elif clicktype == 'RIGHTCLICK':
            mousebutton = 0
        self.but = mousebutton
            
        screen = self.screen
        self.Pressed = ''

        if event.type == MOUSEBUTTONDOWN:
            if event.button == mousebutton:
                if (event.pos[0] > self.co1[0]):
                    if (event.pos[0] < self.co2[0]):
                        if (event.pos[1] > self.co1[1]):
                            if (event.pos[1] < self.co2[1]):
                                self.Pressed = 'T'
                                self.highlight = 'PRESS'
                                self.down = 'T'
            
        elif event.type == MOUSEBUTTONUP:
            self.down = 'F'

        if event.type == MOUSEMOTION:
            if (event.pos[0] > self.co1[0])and(event.pos[0] < self.co2[0])and(event.pos[1] > self.co1[1])and(event.pos[1] < self.co2[1]):
                self.highlight = 'T'
                if self.down == 'T':
                    self.highlight = 'PRESS'
            else:
                self.highlight = 'F'
                self.down = 'F'
                
        self.draw()

And it's executed so easily!!!

from buttons import *

screen = video_settings()

Button1 = Button(screen, ( 500, 300 ), 'Testing Button')
Button2 = Button(screen, ( 300, 300 ), 'Tis A Button!')
Button3 = Button(screen, ( 100, 300 ), 'Testing The Button') 


def ExecuteButton1():
    print 'button1 has been pressed'
def ExecuteButton2():
    print 'button2 has been pressed'
def ExecuteButton3():
    print 'button3 has been pressed'


while 1:


    for event in pygame.event.get():
        
        Button1.Update( event )    
        Button2.Update( event )
        Button3.Update( event )

        if Button1.Pressed: ExecuteButton1()
        elif Button2.Pressed: ExecuteButton2()
        elif Button3.Pressed: ExecuteButton3()

Man it executes so well! I'm happy with myself.

For full code and graphics, download the 8 kb zip here: http://1v7.com/drsane/Button/

It's awesome because it figures out the size of the button for you and everything, and it gets highlighted when your cursor is on top. Turns brighter when you click it, and if you hold it it stays clicked until you let go or move the cursor off (but only executes the actual command when the button is clicked)!

It's not perfect at figuring out the center of where to place the font though, but it's pretty close.

And I haven't had time to clean up the code yet from when I was last messing with it to try something else.

If anyone wants to make me some button graphics it's very simple, three sets of the following: one 5 x 30, one 1 x 30, and a flip of the first 5 x 30 (as seen in the zip and ftp). For my buttons, the black around the edges is supposed to be transparent, but the best picture program I have is paint (yes I made the buttons in Paint).




EDIT: By the way, I fixed my problem with destroying the queue of keys pressed. I had the right idea with just throwing in an empty "for event in pygame.event.get()" . I was just putting it in the wrong place!! :eek:

As long as you go:
for event in pygame.event.get():"void"
after you used time.sleep. It won't queue the buttons you might have pressed while the time.sleep function was running!

Last edited by Sane; Jul 5th, 2005 at 10:59 PM.
Sane is offline   Reply With Quote
Old Jul 6th, 2005, 5:54 AM   #2
Cerulean
Professional Programmer
 
Cerulean's Avatar
 
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4 Cerulean is on a distinguished road
Why not move:
if Button1.Pressed: ExecuteButton1()
elif Button2.Pressed: ExecuteButton2()
elif Button3.Pressed: ExecuteButton3()
Into the Update function, and in the Button constructor pass a function that will be used as a callback. Just.. cleaner design.
Cerulean is offline   Reply With Quote
Old Jul 6th, 2005, 6:04 AM   #3
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,888
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
How would I make it so the user gets to decide what happens after the button is pressed then? And when the button can be pressed?
Sane is offline   Reply With Quote
Old Jul 6th, 2005, 6:11 AM   #4
Cerulean
Professional Programmer
 
Cerulean's Avatar
 
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4 Cerulean is on a distinguished road
Quote:
How would I make it so the user gets to decide what happens after the button is pressed then?
After the button is pressed? Well, if you have a callback:
def button1pressed():
    # code that I want to do after the button is pressed
mybutton1 = Button(...)
mybutton1.onclick = button1pressed
Then you put the code that you want to be executed in that function..?

Care to re-phrase what you mean by "when the button can be pressed"? Do you want to disable the button? If so, you should make a Button.disable and Button.enable function respectively. The Update function will call the callback as long as the mouse is down on the button and the button is not disabled.
Cerulean is offline   Reply With Quote
Old Jul 6th, 2005, 2:10 PM   #5
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,888
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
Well I mean with mine, you can tell the program exactly where to allow the processing of the button click and etc...I don't really get yours either so yours is probably the same. But either way I think mine works fine for the uses I'll need it for.
Sane is offline   Reply With Quote
Old Jul 6th, 2005, 3:27 PM   #6
Cerulean
Professional Programmer
 
Cerulean's Avatar
 
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4 Cerulean is on a distinguished road
Sure, i'm just saying it's generally not good to have different pieces of code that do different things split apart. Saves you a headache later, but yeah.
Cerulean is offline   Reply With Quote
Old Jul 6th, 2005, 4:38 PM   #7
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,888
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
HUZZAH!

Radio buttons!

For in my RPG where you get to select things like music/sfx volume and text scroll speed.

Complete Zip with Images and a practical example (8 kb): www.1v7.com/drsane/Button/ButtonsZip.zip

import pygame, sys
from pygame.locals import *
pygame.init()

class RadioButton(object):
    def __init__(self,screen,Buttons):

        topleftrect,text,values = [],[],[]
        
        for a in range(len(Buttons)):
            topleftrect.append(Buttons[a][0])
            text.append(Buttons[a][1])
            values.append(Buttons[a][2])
        
        if (len(values) == len(text)) and (len(topleftrect) == len(text)):
            self.screen = screen
            pygame.font.init()

            self.blank = pygame.image.load('images/radio_button_blank.bmp')
            self.clicked = pygame.image.load('images/radio_button_clicked.bmp')
            self.clicked_highlight = pygame.image.load('images/radio_button_clicked_highlight.bmp')
            self.highlight = pygame.image.load('images/radio_button_highlight.bmp')
            self.toggle = pygame.image.load('images/radio_button_toggle.bmp')
            
            for a in range (len(text)):
                                
                exec "self.highlight%d = 'F'"%(a)
                exec "self.clicked%d = 'F'"%(a)
                exec "self.co1%d = (topleftrect[a])"%(a)
                exec "self.co2%d = (topleftrect[a][0]+13, topleftrect[a][1]+13)"%(a)
                exec "self.text%d = text[a]"%(a)

            self.values = values
            self.amount = len(text)
            self.Toggled = False
            self.Toggle = ''
                
            self.draw()
            
        else:
            print 'Invalid Arguments (Must all be the same number of items)'

    def draw(self):
        screen = self.screen

        for a in range(self.amount):

            click = 'F'
            high = 'F'
            exec "if self.clicked%d == 'T': click = 'T'"%(a)
            exec "if self.highlight%d == 'T': high = 'T'"%(a)
            exec "if self.clicked%d == 'TOGGLE': click = 'TOGGLE'"%(a)
            exec "loc = self.co1%d"%(a)
            exec "text = self.text%d"%(a)


            font=pygame.font.Font(None,18)
            texta=font.render(text,0,(255,255,255))
            textpos=(loc[0]+7 - int((5.7*(len(text))/2)) , loc[1]+14)        
            screen.blit(texta,textpos)

            
            if click == 'TOGGLE':
                screen.blit(self.toggle, loc)
                pygame.display.flip()
                exec "self.clicked%d = 'T'"%(a)
            elif click == 'T' and high == 'T':
                screen.blit(self.clicked_highlight, loc)
                pygame.display.flip()
            elif click == 'T':
                screen.blit(self.clicked, loc)
                pygame.display.flip()
            elif click == 'F' and high == 'T':
                screen.blit(self.highlight, loc)
                pygame.display.flip()
            elif click == 'F':
                screen.blit(self.blank, loc)
                pygame.display.flip()

    def Update(self, event):
        screen = self.screen

        for a in range(self.amount):

            exec "loc1 = self.co1%d"%(a)
            exec "loc2 = self.co2%d"%(a)

            if event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    if (event.pos[0] > loc1[0]):
                        if (event.pos[0] < loc2[0]):
                            if (event.pos[1] > loc1[1]):
                                if (event.pos[1] < loc2[1]):
                                    for b in range(self.amount):
                                        exec "self.clicked%d = 'F'"%(b)
                                    exec"self.clicked%d = 'TOGGLE'"%(a)
                                    self.Toggle = self.values[a]
                                    self.Toggled = True

            if event.type == MOUSEMOTION:
                exec "self.highlight%d = 'F'"%(a)
                if (event.pos[0] > loc1[0]):
                    if (event.pos[0] < loc2[0]):
                        if (event.pos[1] > loc1[1]):
                            if (event.pos[1] < loc2[1]):
                                exec "self.highlight%d = 'T'"%(a)
                                
        self.draw()

And if you don't feel like downloading it, here's a pretty screenshot of what it can do (included in the zip), clicking vote only prints stuff though, it doesn't actually vote. But maybe when I learn how to do internet stuff in Python.


Last edited by Sane; Jul 6th, 2005 at 5:03 PM.
Sane is offline   Reply With Quote
Old Jul 6th, 2005, 9:04 PM   #8
Cerulean
Professional Programmer
 
Cerulean's Avatar
 
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4 Cerulean is on a distinguished road
Heh, sweet. Keep it up
Cerulean is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 3:19 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC