// parseJSONPos // loadJSONRecursive runs down the hierarchy in the JSON file func loadJSONRecursive(am *assetmanager.AssetManager, node map[string]interface{}, filename string, entityByID map[string]*Entity) *Entity { var id string var idOK, ok bool var childEntity *Entity entity := NewEntity(nil) // Do this first to help with error messaging id, idOK = node["Id"].(string) if idOK { entity.ID = id if entityByID != nil { entityByID[id] = entity } } else { id = "[No ID]" } // Do these first since X and Y might depend on them: _, ok = node["W"].(string) if ok { entity.W = am.ParseDimension(filename, id, "W", node) } _, ok = node["H"].(string) if ok { entity.H = am.ParseDimension(filename, id, "H", node) } assetName, ok := node["Asset"].(string) if ok { entity.Surface = am.Surfaces[assetName] entity.W = entity.Surface.W entity.H = entity.Surface.H } // Now do the rest of the properties for k, v := range node { switch k { case "Id", "W", "H", "Asset": // do nothing; handled above case "X": entity.X = am.ParsePosition(filename, id, entity.W, "X", node) case "Y": entity.Y = am.ParsePosition(filename, id, entity.H, "Y", node) case "Visible": entity.Visible = v.(bool) case "Children": for _, child := range v.([]interface{}) { childEntity = loadJSONRecursive(am, child.(map[string]interface{}), filename, entityByID) entity.AddChild(childEntity) } default: panic(fmt.Sprintf("scenegraph.LoadJSON: unrecognized key: %s", k)) } } return entity }
// New constructs the menu func New(am *assetmanager.AssetManager, id string, items []Item, spacing int32, justification int) *Menu { // TODO: do these even need to be registered with any asset manager? just use util.RenderText? menu := &Menu{items: items, spacing: spacing, justification: justification} menuEntity := scenegraph.NewEntity(nil) maxH := int32(0) maxW := int32(0) idNum := 0 for i, item := range menu.items { var err error var surface, surfaceHi *sdl.Surface var entity, entityHi *scenegraph.Entity if surface, err = am.RenderText(fmt.Sprintf("%s-%d", id, idNum), item.AssetFontID, item.Text, item.Color); err != nil { panic(fmt.Sprintf("Menu render font: %v", err)) } idNum++ if surfaceHi, err = am.RenderText(fmt.Sprintf("%s-%d", id, idNum), item.AssetFontID, item.Text, item.HiColor); err != nil { panic(fmt.Sprintf("Intro render font: %v", err)) } idNum++ entity = scenegraph.NewEntity(surface) entity.Visible = i > 0 entityHi = scenegraph.NewEntity(surfaceHi) entityHi.Visible = i == 0 menuEntity.AddChild(entity, entityHi) if entity.W > maxW { maxW = entity.W } entity.Y = maxH entityHi.Y = maxH maxH += menu.spacing } menuEntity.W = maxW menuEntity.H = maxH // position everything now that we have sizes known for i := range menu.items { entity := menuEntity.GetChild(i * 2) entityHi := menuEntity.GetChild(i*2 + 1) switch menu.justification { case MenuJustifyLeft: entity.X = 0 entityHi.X = 0 case MenuJustifyCenter: scenegraph.CenterEntityInParent(entity, menuEntity) scenegraph.CenterEntityInParent(entityHi, menuEntity) case MenuJustifyRight: scenegraph.RightJustifyEntityInParent(entity, menuEntity) scenegraph.RightJustifyEntityInParent(entityHi, menuEntity) } } menu.RootEntity = menuEntity return menu }