97 lines
2.9 KiB
Nim
97 lines
2.9 KiB
Nim
import gtk2, glib2, gdk2, cairo
|
|
|
|
const
|
|
Width = 600
|
|
Height = 460
|
|
|
|
type
|
|
Color = (float, float, float)
|
|
Edge {.pure.} = enum LT, TR, RB, BL
|
|
|
|
const
|
|
|
|
Edges = [[LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
|
|
[LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
|
|
[TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
|
|
[TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT],
|
|
[RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT],
|
|
[RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR],
|
|
[BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR],
|
|
[BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB],
|
|
[LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
|
|
[LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
|
|
[TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
|
|
[TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT]]
|
|
|
|
Black: Color = (0.0, 0.0, 0.0)
|
|
Blue: Color = (0.2, 0.3, 1.0)
|
|
White: Color = (1.0, 1.0, 1.0)
|
|
Yellow: Color = (0.8, 0.8, 0.0)
|
|
|
|
Colors: array[Edge, array[4, Color]] = [[White, Black, Black, White],
|
|
[White, White, Black, Black],
|
|
[Black, White, White, Black],
|
|
[Black, Black, White, White]]
|
|
|
|
|
|
template setSource(ctx: ptr Context; color: Color) =
|
|
ctx.setSourceRgb(color[0], color[1], color[2])
|
|
|
|
|
|
proc draw(context: ptr Context) =
|
|
## Draw the pattern.
|
|
|
|
func line(x1, y1, x2, y2: float; color: Color) =
|
|
context.setSource(color)
|
|
context.moveTo(x1, y1)
|
|
context.lineTo(x2, y2)
|
|
context.stroke
|
|
|
|
context.setSource(Yellow)
|
|
context.rectangle(0, 0, Width, Height)
|
|
context.fill()
|
|
|
|
for x in 0..11:
|
|
let px = float(86 + x * 36)
|
|
for y in 0..11:
|
|
let py = float(16 + y * 36)
|
|
context.setSource(Blue)
|
|
context.rectangle(px, py, 24, 24)
|
|
context.fill()
|
|
let carray = Colors[Edges[y][x]]
|
|
context.setLineWidth(2)
|
|
line(px, py, px + 23, py, carray[0])
|
|
line(px + 23, py, px + 23, py + 23, carray[1])
|
|
line(px + 23, py + 23, px, py + 23, carray[2])
|
|
line(px, py + 23, px, py, carray[3])
|
|
|
|
|
|
proc onExposeEvent(area: PDrawingArea; event: PEventExpose; data: pointer): gboolean {.cdecl.} =
|
|
## Callback to draw/redraw the drawing area contents.
|
|
let context = cairoCreate(area.window)
|
|
context.draw()
|
|
result = true
|
|
|
|
|
|
proc onDestroyEvent(widget: PWidget; data: pointer): gboolean {.cdecl.} =
|
|
## Process the "destroy" event.
|
|
mainQuit()
|
|
|
|
|
|
nimInit()
|
|
let window = windowNew(WINDOW_TOPLEVEL)
|
|
window.setSizeRequest(Width, Height)
|
|
window.setTitle("Peripheral drift illusion")
|
|
|
|
# Create the drawing area.
|
|
let area = drawingAreaNew()
|
|
window.add area
|
|
|
|
# Connect the "expose" event to the callback to draw the pattern.
|
|
discard area.signalConnect("expose-event", SIGNAL_FUNC(onExposeEvent), nil)
|
|
|
|
# Quit the application if the window is closed.
|
|
discard window.signalConnect("destroy", SIGNAL_FUNC(onDestroyEvent), nil)
|
|
|
|
window.showAll()
|
|
main()
|