Created
August 28, 2009 20:19
-
-
Save coordt/177202 to your computer and use it in GitHub Desktop.
Create an iPhone-like button using python and cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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