windicators

package module
v0.0.1-alpha.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2023 License: MIT Imports: 10 Imported by: 0

README

windicators

Simple GUI indicators for desktop (discrete, no blinking).
Hidden until one of the indicators are valid for display.
Use your own jobs: API calls, bash scripts etc. for component data source.

Tested on Ubuntu and MacOS (intel and apple silicon).

Dependencies

This package requires some OS dependencies because of some C bindings.

Ubuntu:

sudo apt install libgl1-mesa-dev xorg-dev

MacOS:

xcode-select --install
Example
func main() {
    // Define window size and position
    iw, err := windicators.NewIndicatorWindow(200, 20, windicators.PositionCenterBottom)
    if err != nil {
        log.Fatalf("new window error: %s", err)
    }
    
    defer iw.Terminate()
    
    // First indicator component 
    windicators.NewComponent(iw, "demo-rand", "Demo(%v)", func (c *windicators.Component) any {
        r := rand.Intn(10) // simulate some background job/api call
        c.IsVisible = r > 3 // when to show
        return r            // return value
    }, 2*time.Second)
    	
    // Second indicator component 
    windicators.NewComponent(iw, "demo-dummy-emails", "Unread->%v", func (c *windicators.Component) any {
        unreadCount := myFuncFetchEmails()
        c.IsVisible = unreadCount > 0
        return unreadCount
    }, 5*time.Second)
    
    // Ready!
    iw.Run()
}

// This is dummy function just to demonstrate something is done 
func myFuncFetchEmails() int {
	 return rand.Intn(5)
}

Full demo can be found in example directory.

Text colors
	c := windicators.NewComponent(iw, "demo-dummy-emails", "Unread->%v", func(c *windicators.Component) any {
		unreadCount := myFuncFetchEmails()
		c.IsVisible = unreadCount > 0
		return unreadCount
	}, 5*time.Second)

	c.Font.SetColor(.2, 1.0, .4, 1)
	c.OnClick = func(c *windicators.Component) {
		log.Printf("[%s] Click callback...", c.ID)
	}

Use glfw.Window and customize as you will

// IndicatorWindow for indicators
type IndicatorWindow struct {
	*glfw.Window
	// ...

Example to dynamically change colors

	windicators.NewComponent(iw, "demo-rand-status", "Status=%v", func(c *windicators.Component) any {
		// simulate some background job/api call
		r := rand.Intn(5)

		status := ""
		switch r {
		case 1:
			status = "OK"
			c.Font.SetColor(0, 1, 0, 1)
		case 3:
			status = "ERR"
			c.Font.SetColor(1, 0, 0, 1)
		default:
			c.Font.SetColor(1, 1, 1, .5)
		}

		c.IsVisible = status != "" // when to show
		return status              // return value
	}, 2*time.Second)

Predefined positions and offset

First use one of these: PositionCenterTop, PositionRightTop, PositionRightCenter, PositionRightBottom, PositionCenterBottom, PositionLeftBottom, PositionLeftCenter, PositionLeftTop.
Then fine tune with iw.MoveTo(x,y):

    iw.MoveTo(iw.Position.X - 100, iw.Position.Y + 60)
Click callback

Assign component OnClick callback to do something special.

wi.NewComponent(iw, "demo-rand", "Demo(%v)", func(c *wi.Component) any {
    // simulate some background job/api call
    r := rand.Int31n(10)
    c.IsVisible = r > 0 // when to show
    c.Data = fmt.Sprintf("http://localhost?mydata=%d",r)
    return r            // return value
}, 15*time.Minute)

c.OnClick = func(c *windicators.Component) {
	log.Printf("[%s] Click", c.ID)
	log.Printf("Open URL `%s`", c.Data.(string)) // --> http://localhost?mydata=2
}

TODO's
  • Test/Fix for other OS's
  • Window auto resize for indicators visible
  • Vertical display
  • Add real-life examples under examples/ folder
  • Before/After render hooks
  • Loading and Minimized views
  • Be aware of multiple monitors

Documentation

Index

Constants

View Source
const (
	PositionCenterTop uint = iota
	PositionRightTop
	PositionRightCenter
	PositionRightBottom
	PositionCenterBottom
	PositionLeftBottom
	PositionLeftCenter
	PositionLeftTop
)

Prefefined positions for quick setup

Variables

This section is empty.

Functions

This section is empty.

Types

type Component

type Component struct {
	ID        string
	Format    string
	Value     any
	IsVisible bool

	Font glfont.Font
	*ComponentMetrics

	OnClick func(c *Component)
	Data    any // use to save data for `OnClick` or other uses
	// contains filtered or unexported fields
}

Component ..

func NewComponent

func NewComponent(iw *IndicatorWindow, id, format string, fnCheck func(c *Component) any, fnCheckDuration time.Duration) *Component

NewComponent ..

func (*Component) Check

func (c *Component) Check()

Check ..

func (*Component) DrawText

func (c *Component) DrawText(posX, posY float32)

DrawText ..

func (*Component) InPos

func (c *Component) InPos(posX, posY float32) bool

InPos ..

func (*Component) IsClickable

func (c *Component) IsClickable() bool

IsClickable have coordinates updated after draw

func (*Component) String

func (c *Component) String() string

String ..

func (*Component) UseFont

func (c *Component) UseFont(fpath string, pt int32)

UseFont - change font for component

type ComponentList

type ComponentList []*Component

ComponentList ..

func (ComponentList) CheckAll

func (complist ComponentList) CheckAll()

CheckAll - trigger check for every component

func (ComponentList) FilterVisible

func (complist ComponentList) FilterVisible() ComponentList

FilterVisible - filter only visibles

func (ComponentList) FindByID

func (complist ComponentList) FindByID(id string) *Component

FindByID ..

func (ComponentList) IsAllHidden

func (complist ComponentList) IsAllHidden() bool

IsAllHidden is something changed

type ComponentMetrics

type ComponentMetrics struct {
	X, Y   float32
	Height uint

	// calculated
	FontSize uint
	Baseline uint
	Width    uint
	X2, Y2   float32
	// contains filtered or unexported fields
}

ComponentMetrics ,,

func NewMetrics

func NewMetrics(c *Component) *ComponentMetrics

NewMetrics ..

func (*ComponentMetrics) CoordinatesWithPadding

func (metr *ComponentMetrics) CoordinatesWithPadding(t, r, b, l float32) (float32, float32, float32, float32)

CoordinatesWithPadding - top, right, bottom, left padding

func (*ComponentMetrics) IsValid

func (metr *ComponentMetrics) IsValid() bool

IsValid ..

func (*ComponentMetrics) RecalcFor

func (metr *ComponentMetrics) RecalcFor(posX, posY float32, s string)

RecalcFor ..

func (*ComponentMetrics) String

func (metr *ComponentMetrics) String() string

String ..

type IndicatorWindow

type IndicatorWindow struct {
	*glfw.Window
	Font     *glfont.Font
	FontSize uint

	Position                  *Point
	Width, Height             uint
	ScreenWidth, ScreenHeight uint
	// contains filtered or unexported fields
}

IndicatorWindow for indicators

func NewIndicatorWindow

func NewIndicatorWindow(width, height, position uint) (*IndicatorWindow, error)

NewIndicatorWindow ..

func (*IndicatorWindow) Draw

func (iw *IndicatorWindow) Draw()

Draw ..

func (*IndicatorWindow) IsRunning

func (iw *IndicatorWindow) IsRunning() bool

IsRunning - if channel is active then window is started

func (*IndicatorWindow) ListenEvents

func (iw *IndicatorWindow) ListenEvents()

ListenEvents ..

func (*IndicatorWindow) MoveTo

func (iw *IndicatorWindow) MoveTo(x, y int)

MoveTo ..

func (*IndicatorWindow) Run

func (iw *IndicatorWindow) Run() error

Run ..

func (*IndicatorWindow) Terminate

func (iw *IndicatorWindow) Terminate()

Terminate window and clean up resources. Must be called whenever program exists - on success or on error. There is no need to call this function if IndicatorWindow creation fails.

func (*IndicatorWindow) UseFont

func (iw *IndicatorWindow) UseFont(fpath string, size uint) (*glfont.Font, error)

UseFont ..

type Point

type Point struct {
	X, Y int
}

Point ..

func NewPoint

func NewPoint(x, y int) *Point

NewPoint .. :shrug:

func PositionPoint

func PositionPoint(position, screenW, screenH, windowW, windowH uint) *Point

PositionPoint ..

func (*Point) String

func (p *Point) String() string

String ..

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL