Skip to content

Instantly share code, notes, and snippets.

@coordt
Created August 28, 2009 20:19
Show Gist options
  • Save coordt/177202 to your computer and use it in GitHub Desktop.
Save coordt/177202 to your computer and use it in GitHub Desktop.
Create an iPhone-like button using python and cairo
#!/usr/bin/env python
"""
Create a button
"""
import sys, cairo, cairo_helpers
def roundedrec(context,x,y,w,h,r = 10):
"Draw a rounded rectangle"
# A****BQ
# H C
# * *
# G D
# F****E
context.move_to(x+r,y) # Move to A
context.line_to(x+w-r,y) # Straight line to B
context.curve_to(x+w,y,x+w,y,x+w,y+r) # Curve to C, Control points are both at Q
context.line_to(x+w,y+h-r) # Move to D
context.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h) # Curve to E
context.line_to(x+r,y+h) # Line to F
context.curve_to(x,y+h,x,y+h,x,y+h-r) # Curve to G
context.line_to(x,y+r) # Line to H
context.curve_to(x,y,x,y,x+r,y) # Curve to A
return
def left_pointed_rec(context,x,y,w,h,r = 10):
"Draw a left pointed, rounded rectangle"
# x
#y q4 A****B q1
# C
# G *
# D
# q3 F****E q2
arrow_height = -6
pt_a = (x+r+arrow_height, y)
pt_b = (x+w-r, y)
pt_q1 = (x+w, y)
pt_c = (x+w, y+r)
pt_d = (x+w, y+h-r)
pt_q2 = (x+w, y+h)
pt_e = (x+w-r, y+h)
pt_f = (x+r+arrow_height, y+h)
pt_q3 = (x+arrow_height, y+h)
pt_g = (x, y+(h/2))
pt_q4 = (x+arrow_height, y)
context.move_to(*pt_a) # Move to A
context.line_to(*pt_b) # Straight line to B
context.curve_to(*(pt_q1 + pt_q1 + pt_c)) # Curve to C
context.line_to(*pt_d) # Line to D
context.curve_to(*(pt_q2 + pt_q2 + pt_e)) # Curve to E
context.line_to(*pt_f) # Line to F
context.line_to(*pt_g) # Line to G
context.line_to(*pt_a) # Line to A
return
def right_pointed_rec(context,x,y,w,h,r = 10):
"Draw a left pointed, rounded rectangle"
# A****B
# G
# C
# F
# E****D
arrow_height = -6
pt_a = (x+r, y)
pt_b = (x+w-r-arrow_height, y)
pt_q1 = (x+w, y)
pt_c = (x+w, y+(h/2))
pt_d = (x+w-r-arrow_height, y+h)
pt_q2 = (x+w, y+h)
pt_e = (x+r, y+h)
pt_f = (x, y+h-r)
pt_q3 = (x, y+h)
pt_g = (x, y+r)
pt_q4 = (x, y)
context.move_to(*pt_a) # Move to A
context.line_to(*pt_b) # Straight line to B
context.line_to(*pt_c) # Line to C
context.line_to(*pt_d) # Line to D
context.line_to(*pt_e) # Line to E
context.curve_to(*(pt_q3 + pt_q3 + pt_f)) # Curve to F
context.line_to(*pt_g) # Line to G
context.curve_to(*(pt_q4 + pt_q4 + pt_a)) # Curve to A
return
def drawButton(cr, button_width, button_height, btn_text, topcolor, bottomcolor,
background=None, btntype='rounded', font="Helvetica Neue Bold"):
"""Draw a generic iphone button and return the context"""
highlight_top = cairo_helpers.RGBColor(255,255,255,0.4) # 60% white
highlight_bottom = cairo_helpers.RGBColor(0,255,0,0.0) # Transparent
if background:
cr.rectangle(0,0,button_width, button_height)
red, green, blue, alpha = background.as_float()
cr.set_source_rgba(red, green, blue, alpha)
cr.fill()
# Create the button outline and mask it
if btntype == 'rounded':
btnfunc = roundedrec
elif btntype == 'roundedleft':
btnfunc = left_pointed_rec
elif btntype == 'roundedright':
btnfunc = right_pointed_rec
btnfunc(cr, 0, 0, button_width, button_height, 12)
cr.clip()
# Set up the gradients
gradient = cairo_helpers.LinearGradient(x1=0.0,y1=0.0, x2=0.0,y2=1.0)
gradient.add_color_stop(topcolor, 0.0)
gradient.add_color_stop(bottomcolor, 0.8)
gradient2 = cairo_helpers.LinearGradient(x1=0.0,y1=0.0, x2=0.0,y2=1.0)
gradient2.add_color_stop(highlight_top, 0.0)
gradient2.add_color_stop(highlight_bottom, 1.0)
# Transform the coordinates so the width and height are both 1
# We save the current settings and restore them afterward
cr.save()
cr.scale(button_width, button_height)
cr.rectangle(0,0,1,1)
cr.set_source_rgb(0,0,1)
cr.set_source(gradient.pat)
cr.fill()
cr.rectangle(0,0.05,1,0.5)
cr.set_source(gradient2.pat)
cr.fill()
cr.restore()
# Draw the button text
cr.select_font_face (font,
cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size (14)
# Center the text
x_bearing, y_bearing, width, height, x_advance, y_advance = cr.text_extents(btn_text)
x = (button_width/2.0)-(width/2.0 + x_bearing)
y = (button_height/2.0)-(height/2.0 + y_bearing)
# Offset by 1 pixel to draw a shadow
cr.move_to (x-1, y-1)
cr.set_source_rgba (0,0,0,0.4) # Black, 40% transparent
cr.show_text(btn_text)
# start the button text
cr.move_to (x, y)
cr.set_source_rgba (1,1,1,1) # White
cr.show_text (btn_text)
# Draw the border of the button
cr.set_source_rgba (0,0,0,1)
btnfunc(cr, 0, 0, button_width, button_height, 12)
cr.stroke()
return cr
def drawGreenButton(button_text, filename, button_width, button_height):
bkgnd = cairo_helpers.RGBColor(255,255,255)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, button_width, button_height)
cr = cairo.Context(surface)
light = cairo_helpers.RGBColor(103, 225, 66)
dark = cairo_helpers.RGBColor(47, 111, 22)
drawButton(cr, button_width, button_height, button_text, light, dark, bkgnd)
surface.write_to_png(filename)
def drawRedButton(button_text, filename, button_width, button_height):
bkgnd = cairo_helpers.RGBColor(255,255,255)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, button_width, button_height)
cr = cairo.Context(surface)
light = cairo_helpers.RGBColor(232, 66, 34)
dark = cairo_helpers.RGBColor(114, 19, 12)
drawButton(cr, button_width, button_height, button_text, light, dark, bkgnd)
surface.write_to_png(filename)
def drawBlueButton(button_text, filename, button_width, button_height, btntype='rounded'):
bkgnd = cairo_helpers.RGBColor(255,255,255)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, button_width, button_height)
cr = cairo.Context(surface)
light = cairo_helpers.RGBColor(34, 95, 218)
dark = cairo_helpers.RGBColor(25, 67, 149)
drawButton(cr, button_width, button_height, button_text, light, dark, bkgnd, btntype)
surface.write_to_png(filename)
def drawArrowButtons():
bkgnd = cairo_helpers.RGBColor(255,255,255)
button_width = 19
button_height = 17
button_text = ' '
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, button_width, button_height)
cr = cairo.Context(surface)
light = cairo_helpers.RGBColor(34, 95, 218)
dark = cairo_helpers.RGBColor(25, 67, 149)
drawButton(cr, button_width, button_height, button_text, light, dark, bkgnd, 'roundedleft', 'Webdings')
surface.write_to_png('arrowprevious.png')
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, button_width, button_height)
cr = cairo.Context(surface)
light = cairo_helpers.RGBColor(34, 95, 218)
dark = cairo_helpers.RGBColor(25, 67, 149)
drawButton(cr, button_width, button_height, button_text, light, dark, bkgnd, 'roundedright', 'Webdings')
surface.write_to_png('arrownext.png')
if __name__ == '__main__':
button_width = 100
button_height = 24
green_button_list = [
('Accept','accept.png'),
('Continue','continue.png'),
('Apply','apply.png'),
('Start','button_go.png'),
('Login', 'login.png'),
('Check Out', 'checkout.png'),
('Edit Ad', 'editad.png'),
('Publish Ad','publishad.png'),
('New Account', 'newaccount.png'),
]
green_long_btn_list = [
('Place Ad Now','place_ad_now.png'),
('Place Another','placeanotherad.png'),
('Save As Quote','saveasquote.png'),
]
blue_button_list = [
('Spell Check', 'checkspelling.png'),
('Add Inserts','addinserts.png'),
('Replace','replace.png'),
('Replace All','replaceall.png'),
('Ignore','ignore.png'),
('Reset','reset.png'),
('Ignore All','ignoreall.png'),
('Edit Account','editaccount.png'),
('Search','search.png'),
]
blue_long_btn_list = [
('Add Credit Card','addcreditcard.png'),
('Change Package','changepackage.png'),
('Update Price','updatepreview.png'),
]
red_button_list = [
('Previous','previous.png'),
('Back','back.png'),
('Cancel', 'cancel.png'),
('Logoff', 'logoff.png'),
('Expire Ad','expiread.png'),
('Kill Order','killorder.png'),
]
# for item in green_button_list:
# drawGreenButton(item[0], item[1], button_width, button_height)
# for item in green_long_btn_list:
# drawGreenButton(item[0], item[1], button_width+20, button_height)
# for item in red_button_list:
# drawRedButton(item[0], item[1], button_width, button_height)
# for item in blue_button_list:
# drawBlueButton(item[0], item[1], button_width, button_height)
# for item in blue_long_btn_list:
# drawBlueButton(item[0], item[1], button_width+20, button_height)
#drawBlueButton(u'<', 'arrowleft.png', button_width, button_height, 'roundedleft')
#drawArrowButtons()
drawGreenButton('Apply Updates', 'applyupdates.png', button_width+20, button_height)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment