package astilectron import ( "context" "github.com/asticode/go-astikit" ) // Tray event names const ( EventNameTrayCmdCreate = "tray.cmd.create" EventNameTrayCmdDestroy = "tray.cmd.destroy" EventNameTrayCmdSetImage = "tray.cmd.set.image" EventNameTrayCmdPopupContextMenu = "tray.cmd.popup.context.menu" EventNameTrayEventClicked = "tray.event.clicked" EventNameTrayEventCreated = "tray.event.created" EventNameTrayEventDestroyed = "tray.event.destroyed" EventNameTrayEventDoubleClicked = "tray.event.double.clicked" EventNameTrayEventImageSet = "tray.event.image.set" EventNameTrayEventRightClicked = "tray.event.right.clicked" EventNameTrayEventContextMenuPoppedUp = "tray.event.context.menu.popped.up" ) // Tray represents a tray type Tray struct { *object o *TrayOptions } // TrayOptions represents tray options // We must use pointers since GO doesn't handle optional fields whereas NodeJS does. Use astikit.BoolPtr, astikit.IntPtr or astikit.StrPtr // to fill the struct // https://github.com/electron/electron/blob/v1.8.1/docs/api/tray.md type TrayOptions struct { Image *string `json:"image,omitempty"` Tooltip *string `json:"tooltip,omitempty"` } // TrayPopUpOptions represents Tray PopUpContextMenu options type TrayPopUpOptions struct { Menu *Menu Position *PositionOptions } // newTray creates a new tray func newTray(ctx context.Context, o *TrayOptions, d *dispatcher, i *identifier, wrt *writer) (t *Tray) { // Init t = &Tray{ o: o, object: newObject(ctx, d, i, wrt, i.new()), } // Make sure the tray's context is cancelled once the destroyed event is received t.On(EventNameTrayEventDestroyed, func(e Event) (deleteListener bool) { t.cancel() return true }) return } // Create creates the tray func (t *Tray) Create() (err error) { if err = t.ctx.Err(); err != nil { return } var e = Event{Name: EventNameTrayCmdCreate, TargetID: t.id, TrayOptions: t.o} _, err = synchronousEvent(t.ctx, t, t.w, e, EventNameTrayEventCreated) return } // Destroy destroys the tray func (t *Tray) Destroy() (err error) { if err = t.ctx.Err(); err != nil { return } _, err = synchronousEvent(t.ctx, t, t.w, Event{Name: EventNameTrayCmdDestroy, TargetID: t.id}, EventNameTrayEventDestroyed) return } // NewMenu creates a new tray menu func (t *Tray) NewMenu(i []*MenuItemOptions) *Menu { return newMenu(t.ctx, t.id, i, t.d, t.i, t.w) } // SetImage sets the tray image func (t *Tray) SetImage(image string) (err error) { if err = t.ctx.Err(); err != nil { return } t.o.Image = astikit.StrPtr(image) _, err = synchronousEvent(t.ctx, t, t.w, Event{Name: EventNameTrayCmdSetImage, Image: image, TargetID: t.id}, EventNameTrayEventImageSet) return } // PopUpContextMenu pops up the context menu of the tray icon. // When menu is passed, the menu will be shown instead of the tray icon's context menu. // The position is only available on Windows, and it is (0, 0) by default. // https://www.electronjs.org/docs/latest/api/tray#traypopupcontextmenumenu-position-macos-windows func (t *Tray) PopUpContextMenu(p *TrayPopUpOptions) (err error) { var em *EventMenu var mp *MenuPopupOptions if err = t.ctx.Err(); err != nil { return } if p.Menu != nil { em = p.Menu.toEvent() } if p.Position != nil { mp = &MenuPopupOptions{PositionOptions: *p.Position} } var e = Event{Name: EventNameTrayCmdPopupContextMenu, TargetID: t.id, Menu: em, MenuPopupOptions: mp} _, err = synchronousEvent(t.ctx, t, t.w, e, EventNameTrayEventContextMenuPoppedUp) return }