Skip to content

Commit

Permalink
Improve assets UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikKalkoken committed Jun 12, 2024
1 parent bbec557 commit 502626a
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 33 deletions.
8 changes: 8 additions & 0 deletions internal/model/characterasset.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ func (ca CharacterAsset) IsShip() bool {
return ca.EveType.Group.Category.ID == EveCategoryShip
}

func (ca CharacterAsset) IsInCargoBay() bool {
return ca.LocationFlag == "Cargo"
}

func (ca CharacterAsset) IsInFuelBay() bool {
return ca.LocationFlag == "SpecializedFuelBay"
}

func (ca CharacterAsset) Variant() EveTypeVariant {
if ca.IsSKIN() {
return VariantSKIN
Expand Down
8 changes: 8 additions & 0 deletions internal/model/evegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ package model
const (
EveGroupAuditLogFreightContainer = 649
EveGroupAuditLogSecureCargoContainer = 448
EveGroupBlackOps = 898
EveGroupCapitalIndustrialShip = 883
EveGroupCargoContainer = 12
EveGroupCarrier = 547
EveGroupDreadnought = 485
EveGroupForceAuxiliary = 1538
EveGroupJumpFreighter = 902
EveGroupSecureCargoContainer = 340
EveGroupSuperCarrier = 659
EveGroupTitan = 30
)

// EveGroup is a group in Eve Online.
Expand Down
18 changes: 18 additions & 0 deletions internal/model/evetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ func (et EveType) IsSKIN() bool {
return et.Group.Category.ID == EveCategorySKINs
}

func (et EveType) HasFuelBay() bool {
if et.Group.Category.ID != EveCategoryShip {
return false
}
switch et.Group.ID {
case EveGroupBlackOps,
EveGroupCapitalIndustrialShip,
EveGroupCarrier,
EveGroupDreadnought,
EveGroupForceAuxiliary,
EveGroupJumpFreighter,
EveGroupSuperCarrier,
EveGroupTitan:
return true
}
return false
}

func (et EveType) HasRender() bool {
switch et.Group.Category.ID {
case
Expand Down
114 changes: 81 additions & 33 deletions internal/ui/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ const (
nodeShipHangar
nodeItemHangar
nodeContainer
nodeShip
nodeCargoBay
nodeFuelBay
)

// locationNode is a node for the asset tree widget.
type locationNode struct {
CharacterID int32
ContainerID int64
Expand All @@ -37,8 +41,6 @@ type locationNode struct {
Type locationNodeType
}

var defaultAssetIcon = theme.NewDisabledResource(resourceQuestionmarkSvg)

func (n locationNode) UID() widget.TreeNodeID {
if n.CharacterID == 0 || n.ContainerID == 0 || n.Type == 0 {
panic("some IDs are not set")
Expand All @@ -50,6 +52,15 @@ func (n locationNode) isBranch() bool {
return n.Type == nodeLocation
}

func (n locationNode) addToTree(parentUID string, ids map[string][]string, values map[string]string) string {
uid := n.UID()
ids[parentUID] = append(ids[parentUID], uid)
values[uid] = objectToJSONOrPanic(n)
return uid
}

var defaultAssetIcon = theme.NewDisabledResource(resourceQuestionmarkSvg)

// assetsArea is the UI area that shows the skillqueue
type assetsArea struct {
content fyne.CanvasObject
Expand Down Expand Up @@ -202,12 +213,7 @@ func (a *assetsArea) updateLocationData() (map[string][]string, map[string]strin
} else {
ln.IsUnknown = true
}
uid := ln.UID()
values[uid], err = objectToJSON(ln)
if err != nil {
return nil, nil, 0, err
}
ids[""] = append(ids[""], uid)
locationUID := ln.addToTree("", ids, values)

topAssets := atl.Nodes()
slices.SortFunc(topAssets, func(a assettree.AssetNode, b assettree.AssetNode) int {
Expand All @@ -226,33 +232,54 @@ func (a *assetsArea) updateLocationData() (map[string][]string, map[string]strin
}

nsh := makeHangarNode(nodeShipHangar, ln.ContainerID, len(ships), characterID)
shipsUID := nsh.UID()
ids[uid] = append(ids[uid], shipsUID)
values[shipsUID], err = objectToJSON(nsh)
if err != nil {
return nil, nil, 0, err
shipsUID := nsh.addToTree(locationUID, ids, values)
for _, an := range ships {
ship := an.Asset
ln := locationNode{
CharacterID: characterID,
ContainerID: an.Asset.ItemID,
Name: fmt.Sprintf("%s (%s)", ship.Name, ship.EveType.Name),
Type: nodeShip,
}
shipUID := ln.addToTree(shipsUID, ids, values)
cargo := make([]assettree.AssetNode, 0)
fuel := make([]assettree.AssetNode, 0)
for _, an2 := range an.Nodes() {
if an2.Asset.IsInCargoBay() {
cargo = append(cargo, an2)
} else if an2.Asset.IsInFuelBay() {
fuel = append(fuel, an2)
}
}
cln := locationNode{
CharacterID: characterID,
ContainerID: ship.ItemID,
Name: makeNameWithCount("Cargo Bay", len(cargo)),
Type: nodeCargoBay,
}
cln.addToTree(shipUID, ids, values)
if ship.EveType.HasFuelBay() {
fln := locationNode{
CharacterID: characterID,
ContainerID: an.Asset.ItemID,
Name: makeNameWithCount("Fuel Bay", len(fuel)),
Type: nodeFuelBay,
}
fln.addToTree(shipUID, ids, values)
}
}

itemsCount := len(topAssets) - len(ships)
nih := makeHangarNode(nodeItemHangar, ln.ContainerID, itemsCount, characterID)
itemsUID := nih.UID()
ids[uid] = append(ids[uid], itemsUID)
values[itemsUID], err = objectToJSON(nih)
if err != nil {
return nil, nil, 0, err
}
itemsUID := nih.addToTree(locationUID, ids, values)
for _, an := range itemContainers {
cln := locationNode{
ln := locationNode{
CharacterID: characterID,
ContainerID: an.Asset.ItemID,
Name: makeNameWithCount(an.Asset.Name, len(an.Nodes())),
Type: nodeContainer,
}
cUID := cln.UID()
ids[itemsUID] = append(ids[itemsUID], cUID)
values[cUID], err = objectToJSON(cln)
if err != nil {
return nil, nil, 0, err
}
ln.addToTree(itemsUID, ids, values)
}
}
return ids, values, len(a.assetTree.Locations()), nil
Expand All @@ -275,10 +302,6 @@ func makeHangarNode(t locationNodeType, locationID int64, n int, characterID int
return hn
}

func makeNameWithCount(name string, count int) string {
return fmt.Sprintf("%s (%d)", name, count)
}

func (a *assetsArea) makeTopText(total int) (string, widget.Importance, error) {
if !a.ui.hasCharacter() {
return "No character", widget.LowImportance, nil
Expand All @@ -305,15 +328,33 @@ func (a *assetsArea) redrawAssets(n locationNode) error {
f = a.ui.sv.Character.ListCharacterAssetsInShipHangar
case nodeItemHangar:
f = a.ui.sv.Character.ListCharacterAssetsInItemHangar
case nodeContainer:
f = a.ui.sv.Character.ListCharacterAssetsInLocation
default:
return fmt.Errorf("invalid node type: %v", n.Type)
f = a.ui.sv.Character.ListCharacterAssetsInLocation
}
assets, err := f(context.Background(), n.CharacterID, n.ContainerID)
if err != nil {
return err
}
switch n.Type {
case nodeCargoBay:
cargo := make([]*model.CharacterAsset, 0)
for _, ca := range assets {
if !ca.IsInCargoBay() {
continue
}
cargo = append(cargo, ca)
}
assets = cargo
case nodeFuelBay:
fuel := make([]*model.CharacterAsset, 0)
for _, ca := range assets {
if !ca.IsInFuelBay() {
continue
}
fuel = append(fuel, ca)
}
assets = fuel
}
if err := a.assetsData.Set(copyToUntypedSlice(assets)); err != nil {
return err
}
Expand Down Expand Up @@ -380,3 +421,10 @@ func (u *ui) makeAssetGrid(assetsData binding.UntypedList) *widget.GridWrap {
}
return g
}

func makeNameWithCount(name string, count int) string {
if count == 0 {
return name
}
return fmt.Sprintf("%s (%s)", name, humanize.Comma(int64(count)))
}
8 changes: 8 additions & 0 deletions internal/ui/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ func objectToJSON[T any](o T) (string, error) {
return string(s), nil
}

func objectToJSONOrPanic[T any](o T) string {
s, err := objectToJSON(o)
if err != nil {
panic(err)
}
return s
}

func entityNameOrFallback[T int | int32 | int64](e *model.EntityShort[T], fallback string) string {
if e == nil {
return fallback
Expand Down

0 comments on commit 502626a

Please sign in to comment.