Example #1
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(800, 600, "Hi")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray50))

	fontData, err := ioutil.ReadFile(sysFont("幼圆")) //this font comes from windows
	if err != nil {
		log.Fatalf("error reading font: %v", err)
	}
	font, err := driver.CreateFont(fontData, 50)
	if err != nil {
		panic(err)
	}
	label := theme.CreateLabel()
	label.SetFont(font)
	label.SetColor(gxui.Red50)
	label.SetText("支持一下中文")

	button := theme.CreateButton()
	button.SetText("点我一下")

	window.AddChild(label)
	window.AddChild(button)

	window.OnClose(driver.Terminate)

}
Example #2
0
File: main.go Project: ww24/goss
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)
	img := theme.CreateImage()

	// mx := source.Bounds().Max
	// fmt.Println(mx)

	window := theme.CreateWindow(500, 500, "Screenshot")
	size := window.Viewport().SizePixels()
	fmt.Println(size)
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(img)

	go func() {
		for {
			source, err := goss.Capture()
			if err != nil {
				fmt.Fprintln(os.Stderr, "Failed to capture screenshot.")
				os.Exit(1)
			}

			rgba := image.NewRGBA(source.Bounds())
			draw.Draw(rgba, source.Bounds(), source, image.ZP, draw.Src)
			texture := driver.CreateTexture(rgba, 1)
			img.SetTexture(texture)
		}
	}()

	window.OnClose(driver.Terminate)
}
Example #3
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	// ┌───────┐║┌───────┐
	// │       │║│       │
	// │   A   │║│   B   │
	// │       │║│       │
	// └───────┘║└───────┘
	// ═══════════════════
	// ┌───────┐║┌───────┐
	// │       │║│       │
	// │   C   │║│   D   │
	// │       │║│       │
	// └───────┘║└───────┘

	splitterAB := theme.CreateSplitterLayout()
	splitterAB.SetOrientation(gxui.Horizontal)
	splitterAB.AddChild(panelHolder("A", theme))
	splitterAB.AddChild(panelHolder("B", theme))

	splitterCD := theme.CreateSplitterLayout()
	splitterCD.SetOrientation(gxui.Horizontal)
	splitterCD.AddChild(panelHolder("C", theme))
	splitterCD.AddChild(panelHolder("D", theme))

	vSplitter := theme.CreateSplitterLayout()
	vSplitter.SetOrientation(gxui.Vertical)
	vSplitter.AddChild(splitterAB)
	vSplitter.AddChild(splitterCD)

	window := theme.CreateWindow(800, 600, "Panels")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(vSplitter)
	window.OnClose(driver.Terminate)
}
Example #4
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(500, 200, "Launch")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray10))

	layout := theme.CreateLinearLayout()
	layout.SetDirection(gxui.TopToBottom)

	searchBox := theme.CreateTextBox()
	searchBox.SetDesiredWidth(500)
	searchBox.SetMargin(math.Spacing{L: 4, T: 2, R: 4, B: 2})

	layout.AddChild(searchBox)

	adapter := gxui.CreateDefaultAdapter()

	searchBox.OnKeyDown(func(ev gxui.KeyboardEvent) {
		res := search.Search(searchBox.Text())
		adapter.SetItems(res.NameList())
	})

	droplist := theme.CreateDropDownList()
	droplist.SetAdapter(adapter)

	layout.AddChild(droplist)

	window.AddChild(layout)
	window.OnClose(driver.Terminate)

}
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(ANIMATION_WIDTH, 2*ANIMATION_HEIGHT, "Pendulum")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray50))

	image := theme.CreateImage()

	ticker := time.NewTicker(time.Millisecond * 15)
	pendulum := &mathematicalPendulum{}
	pendulum2 := &numericalPendulum{PHI_ZERO, 0.0, 0.0, time.Time{}}

	go func() {
		for _ = range ticker.C {
			canvas := driver.CreateCanvas(math.Size{ANIMATION_WIDTH, 2 * ANIMATION_HEIGHT})
			canvas.Clear(gxui.White)

			draw(pendulum, canvas, 0, 0)
			draw(pendulum2, canvas, 0, ANIMATION_HEIGHT)

			canvas.Complete()
			driver.Call(func() {
				image.SetCanvas(canvas)
			})
		}
	}()

	window.AddChild(image)

	window.OnClose(ticker.Stop)
	window.OnClose(driver.Terminate)
}
Example #6
0
func mainView(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	layout := theme.CreateLinearLayout()
	layout.SetSizeMode(gxui.Fill)

	window := theme.CreateWindow(800, 600, "Snmp Viewer")
	window.SetScale(flags.DefaultScaleFactor)
	window.OnClose(driver.Terminate)

	// テキストボックス
	ipText := createIpText(theme)

	// ボタン -----
	goButton := theme.CreateButton()
	goButton.SetText("GO")

	okClick := func(gxui.MouseEvent) {
		log.Println("clicked ok button")
		resultList := makeResultText(theme)
		layout.AddChild(resultList)
	}
	goButton.OnClick(okClick)

	// レイアウトに追加
	layout.AddChild(ipText)
	layout.AddChild(goButton)

	// windowに設定
	window.AddChild(layout)

}
Example #7
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	label := theme.CreateLabel()
	label.SetText("This is a progress bar:")

	progressBar := theme.CreateProgressBar()
	progressBar.SetDesiredSize(math.Size{W: 400, H: 20})
	progressBar.SetTarget(100)

	layout := theme.CreateLinearLayout()
	layout.AddChild(label)
	layout.AddChild(progressBar)
	layout.SetHorizontalAlignment(gxui.AlignCenter)

	window := theme.CreateWindow(800, 600, "Progress bar")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(layout)
	window.OnClose(driver.Terminate)

	progress := 0
	pause := time.Millisecond * 500
	var timer *time.Timer
	timer = time.AfterFunc(pause, func() {
		driver.Call(func() {
			progress = (progress + 3) % progressBar.Target()
			progressBar.SetProgress(progress)
			timer.Reset(pause)
		})
	})
}
Example #8
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	overlay := theme.CreateBubbleOverlay()

	holder := theme.CreatePanelHolder()
	holder.AddPanel(numberPicker(theme, overlay), "Default adapter")
	holder.AddPanel(colorPicker(theme), "Custom adapter")

	window := theme.CreateWindow(800, 600, "Lists")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(holder)
	window.AddChild(overlay)
	window.OnClose(driver.Terminate)
	window.SetPadding(math.Spacing{L: 10, T: 10, R: 10, B: 10})
}
Example #9
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)
	window := theme.CreateWindow(800, 600, "gxpl")
	list := theme.CreateList()
	adapter := newFileAdapter()
	list.SetSize(math.Size{math.MaxInt, math.MaxInt})
	list.SetAdapter(adapter)
	list.OnItemClicked(func(e gxui.MouseEvent, item gxui.AdapterItem) {
		if e.Button != gxui.MouseButtonLeft {
			return
		}
		fi := item.(os.FileInfo)
		if fi.IsDir() {
			mvdir(fi.Name())
			adapter.Reload()
		}
	})

	reloadButton := theme.CreateButton()
	reloadButton.SetText("Reload")
	reloadButton.OnClick(func(e gxui.MouseEvent) {
		adapter.Reload()
	})
	backButton := theme.CreateButton()
	backButton.SetText("Back")
	backButton.OnClick(func(e gxui.MouseEvent) {
		mvdir("..")
		adapter.Reload()
	})
	layoutButton := theme.CreateLinearLayout()
	layoutButton.SetDirection(gxui.RightToLeft)
	layoutButton.AddChild(reloadButton)
	layoutButton.AddChild(backButton)
	layout := theme.CreateLinearLayout()
	layout.SetDirection(gxui.TopToBottom)
	layout.SetSizeMode(gxui.Fill)
	layout.AddChild(layoutButton)
	layout.AddChild(list)
	window.AddChild(layout)
	window.OnClose(driver.Terminate)
}
Example #10
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	canvas := driver.CreateCanvas(math.Size{W: 800, H: 600})

	for i := 0; i < 800; i++ {
		var fy = maths.Sin(float64(i) * (maths.Pi / 180))
		y := (int(fy*100) + 240)
		plot(canvas, i, y)
	}

	canvas.Complete()

	image := theme.CreateImage()
	image.SetCanvas(canvas)

	window := theme.CreateWindow(800, 600, "")
	window.AddChild(image)
	window.OnClose(driver.Terminate)

}
Example #11
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)
	window := theme.CreateWindow(800, 600, "Polygon")
	window.SetScale(flags.DefaultScaleFactor)

	canvas := driver.CreateCanvas(math.Size{W: 1000, H: 1000})
	drawStar(canvas, math.Point{X: 100, Y: 100}, 50, 0.2, 6)
	drawStar(canvas, math.Point{X: 650, Y: 170}, 70, 0.5, 7)
	drawStar(canvas, math.Point{X: 40, Y: 300}, 20, 0, 5)
	drawStar(canvas, math.Point{X: 410, Y: 320}, 25, 0.9, 5)
	drawStar(canvas, math.Point{X: 220, Y: 520}, 45, 0, 6)

	drawMoon(canvas, math.Point{X: 400, Y: 300}, 200)
	canvas.Complete()

	image := theme.CreateImage()
	image.SetCanvas(canvas)
	window.AddChild(image)

	window.OnClose(driver.Terminate)
}
Example #12
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)
	window := theme.CreateWindow(800, 600, "Polygon")

	container := theme.CreateLinearLayout()

	//	texture := driver.CreateTexture(getImage(cacheDir, tweet.User.ProfileImageURL), 96)
	f, err := os.Open("data/icont19.png")
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	im, _, err := image.Decode(f)
	if err != nil {
		log.Fatalln(err)
	}

	for i := 0; i < 100; i++ {
		pict := theme.CreateImage()
		texture := driver.CreateTexture(im, 96)
		texture.SetFlipY(true)
		pict.SetTexture(texture)
		pict.SetExplicitSize(math.Size{32, 32})
		pict.SetMargin(math.CreateSpacing(4))
		container.AddChild(pict)
	}

	label := theme.CreateLabel()
	label.SetText("hogehogehoge")
	label.SetMargin(math.CreateSpacing(200))
	container.AddChild(label)

	window.OnClose(driver.Terminate)

	window.AddChild(container)

	gxui.EventLoop(driver)
}
Example #13
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(200, 150, "Window")
	window.OnClose(driver.Terminate)
	window.SetScale(flags.DefaultScaleFactor)
	window.SetPadding(math.Spacing{L: 10, R: 10, T: 10, B: 10})
	button := theme.CreateButton()
	button.SetHorizontalAlignment(gxui.AlignCenter)
	button.SetSizeMode(gxui.Fill)
	toggle := func() {
		fullscreen := !window.Fullscreen()
		window.SetFullscreen(fullscreen)
		if fullscreen {
			button.SetText("Make windowed")
		} else {
			button.SetText("Make fullscreen")
		}
	}
	button.SetText("Make fullscreen")
	button.OnClick(func(gxui.MouseEvent) { toggle() })
	window.AddChild(button)
}
Example #14
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	font, err := driver.CreateFont(gxfont.Default, 75)
	if err != nil {
		panic(err)
	}

	window := theme.CreateWindow(380, 100, "Hi")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray50))

	label := theme.CreateLabel()
	label.SetFont(font)
	label.SetText("Hello world")

	window.AddChild(label)

	ticker := time.NewTicker(time.Millisecond * 30)
	go func() {
		phase := float32(0)
		for _ = range ticker.C {
			c := gxui.Color{
				R: 0.75 + 0.25*math.Cosf((phase+0.000)*math.TwoPi),
				G: 0.75 + 0.25*math.Cosf((phase+0.333)*math.TwoPi),
				B: 0.75 + 0.25*math.Cosf((phase+0.666)*math.TwoPi),
				A: 0.50 + 0.50*math.Cosf(phase*10),
			}
			phase += 0.01
			driver.Call(func() {
				label.SetColor(c)
			})
		}
	}()

	window.OnClose(ticker.Stop)
	window.OnClose(driver.Terminate)
}
Example #15
0
func AppMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	layout := theme.CreateLinearLayout()

	label := theme.CreateLabel()
	label.SetFont(CreateFont(15, driver))
	label.SetText("Path To Folder")
	layout.AddChild(label)

	textBox := theme.CreateTextBox()
	textBox.SetFont(CreateFont(15, driver))
	textBox.SetDesiredWidth(300)
	layout.AddChild(textBox)

	button := theme.CreateButton()
	button.SetText("Parse Docs")

	action := func() {
		fmt.Println("What the heck")
	}

	button.OnClick(func(gxui.MouseEvent) {
		action()
	})
	layout.AddChild(button)

	vSplitter := theme.CreateSplitterLayout()
	vSplitter.SetOrientation(gxui.Vertical)
	vSplitter.AddChild(layout)

	window := theme.CreateWindow(600, 400, "Office File Parser")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray10))
	window.AddChild(vSplitter)
	window.OnClose(driver.Terminate)
}
Example #16
0
func appMain(driver gxui.Driver) {
	args := flag.Args()
	if len(args) != 1 {
		fmt.Print("usage: image_viewer image-path\n")
		os.Exit(1)
	}

	file := args[0]
	f, err := os.Open(file)
	if err != nil {
		fmt.Printf("Failed to open image '%s': %v\n", file, err)
		os.Exit(1)
	}

	source, _, err := image.Decode(f)
	if err != nil {
		fmt.Printf("Failed to read image '%s': %v\n", file, err)
		os.Exit(1)
	}

	theme := dark.CreateTheme(driver)
	img := theme.CreateImage()

	mx := source.Bounds().Max
	window := theme.CreateWindow(mx.X, mx.Y, "Image viewer")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(img)

	// Copy the image to a RGBA format before handing to a gxui.Texture
	rgba := image.NewRGBA(source.Bounds())
	draw.Draw(rgba, source.Bounds(), source, image.ZP, draw.Src)
	texture := driver.CreateTexture(rgba, 1)
	img.SetTexture(texture)

	window.OnClose(driver.Terminate)
}
Example #17
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	layout := theme.CreateLinearLayout()
	layout.SetSizeMode(gxui.Fill)

	buttonState := map[gxui.Button]func() bool{}
	update := func() {
		for button, f := range buttonState {
			button.SetChecked(f())
		}
	}

	button := func(name string, action func(), isSelected func() bool) gxui.Button {
		b := theme.CreateButton()
		b.SetText(name)
		b.OnClick(func(gxui.MouseEvent) { action(); update() })
		layout.AddChild(b)
		buttonState[b] = isSelected
		return b
	}

	button("TopToBottom",
		func() { layout.SetDirection(gxui.TopToBottom) },
		func() bool { return layout.Direction().TopToBottom() },
	)
	button("LeftToRight",
		func() { layout.SetDirection(gxui.LeftToRight) },
		func() bool { return layout.Direction().LeftToRight() },
	)
	button("BottomToTop",
		func() { layout.SetDirection(gxui.BottomToTop) },
		func() bool { return layout.Direction().BottomToTop() },
	)
	button("RightToLeft",
		func() { layout.SetDirection(gxui.RightToLeft) },
		func() bool { return layout.Direction().RightToLeft() },
	)

	button("AlignLeft",
		func() { layout.SetHorizontalAlignment(gxui.AlignLeft) },
		func() bool { return layout.HorizontalAlignment().AlignLeft() },
	)
	button("AlignCenter",
		func() { layout.SetHorizontalAlignment(gxui.AlignCenter) },
		func() bool { return layout.HorizontalAlignment().AlignCenter() },
	)
	button("AlignRight",
		func() { layout.SetHorizontalAlignment(gxui.AlignRight) },
		func() bool { return layout.HorizontalAlignment().AlignRight() },
	)

	button("AlignTop",
		func() { layout.SetVerticalAlignment(gxui.AlignTop) },
		func() bool { return layout.VerticalAlignment().AlignTop() },
	)
	button("AlignMiddle",
		func() { layout.SetVerticalAlignment(gxui.AlignMiddle) },
		func() bool { return layout.VerticalAlignment().AlignMiddle() },
	)
	button("AlignBottom",
		func() { layout.SetVerticalAlignment(gxui.AlignBottom) },
		func() bool { return layout.VerticalAlignment().AlignBottom() },
	)

	update()

	window := theme.CreateWindow(800, 600, "Linear layout")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(layout)
	window.OnClose(driver.Terminate)
	window.SetPadding(math.Spacing{L: 10, T: 10, R: 10, B: 10})
}
Example #18
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	layout := theme.CreateLinearLayout()
	layout.SetDirection(gxui.TopToBottom)

	animals := &adapter{
		node: node{
			name: "Animals",
			children: []node{
				node{
					name: "Mammals",
					children: []node{
						node{name: "Cats"},
						node{name: "Dogs"},
						node{name: "Horses"},
						node{name: "Duck-billed platypuses"},
					},
				},
				node{
					name: "Birds",
					children: []node{
						node{name: "Peacocks"},
						node{name: "Doves"},
					},
				},
				node{
					name: "Reptiles",
					children: []node{
						node{name: "Lizards"},
						node{name: "Turtles"},
						node{name: "Crocodiles"},
						node{name: "Snakes"},
					},
				},
				node{
					name: "Amphibians",
					children: []node{
						node{name: "Frogs"},
						node{name: "Toads"},
					},
				},
				node{
					name: "Arthropods",
					children: []node{
						node{
							name: "Crustaceans",
							children: []node{
								node{name: "Crabs"},
								node{name: "Lobsters"},
							},
						},
						node{
							name: "Insects",
							children: []node{
								node{name: "Ants"},
								node{name: "Bees"},
							},
						},
						node{
							name: "Arachnids",
							children: []node{
								node{name: "Spiders"},
								node{name: "Scorpions"},
							},
						},
					},
				},
			},
		},
	}

	tree := theme.CreateTree()
	tree.SetAdapter(animals)
	tree.Select("Doves")
	tree.Show(tree.Selected())

	layout.AddChild(tree)

	row := theme.CreateLinearLayout()
	row.SetDirection(gxui.LeftToRight)
	layout.AddChild(row)

	expandAll := theme.CreateButton()
	expandAll.SetText("Expand All")
	expandAll.OnClick(func(gxui.MouseEvent) { tree.ExpandAll() })
	row.AddChild(expandAll)

	collapseAll := theme.CreateButton()
	collapseAll.SetText("Collapse All")
	collapseAll.OnClick(func(gxui.MouseEvent) { tree.CollapseAll() })
	row.AddChild(collapseAll)

	window := theme.CreateWindow(800, 600, "Tree view")
	window.SetScale(flags.DefaultScaleFactor)
	window.AddChild(layout)
	window.OnClose(driver.Terminate)
	window.SetPadding(math.Spacing{L: 10, T: 10, R: 10, B: 10})
}
Example #19
0
func SetTheme() gxui.Theme {
	appTheme = dark.CreateTheme(appDriver)
	return appTheme
}
Example #20
0
func MainWindow(driver gxui.Driver) {
	theme = dark.CreateTheme(driver)

	fontData, err := ioutil.ReadFile("./fonts/Microsoft Yahei.ttf")
	if err != nil {
		log.Fatalf("error reading font: %v", err)
	}
	font, err := driver.CreateFont(fontData, 20)
	if err != nil {
		panic(err)
	}
	theme.SetDefaultFont(font)

	headLayout := theme.CreateLinearLayout()
	headLayout.SetSizeMode(gxui.Fill)
	headLayout.SetHorizontalAlignment(gxui.AlignCenter)
	headLayout.SetDirection(gxui.TopToBottom)
	headLayout.SetSize(math.Size{W: 100, H: 50})

	label := theme.CreateLabel()
	label.SetMargin(math.CreateSpacing(10))
	label.SetText("豆瓣FM红心歌单下载")

	headLayout.AddChild(label)

	bodyLayout := theme.CreateLinearLayout()
	bodyLayout.SetSizeMode(gxui.Fill)
	bodyLayout.SetHorizontalAlignment(gxui.AlignCenter)
	bodyLayout.SetSize(math.Size{W: 100, H: 400})
	bodyLayout.SetDirection(gxui.TopToBottom)
	// bodyLayout.SetMargin(math.Spacing{T: 50})

	userHint := theme.CreateLabel()
	userHint.SetMargin(math.CreateSpacing(10))
	userHint.SetText("用户名")
	bodyLayout.AddChild(userHint)
	usernameField := theme.CreateTextBox()
	bodyLayout.AddChild(usernameField)

	passHint := theme.CreateLabel()
	passHint.SetMargin(math.CreateSpacing(10))
	passHint.SetText("密码")
	bodyLayout.AddChild(passHint)
	passwordField := theme.CreateTextBox()
	bodyLayout.AddChild(passwordField)

	footLayout := theme.CreateLinearLayout()
	footLayout.SetSizeMode(gxui.Fill)
	footLayout.SetHorizontalAlignment(gxui.AlignCenter)
	footLayout.SetDirection(gxui.TopToBottom)
	// footLayout.SetMargin(math.Spacing{T: 450})

	button := theme.CreateButton()
	button.SetText("登录并下载")
	button.OnClick(func(gxui.MouseEvent) {
		user := usernameField.Text()
		password := passwordField.Text()
		if user == "" || password == "" {
			return
		}
		label.SetText(user + "&" + password)
	})
	footLayout.AddChild(button)

	window := theme.CreateWindow(600, 800, "豆瓣FM下载器")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.White))

	window.AddChild(headLayout)
	window.AddChild(bodyLayout)
	window.AddChild(footLayout)

	window.OnClose(driver.Terminate)
	window.SetPadding(math.Spacing{L: 10, T: 10, R: 10, B: 10})
}
Example #21
0
// CreateTheme creates and returns the theme specified on the command line.
// The default theme is dark.
func CreateTheme(driver gxui.Driver) gxui.Theme {
	if FlagTheme == "light" {
		return light.CreateTheme(driver)
	}
	return dark.CreateTheme(driver)
}
Example #22
0
func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(800, 600, "Open file...")
	window.SetScale(flags.DefaultScaleFactor)

	// fullpath is the textbox at the top of the window holding the current
	// selection's absolute file path.
	fullpath := theme.CreateTextBox()
	fullpath.SetDesiredWidth(math.MaxSize.W)

	// directories is the Tree of directories on the left of the window.
	// It uses the directoryAdapter to show the entire system's directory
	// hierarchy.
	directories := theme.CreateTree()
	directories.SetAdapter(&directoryAdapter{
		directory: directory{
			subdirs: roots.Roots(),
		},
	})

	// filesAdapter is the adapter used to show the currently selected directory's
	// content. The adapter has its data changed whenever the selected directory
	// changes.
	filesAdapter := &filesAdapter{}

	// files is the List of files in the selected directory to the right of the
	// window.
	files := theme.CreateList()
	files.SetAdapter(filesAdapter)

	open := theme.CreateButton()
	open.SetText("Open...")
	open.OnClick(func(gxui.MouseEvent) {
		fmt.Printf("File '%s' selected!\n", files.Selected())
		window.Close()
	})

	// If the user hits the enter key while the fullpath control has focus,
	// attempt to select the directory.
	fullpath.OnKeyDown(func(ev gxui.KeyboardEvent) {
		if ev.Key == gxui.KeyEnter || ev.Key == gxui.KeyKpEnter {
			path := fullpath.Text()
			if directories.Select(path) {
				directories.Show(path)
			}
		}
	})

	// When the directory selection changes, update the files list
	directories.OnSelectionChanged(func(item gxui.AdapterItem) {
		dir := item.(string)
		filesAdapter.SetFiles(filesAt(dir))
		fullpath.SetText(dir)
	})

	// When the file selection changes, update the fullpath text
	files.OnSelectionChanged(func(item gxui.AdapterItem) {
		fullpath.SetText(item.(string))
	})

	// When the user double-clicks a directory in the file list, select it in the
	// directories tree view.
	files.OnDoubleClick(func(gxui.MouseEvent) {
		path := files.Selected().(string)
		if fi, err := os.Stat(path); err == nil && fi.IsDir() {
			if directories.Select(path) {
				directories.Show(path)
			}
		} else {
			fmt.Printf("File '%s' selected!\n", path)
			window.Close()
		}
	})

	// Start with the CWD selected and visible.
	if cwd, err := os.Getwd(); err == nil {
		if directories.Select(cwd) {
			directories.Show(directories.Selected())
		}
	}

	splitter := theme.CreateSplitterLayout()
	splitter.SetOrientation(gxui.Horizontal)
	splitter.AddChild(directories)
	splitter.AddChild(files)

	topLayout := theme.CreateLinearLayout()
	topLayout.SetDirection(gxui.TopToBottom)
	topLayout.AddChild(fullpath)
	topLayout.AddChild(splitter)

	btmLayout := theme.CreateLinearLayout()
	btmLayout.SetDirection(gxui.BottomToTop)
	btmLayout.SetHorizontalAlignment(gxui.AlignRight)
	btmLayout.AddChild(open)
	btmLayout.AddChild(topLayout)

	window.AddChild(btmLayout)
	window.OnClose(driver.Terminate)
	window.SetPadding(math.Spacing{L: 10, T: 10, R: 10, B: 10})
}