@@ -1157,6 +1157,162 @@ namespace microgui {
11571157 }
11581158
11591159
1160+ export class RadioButton {
1161+ private text : string ;
1162+ private textColour : number ;
1163+ private x : number ;
1164+ private y : number ;
1165+ private onClick : ( obj ?: Object ) => void ;
1166+ private isSelected : boolean ;
1167+
1168+ constructor ( opts : { text : string , onClick : ( obj : Object ) => void , colour ?: number } ) {
1169+ this . text = opts . text ;
1170+ this . x = null ;
1171+ this . y = null ;
1172+ this . onClick = opts . onClick ;
1173+ this . isSelected = false ;
1174+ this . textColour = ( opts . colour == null ) ? 15 : opts . colour ;
1175+ }
1176+
1177+ public setSelected ( isSelected : boolean ) {
1178+ this . isSelected = isSelected ;
1179+ }
1180+
1181+ public setPosition ( x : number , y : number ) {
1182+ this . x = x ;
1183+ this . y = y ;
1184+ }
1185+
1186+ public click ( ) {
1187+ this . onClick ( ) ;
1188+ }
1189+
1190+ draw ( ) {
1191+ screen ( ) . fillCircle (
1192+ this . x - 6 ,
1193+ this . y + 3 ,
1194+ 4 ,
1195+ this . isSelected ? 6 : 1
1196+ )
1197+
1198+ screen ( ) . print (
1199+ this . text ,
1200+ this . x ,
1201+ this . y ,
1202+ this . textColour
1203+ )
1204+ }
1205+ }
1206+
1207+
1208+ export class RadioButtonCollection extends GUIComponentAbstract {
1209+ private title : string ;
1210+ private btns : RadioButton [ ]
1211+ private selectedTextBtnIndex : number ;
1212+
1213+ constructor ( opts : {
1214+ alignment : GUIComponentAlignment ,
1215+ isActive : boolean ,
1216+ btns : RadioButton [ ] ,
1217+ isHidden ?: boolean ,
1218+ xOffset ?: number ,
1219+ yOffset ?: number ,
1220+ xScaling ?: number ,
1221+ yScaling ?: number ,
1222+ colour ?: number ,
1223+ border ?: boolean ,
1224+ title ?: string ,
1225+ text ?: string | string [ ]
1226+ } ) {
1227+ super ( {
1228+ alignment : opts . alignment ,
1229+ xOffset : ( opts . xOffset != null ) ? opts . xOffset : 0 ,
1230+ yOffset : ( opts . yOffset != null ) ? opts . yOffset : 0 ,
1231+ isActive : opts . isActive ,
1232+ isHidden : opts . isHidden ,
1233+ xScaling : opts . xScaling ,
1234+ yScaling : opts . yScaling ,
1235+ colour : opts . colour ,
1236+ border : opts . border
1237+ } ) ;
1238+
1239+ this . title = ( opts . title != null ) ? opts . title : "" ;
1240+ this . btns = ( opts . btns != null ) ? opts . btns : [ ] ;
1241+
1242+ const titleYOffset = ( this . title != "" ) ? 13 : 0 ;
1243+
1244+ const btnXOffset = ( this . btns . length > 0 ) ? ( this . bounds . width / ( this . btns . length + 1 ) ) : 0 ;
1245+
1246+ const xBorder = this . bounds . width * 0.08 ;
1247+ const yBorder = this . bounds . height * 0.05 ;
1248+ const ySpacing = ( this . bounds . height - yBorder ) / ( this . btns . length + 1 ) ;
1249+
1250+ for ( let i = 0 ; i < this . btns . length ; i ++ ) {
1251+ this . btns [ i ] . setPosition (
1252+ xBorder + this . bounds . left + this . bounds . width ,
1253+ titleYOffset + ( ( i + 1 ) * ySpacing )
1254+ ) ;
1255+ this . btns [ i ] . setSelected ( false )
1256+ }
1257+
1258+ if ( this . btns ) {
1259+ this . selectedTextBtnIndex = 0
1260+ this . btns [ this . selectedTextBtnIndex ] . setSelected ( true )
1261+ }
1262+ }
1263+
1264+ public makeActive ( ) {
1265+ super . makeActive ( ) ;
1266+ this . setupButtonBindings ( ) ;
1267+ }
1268+
1269+ setupButtonBindings ( ) {
1270+ unbindShieldButtons ( ) ;
1271+
1272+ control . onEvent ( ControllerButtonEvent . Pressed , controller . A . id , ( ) => {
1273+ this . btns [ this . selectedTextBtnIndex ] . click ( ) ;
1274+ } )
1275+
1276+ control . onEvent ( ControllerButtonEvent . Pressed , controller . up . id , ( ) => {
1277+ this . btns [ this . selectedTextBtnIndex ] . setSelected ( false )
1278+
1279+ const len = this . btns . length
1280+ this . selectedTextBtnIndex = ( ( ( this . selectedTextBtnIndex - 1 ) % len ) + len ) % len
1281+
1282+ this . btns [ this . selectedTextBtnIndex ] . setSelected ( true )
1283+ } )
1284+
1285+ control . onEvent ( ControllerButtonEvent . Pressed , controller . down . id , ( ) => {
1286+ this . btns [ this . selectedTextBtnIndex ] . setSelected ( false )
1287+ this . selectedTextBtnIndex = ( this . selectedTextBtnIndex + 1 ) % this . btns . length
1288+ this . btns [ this . selectedTextBtnIndex ] . setSelected ( true )
1289+ } )
1290+
1291+ control . onEvent ( ControllerButtonEvent . Pressed , controller . left . id , ( ) => {
1292+ this . selectedTextBtnIndex = 0 ;
1293+ } )
1294+
1295+ control . onEvent ( ControllerButtonEvent . Pressed , controller . right . id , ( ) => {
1296+ this . selectedTextBtnIndex = this . btns . length - 1 ;
1297+ } )
1298+ }
1299+
1300+ draw ( ) {
1301+ super . draw ( ) ;
1302+
1303+ const titleOffset = ( font . charWidth * this . title . length ) >> 1 ;
1304+
1305+ screen ( ) . print (
1306+ this . title ,
1307+ ( screen ( ) . width >> 1 ) + this . bounds . left + ( this . width >> 1 ) - titleOffset ,
1308+ ( screen ( ) . height >> 1 ) + this . bounds . top + 2 ,
1309+ )
1310+
1311+ this . btns . forEach ( btn => btn . draw ( ) )
1312+ }
1313+ }
1314+
1315+
11601316 /**
11611317 * Holds other components,
11621318 * One component is active at a time
@@ -1266,6 +1422,7 @@ namespace microgui {
12661422 btns : Button [ ] [ ] ,
12671423 isActive : boolean ,
12681424 isHidden ?: boolean ,
1425+ noAutoScaling ?: boolean ,
12691426 xOffset ?: number ,
12701427 yOffset ?: number ,
12711428 xScaling ?: number ,
@@ -1291,16 +1448,31 @@ namespace microgui {
12911448 // This is checked before drawing.
12921449 this . cursorBounds = null ;
12931450
1451+ const autoScaling = ( opts . noAutoScaling == null ) ? true : ! opts . noAutoScaling
1452+
12941453 if ( opts . btns != null ) {
12951454 this . btns = opts . btns ;
12961455
1456+ const yBorder = this . bounds . height * 0.05
1457+ const xBorder = this . bounds . width * 0.05
1458+ const ySpacing : number = ( this . bounds . height - yBorder ) / ( this . btns . length + 1 ) ;
1459+
12971460 // Adjust button x & y to be relative to this components window left & top:
1298- this . btns . forEach ( row => {
1299- row . forEach ( btn => {
1300- btn . xfrm . localPos . x = this . bounds . left + btn . xfrm . localPos . x + ( btn . width >> 1 ) + 2
1301- btn . xfrm . localPos . y = this . bounds . top + btn . xfrm . localPos . y + ( btn . height >> 1 ) + 2
1302- } )
1303- } )
1461+ for ( let i = 0 ; i < this . btns . length ; i ++ ) {
1462+ const row = this . btns [ i ]
1463+
1464+ const xSpacing : number = ( this . bounds . width - xBorder ) / ( row . length + 1 ) ;
1465+ for ( let j = 0 ; j < row . length ; j ++ ) {
1466+ const btn = row [ j ]
1467+ if ( autoScaling && btn . xfrm . localPos . x == 0 )
1468+ btn . xfrm . localPos . x = ( ( j + 1 ) * xSpacing ) - xBorder
1469+ if ( autoScaling && btn . xfrm . localPos . y == 0 )
1470+ btn . xfrm . localPos . y = ( ( i + 1 ) * ySpacing ) - yBorder
1471+
1472+ btn . xfrm . localPos . x = this . bounds . left + btn . xfrm . localPos . x + ( btn . width >> 1 )
1473+ btn . xfrm . localPos . y = this . bounds . top + btn . xfrm . localPos . y + ( btn . height >> 1 )
1474+ }
1475+ } ;
13041476
13051477 this . isActive = opts . isActive
13061478
@@ -1501,5 +1673,4 @@ namespace microgui {
15011673 } )
15021674 }
15031675 }
1504- }
1505-
1676+ }
0 commit comments