Subclassing Widgets

This example shows how to sublass a widget and override the handle() and draw() methods


import Fltk

class MyWidget extends Fltk.Box {

	event = 0
	pushed = false

	constructor(x, y) {
		base.constructor(x, y, 260, 120)
	}

	function handle(e) {
		switch(e) {
		case Fltk.Event.NO_EVENT:
			return 0
		case Fltk.Event.PUSH:
			event = e
			pushed = true
			redraw()
			return 1
		case Fltk.Event.RELEASE:
			event = e
			if (pushed) {
				pushed = false
				redraw()
				do_callback()
				// Fltk docs say: "never do anything after a callback, 
				// as the callback may delete the widget!"
			}
			return 1
		default:
			event = e
			redraw()
			return 1
		}	
	}
	
	function draw() {
		// back ground
		local bcolor = pushed ? Fltk.Color.WHITE : Fltk.Color.LIGHT1
		Fltk.rectf(x(), y(), w(), h(), bcolor)
		Fltk.color(Fltk.Color.BLACK)
		Fltk.arc(x() + 200, y() + 10, 20, 20, 0, 180)	
		Fltk.pie(x() + 200, y() + 10, 20, 20, 180, 360)

		local y = y() + 20
		local x = x() + 10 // note this shadows the method!
		Fltk.draw(Fltk.event_name(event), x, y)
		y += 20

		// x, y coordinates
		local rowx = x
		Fltk.loop(rowx, y, rowx, y - 10, rowx + 10, y - 5)
		rowx += 20
		Fltk.draw("x: " + Fltk.event_x(), rowx, y)
		rowx += 60
		Fltk.loop(rowx, y - 10, rowx + 10, y - 10, rowx + 5, y)
		rowx += 20
		Fltk.draw("y: " + Fltk.event_y(), rowx, y) 		
		y += 20

		// root x, y coordinates
		rowx = x
		Fltk.loop(rowx, y, rowx, y - 10, rowx + 10, y - 5)
		rowx += 20
		Fltk.draw("x: " + Fltk.event_x_root(), rowx, y)
		rowx += 60
		Fltk.loop(rowx, y - 10, rowx + 10, y - 10, rowx + 5, y)
		rowx += 20
		Fltk.draw("y: " + Fltk.event_y_root(), rowx, y) 		
		y += 20

		local buttons = Fltk.event_buttons()		
		if(buttons) {
			Fltk.draw("Button", x, y) 
			if(buttons & Fltk.MouseButton.ONE) {
				Fltk.draw("1", x + 55, y) 
			}
			if(buttons & Fltk.MouseButton.TWO) { 
				Fltk.draw("2", x + 65, y) 
			}
			if(buttons & Fltk.MouseButton.THREE) { 
				Fltk.draw("3", x + 75, y) 
			}
		}
		y += 20

		rowx = x
		Fltk.draw("key " + Fltk.event_key(), rowx, y)	
		rowx += 80
		Fltk.draw(Fltk.event_text(), rowx, y)
		rowx += 20
		if(Fltk.event_shift()) {
			const mesg = "SHIFT"
			local textwidth = Fltk.width(mesg)
			Fltk.draw(mesg, rowx, y)			
			Fltk.line(rowx, y, rowx + textwidth, y)
			rowx += textwidth + 5
			Fltk.polygon(rowx, y, rowx, y - 10, rowx + 10, y - 10, rowx + 10, y)
		}
		y += 20
	}
}

local window = Fltk.Window(300,160)
// draw custom widget
local custom = MyWidget(20, 20)
custom.callback(@(w) println("callback from widget " + w))

window.end()
window.show()
Fltk.run()




Complete Script

import Fltk

class MyWidget extends Fltk.Box {

	event = 0
	pushed = false

	constructor(x, y) {
		base.constructor(x, y, 260, 120)
	}

	function handle(e) {
		switch(e) {
		case Fltk.Event.NO_EVENT:
			return 0
		case Fltk.Event.PUSH:
			event = e
			pushed = true
			redraw()
			return 1
		case Fltk.Event.RELEASE:
			event = e
			if (pushed) {
				pushed = false
				redraw()
				do_callback()
				// Fltk docs say: "never do anything after a callback, 
				// as the callback may delete the widget!"
			}
			return 1
		default:
			event = e
			redraw()
			return 1
		}	
	}
	
	function draw() {
		// back ground
		local bcolor = pushed ? Fltk.Color.WHITE : Fltk.Color.LIGHT1
		Fltk.rectf(x(), y(), w(), h(), bcolor)
		Fltk.color(Fltk.Color.BLACK)
		Fltk.arc(x() + 200, y() + 10, 20, 20, 0, 180)	
		Fltk.pie(x() + 200, y() + 10, 20, 20, 180, 360)

		local y = y() + 20
		local x = x() + 10 // note this shadows the method!
		Fltk.draw(Fltk.event_name(event), x, y)
		y += 20

		// x, y coordinates
		local rowx = x
		Fltk.loop(rowx, y, rowx, y - 10, rowx + 10, y - 5)
		rowx += 20
		Fltk.draw("x: " + Fltk.event_x(), rowx, y)
		rowx += 60
		Fltk.loop(rowx, y - 10, rowx + 10, y - 10, rowx + 5, y)
		rowx += 20
		Fltk.draw("y: " + Fltk.event_y(), rowx, y) 		
		y += 20

		// root x, y coordinates
		rowx = x
		Fltk.loop(rowx, y, rowx, y - 10, rowx + 10, y - 5)
		rowx += 20
		Fltk.draw("x: " + Fltk.event_x_root(), rowx, y)
		rowx += 60
		Fltk.loop(rowx, y - 10, rowx + 10, y - 10, rowx + 5, y)
		rowx += 20
		Fltk.draw("y: " + Fltk.event_y_root(), rowx, y) 		
		y += 20

		local buttons = Fltk.event_buttons()		
		if(buttons) {
			Fltk.draw("Button", x, y) 
			if(buttons & Fltk.MouseButton.ONE) {
				Fltk.draw("1", x + 55, y) 
			}
			if(buttons & Fltk.MouseButton.TWO) { 
				Fltk.draw("2", x + 65, y) 
			}
			if(buttons & Fltk.MouseButton.THREE) { 
				Fltk.draw("3", x + 75, y) 
			}
		}
		y += 20

		rowx = x
		Fltk.draw("key " + Fltk.event_key(), rowx, y)	
		rowx += 80
		Fltk.draw(Fltk.event_text(), rowx, y)
		rowx += 20
		if(Fltk.event_shift()) {
			const mesg = "SHIFT"
			local textwidth = Fltk.width(mesg)
			Fltk.draw(mesg, rowx, y)			
			Fltk.line(rowx, y, rowx + textwidth, y)
			rowx += textwidth + 5
			Fltk.polygon(rowx, y, rowx, y - 10, rowx + 10, y - 10, rowx + 10, y)
		}
		y += 20
	}
}

local window = Fltk.Window(300,160)
// draw custom widget
local custom = MyWidget(20, 20)
custom.callback(@(w) println("callback from widget " + w))

window.end()
window.show()
Fltk.run()


List of All Examples
Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.