Beispiel #1
0
func main() {
	X, err := xgbutil.NewConn()
	if err != nil {
		log.Fatal(err)
	}

	// Load some font. You may need to change the path depending upon your
	// system configuration.
	fontReader, err := os.Open(fontPath)
	if err != nil {
		log.Fatal(err)
	}

	// Now parse the font.
	font, err := xgraphics.ParseFont(fontReader)
	if err != nil {
		log.Fatal(err)
	}

	// Create some canvas.
	ximg := xgraphics.New(X, image.Rect(0, 0, canvasWidth, canvasHeight))
	ximg.For(func(x, y int) xgraphics.BGRA {
		return bg
	})

	// Now write the text.
	_, _, err = ximg.Text(10, 10, fg, size, font, msg)
	if err != nil {
		log.Fatal(err)
	}

	// Compute extents of first line of text.
	_, firsth := xgraphics.Extents(font, size, msg)

	// Now show the image in its own window.
	win := ximg.XShowExtra("Drawing text using xgraphics", true)

	// Now draw some more text below the above and demonstrate how to update
	// only the region we've updated.
	_, _, err = ximg.Text(10, 10+firsth, fg, size, font, "Some more text.")
	if err != nil {
		log.Fatal(err)
	}

	// Now compute extents of the second line of text, so we know which region
	// to update.
	secw, sech := xgraphics.Extents(font, size, "Some more text.")

	// Now repaint on the region that we drew text on. Then update the screen.
	bounds := image.Rect(10, 10+firsth, 10+secw, 10+firsth+sech)
	ximg.SubImage(bounds).XDraw()
	ximg.XPaint(win.Id)

	// All we really need to do is block, which could be achieved using
	// 'select{}'. Invoking the main event loop however, will emit error
	// message if anything went seriously wrong above.
	xevent.Main(X)
}
Beispiel #2
0
// NewInput constructs Input values. It needs an X connection, a parent window,
// the width of the input box, and theme information related for the font
// and background. Padding separating the text and the edges of the window
// may also be specified.
//
// While NewInput returns an *Input, a Input value also has an xwindow.Window
// value embedded into it. Thus, an Input can also be treated as a normal
// window on which you can assign callbacks, close, destroy, etc.
//
// As with all windows, the Input window should be destroyed when it is no
// longer in used.
func NewInput(X *xgbutil.XUtil, parent xproto.Window, width int, padding int,
	font *truetype.Font, fontSize float64,
	fontColor, bgColor render.Color) *Input {

	_, height := xgraphics.Extents(font, fontSize, "M")

	width, height = width+2*padding, height+2*padding

	img := xgraphics.New(X, image.Rect(0, 0, width, height))
	win := xwindow.Must(xwindow.Create(X, parent))
	win.Listen(xproto.EventMaskKeyPress)
	win.Resize(width, height)

	ti := &Input{
		Window:    win,
		img:       img,
		Text:      make([]rune, 0, 50),
		font:      font,
		fontSize:  fontSize,
		fontColor: fontColor,
		bgColor:   bgColor,
		padding:   padding,
	}

	ti.Render()
	return ti
}
Beispiel #3
0
// DrawText is a convenience function that will create a new image, render
// the provided text to it, paint the image to the provided window, and resize
// the window to fit the text snugly.
//
// An error can occur when rendering the text to an image.
func DrawText(win *xwindow.Window, font *truetype.Font, size float64,
	fontClr, bgClr render.Color, text string) error {

	// BUG(burntsushi): If `text` is zero-length, very bad things happen.
	if len(text) == 0 {
		text = " "
	}

	// Over estimate the extents.
	ew, eh := xgraphics.Extents(font, size, text)

	// Create an image using the over estimated extents.
	img := xgraphics.New(win.X, image.Rect(0, 0, ew, eh))
	xgraphics.BlendBgColor(img, bgClr.ImageColor())

	// Now draw the text, grab the (x, y) position advanced by the text, and
	// check for an error in rendering.
	_, _, err := img.Text(0, 0, fontClr.ImageColor(), size, font, text)
	if err != nil {
		return err
	}

	// Resize the window to the geometry determined by (x, y).
	win.Resize(ew, eh)

	// Now draw the image to the window and destroy it.
	img.XSurfaceSet(win.Id)
	// subimg := img.SubImage(image.Rect(0, 0, ew, eh))
	img.XDraw()
	img.XPaint(win.Id)
	img.Destroy()

	return nil
}
Beispiel #4
0
// NewCycle creates a new prompt. As many prompts as you want can be created,
// and they could even technically be shown simultaneously so long as at most
// one of them is using a grab. (The grab will fail for the others and they
// will not be shown.)
//
// CycleTheme and CycleConfig values can either use DefaultCycle{Theme,Config}
// values found in this package, or custom ones can be created using
// composite literals.
func NewCycle(X *xgbutil.XUtil, theme *CycleTheme, config CycleConfig) *Cycle {
	cycle := &Cycle{
		X:        X,
		theme:    theme,
		config:   config,
		showing:  false,
		selected: -1,
		grabMods: 0,
	}

	// Create all windows used for the base of the cycle prompt.
	// This obviously doesn't include the windows representing the items.
	cwin := func(p xproto.Window) *xwindow.Window {
		return xwindow.Must(xwindow.Create(X, p))
	}
	cycle.win = cwin(X.RootWin())
	cycle.bTop, cycle.bBot = cwin(cycle.win.Id), cwin(cycle.win.Id)
	cycle.bLft, cycle.bRht = cwin(cycle.win.Id), cwin(cycle.win.Id)

	// Make the top-level window override redirect so the window manager
	// doesn't mess with us.
	cycle.win.Change(xproto.CwOverrideRedirect, 1)

	// Set the colors of each window.
	cclr := func(w *xwindow.Window, clr render.Color) {
		w.Change(xproto.CwBackPixel, uint32(clr.Int()))
	}
	cclr(cycle.win, cycle.theme.BgColor)
	cclr(cycle.bTop, cycle.theme.BorderColor)
	cclr(cycle.bBot, cycle.theme.BorderColor)
	cclr(cycle.bLft, cycle.theme.BorderColor)
	cclr(cycle.bRht, cycle.theme.BorderColor)

	// Map the sub-windows once. (Real mapping only happens when
	// cycle.win is mapped.)
	cycle.bTop.Map()
	cycle.bBot.Map()
	cycle.bLft.Map()
	cycle.bRht.Map()

	// Connect the key response handler (i.e., the alt-tab'ing, canceling, etc.)
	cycle.keyResponse().Connect(X, X.Dummy())

	// Guess the maximum font height.
	_, cycle.fontHeight = xgraphics.Extents(
		cycle.theme.Font, cycle.theme.FontSize, "A")

	return cycle
}
Beispiel #5
0
func (c *Clock) Draw() {
	c.img.For(func(x, y int) xgraphics.BGRA {
		return c.Background
	})

	now := time.Now().Format(c.Format)

	w, h := xgraphics.Extents(c.Font, c.FontSize, now)

	//println("OH MYYYY: ", w, h)

	c.img.Text((c.Width/2)-(w/2), (c.Height/2)-(h/2), c.Foreground, c.FontSize, c.Font, now)

	c.img.XDraw()
	c.img.XPaint(c.window.Id)
}
Beispiel #6
0
func (f *Full) UpdateTitle() {
	if f == nil {
		return
	}

	title := f.client.Name()
	font := f.theme.Font
	fontSize := f.theme.FontSize
	aFontColor := f.theme.AFontColor.ImageColor()
	iFontColor := f.theme.IFontColor.ImageColor()

	ew, eh := xgraphics.Extents(font, fontSize, title)

	imgA := render.NewBorder(f.X, 0, render.NoColor, f.theme.ATitleColor,
		ew, f.theme.TitleSize,
		render.GradientVert, render.GradientRegular)
	imgI := render.NewBorder(f.X, 0, render.NoColor, f.theme.ITitleColor,
		ew, f.theme.TitleSize,
		render.GradientVert, render.GradientRegular)

	y := (f.theme.TitleSize - eh) / 2

	_, _, err := imgA.Text(0, y, aFontColor, fontSize, font, title)
	if err != nil {
		logger.Warning.Printf("Could not draw window title for window %s "+
			"because: %v", f.client, err)
	}

	_, _, err = imgI.Text(0, y, iFontColor, fontSize, font, title)
	if err != nil {
		logger.Warning.Printf("Could not draw window title for window %s "+
			"because: %v", f.client, err)
	}

	width, height := ew, imgA.Bounds().Max.Y
	f.titleText.Create(
		imgA.SubImage(image.Rect(0, 0, width, height)),
		imgI.SubImage(image.Rect(0, 0, width, height)))

	f.titleText.MROpt(fW, 0, 0, width, 0)
	if f.client.State() == Active {
		f.titleText.Active()
	} else {
		f.titleText.Inactive()
	}
}
Beispiel #7
0
func (i *Item) update(text string) {
	if text == i.displayed {
		return
	} else if i.displayed == "" {
		i.displayed = text
	}
	width, height := xgraphics.Extents(i.TrueType, i.Size, i.displayed)

	sub := i.image.SubImage(image.Rect(10, i.offset, 10+width, height+i.offset))
	sub.ForExp(func(x, y int) (r, b, g, a uint8) {
		return 0x00, 0x00, 0x00, 0x00
	})
	sub.Text(10, i.offset, i.Color, i.Size, i.TrueType, text)
	sub.XDraw()
	sub.XExpPaint(i.window.Id, 10, i.offset)
	i.displayed = text
}