| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package lifecycle defines an event for an app's lifecycle. |
| // |
| // The app lifecycle consists of moving back and forth between an ordered |
| // sequence of stages. For example, being at a stage greater than or equal to |
| // StageVisible means that the app is visible on the screen. |
| // |
| // A lifecycle event is a change from one stage to another, which crosses every |
| // intermediate stage. For example, changing from StageAlive to StageFocused |
| // implicitly crosses StageVisible. |
| // |
| // Crosses can be in a positive or negative direction. A positive crossing of |
| // StageFocused means that the app has gained the focus. A negative crossing |
| // means it has lost the focus. |
| // |
| // See the golang.org/x/mobile/app package for details on the event model. |
| package lifecycle // import "golang.org/x/mobile/event/lifecycle" |
| |
| import ( |
| "fmt" |
| ) |
| |
| // Cross is whether a lifecycle stage was crossed. |
| type Cross uint32 |
| |
| func (c Cross) String() string { |
| switch c { |
| case CrossOn: |
| return "on" |
| case CrossOff: |
| return "off" |
| } |
| return "none" |
| } |
| |
| const ( |
| CrossNone Cross = 0 |
| CrossOn Cross = 1 |
| CrossOff Cross = 2 |
| ) |
| |
| // Event is a lifecycle change from an old stage to a new stage. |
| type Event struct { |
| From, To Stage |
| |
| // DrawContext is the state used for painting, if any is valid. |
| // |
| // For OpenGL apps, a non-nil DrawContext is a gl.Context. |
| // |
| // TODO: make this an App method if we move away from an event channel? |
| DrawContext interface{} |
| } |
| |
| func (e Event) String() string { |
| return fmt.Sprintf("lifecycle.Event{From:%v, To:%v, DrawContext:%v}", e.From, e.To, e.DrawContext) |
| } |
| |
| // Crosses returns whether the transition from From to To crosses the stage s: |
| // - It returns CrossOn if it does, and the lifecycle change is positive. |
| // - It returns CrossOff if it does, and the lifecycle change is negative. |
| // - Otherwise, it returns CrossNone. |
| // See the documentation for Stage for more discussion of positive and negative |
| // crosses. |
| func (e Event) Crosses(s Stage) Cross { |
| switch { |
| case e.From < s && e.To >= s: |
| return CrossOn |
| case e.From >= s && e.To < s: |
| return CrossOff |
| } |
| return CrossNone |
| } |
| |
| // Stage is a stage in the app's lifecycle. The values are ordered, so that a |
| // lifecycle change from stage From to stage To implicitly crosses every stage |
| // in the range (min, max], exclusive on the low end and inclusive on the high |
| // end, where min is the minimum of From and To, and max is the maximum. |
| // |
| // The documentation for individual stages talk about positive and negative |
| // crosses. A positive lifecycle change is one where its From stage is less |
| // than its To stage. Similarly, a negative lifecycle change is one where From |
| // is greater than To. Thus, a positive lifecycle change crosses every stage in |
| // the range (From, To] in increasing order, and a negative lifecycle change |
| // crosses every stage in the range (To, From] in decreasing order. |
| type Stage uint32 |
| |
| // TODO: how does iOS map to these stages? What do cross-platform mobile |
| // abstractions do? |
| |
| const ( |
| // StageDead is the zero stage. No lifecycle change crosses this stage, |
| // but: |
| // - A positive change from this stage is the very first lifecycle change. |
| // - A negative change to this stage is the very last lifecycle change. |
| StageDead Stage = iota |
| |
| // StageAlive means that the app is alive. |
| // - A positive cross means that the app has been created. |
| // - A negative cross means that the app is being destroyed. |
| // Each cross, either from or to StageDead, will occur only once. |
| // On Android, these correspond to onCreate and onDestroy. |
| StageAlive |
| |
| // StageVisible means that the app window is visible. |
| // - A positive cross means that the app window has become visible. |
| // - A negative cross means that the app window has become invisible. |
| // On Android, these correspond to onStart and onStop. |
| // On Desktop, an app window can become invisible if e.g. it is minimized, |
| // unmapped, or not on a visible workspace. |
| StageVisible |
| |
| // StageFocused means that the app window has the focus. |
| // - A positive cross means that the app window has gained the focus. |
| // - A negative cross means that the app window has lost the focus. |
| // On Android, these correspond to onResume and onFreeze. |
| StageFocused |
| ) |
| |
| func (s Stage) String() string { |
| switch s { |
| case StageDead: |
| return "StageDead" |
| case StageAlive: |
| return "StageAlive" |
| case StageVisible: |
| return "StageVisible" |
| case StageFocused: |
| return "StageFocused" |
| default: |
| return fmt.Sprintf("lifecycle.Stage(%d)", s) |
| } |
| } |