Forum Archive

Difficulty with putting text on a button

clehrich

I'm fairly new to programming (since my old TRS-80 days!), so this may be obvious.

I'm trying to put text onto a button. I have two problems.

  1. The text is always oriented to the bottom-left, and I don't see a way to shift it relative to the frame;

  2. The new layered button suddenly doesn't do anything, though I haven't changed the code for touch_began.

The following example includes lots of stuff to demonstrate what does and doesn't work, and where I got it. The problem is in class TextBtn, which will appear in the top left of the screen if you run this.

Code:

from scene import *
from random import random   # unnecessary for this, but I didn't bother cutting it'
import sound

# iOS system written with Pythonista
#       http://omz-software.com/pythonista/

# Skeleton button system written by Landyquack:
#     https://gist.github.com/LandyQuack/5183934

# Base class for controls
class Window (Layer):
    # Create a default window
    def __init__(self,p,bounds):
                Layer.__init__(self, bounds)

                # Add ourself to parent layer list
                if p: p.add_layer(self)     

                self.background=Color(1,1,1)

    # Skeleton functions to be overriden        
    def touch_began(self,touch): pass
    def touch_moved(self,touch): pass
    def touch_ended(self,touch): pass

#-------------------------------------------------
class Button (Window):
    def __init__(self,p,b):
        Window.__init__(self,p,b)

        # Default to white border of thickness 1.0
        self.stroke = Color(1,1,1)
        self.stroke_weight=1
        self.image = 'Typicons48_Battery_Low'

    def touch_began(self,touch):
        new_color = Color(random(), random(), random())
        self.animate('background', new_color, 1.0)
        sound.play_effect('Crashing')
#-------------------------------------------------

# A window (a Layer) containing buttons
class ButtonBar (Window):
    def __init__(self,p,b,n):
        Window.__init__(self,p,b)

        # Parent window
        b = self.frame
        x = b.x

        for i in range(n):
            Button(self,Rect(x,b.y,b.w,b.h))
            x=x+128

#-------------------------------------------------

# A window (a Layer) containing Text
class Text (Window):
    def __init__(self,p,o,t,f,s):
        Window.__init__(self,p,Rect(o.x,o.y,0,0))
        self.tint = Color(0,0,0)
        self.text_img, ims = render_text(t,font_name=f, font_size=s)
        self.frame=Rect(o.x,o.y,ims.w,ims.h)

        self.image = self.text_img

    def touch_began(self,touch):
        sound.play_effect('Beep')
#-------------------------------------------------

# A window (a Layer) button containing Text
class TxtBtn (Window):
    def __init__(self, p, o, t, f, s):
        Window.__init__(self, p, Rect(o.x, o.y, 0, 0))
        # Create basic button background
        # Default to white border of thickness 1.0
        self.stroke = Color(1,1,1)
        self.stroke_weight=1

        # Create the base image for the text
        self.text_img, ims = render_text(t, font_name=f, font_size=s)
        self.frame = Rect(o.x, o.y, ims.w*1.1, ims.h)
        self.txt_layer = TextLayer(t, f, s)
        self.add_layer(self.txt_layer)

        # Call the background button image
        self.image = 'Test_Boat'

    def touch_began(self,touch):
        sound.play_effect('Beep')
#-------------------------------------------------

class MyApp (Scene):

    # This runs before any frames or layers are drawn
    def setup(self):

        # This is our background canvas (whole display)
        p = self.root_layer = Layer(self.bounds)

        center = self.bounds.center()

        # Create 2 primitive buttons as children of root layer
        Button(p,Rect(center.x + 80, center.y + 80, 128, 128))
        Button(p,Rect(center.x - 80, center.y - 80, 128, 128))

        # Now try a button bar
        ButtonBar (p,Rect(10,10,128,128),5)

        # And a label
        Text (p,Rect(10,200,100,100),'Woof', 'Arial', 100)

        # And a text-button
        TxtBtn (p,Rect(10,600,100,100),'Test', 'Times', 100)

    def draw(self):
        # White background - basically display.clear() before redraw
        background(1, 1, 1)

        self.root_layer.update(self.dt)
        self.root_layer.draw()

    def touch_began(self, touch):
        l=touch.layer
        if l is Window: l.touch_began(touch)

    def touch_moved(self, touch):
        l=touch.layer
        if l is Window: l.touch_moved(touch)

    def touch_ended(self, touch):
        l=touch.layer
        if l is Window: l.touch_ended(touch)

run(MyApp())
clehrich

A passing note:

LandyQuack's code also generates a dead space, visually blank, SW of multiples like ButtonBar. If you make ButtonBar generate last in the main MyApp (Scene) sequence, and move it up and right, you'll see a white space appear SW of the line of 5 buttons.

Anyone know why this happens? It's a dead space, and ideally we don't want to be using space on the screen that isn't good for something.