phetsims / joist

Joist is the main framework for PhET Interactive Simulations. Joist creates and displays the simulation content, home screen, navigation bar, About dialog, enables switching between tabs, and other framework-related features.
MIT License
8 stars 6 forks source link

Replace ?showHomeScreen=false with ?bypassHomeScreen #451

Closed samreid closed 6 years ago

samreid commented 6 years ago

In https://github.com/phetsims/joist/issues/445 we are building out more joist functionality regarding the homescreen, and will be adding a new query parameter ?homeScreen=false which creates a sim with no home screen and no homescreen icon. There is an existing query parameter showHomeScreen which seems like it would be easy to confuse with the new one. We recommend replacing ?showHomeScreen=false with ?bypassHomeScreen for clarity. We think this is rarely used outside of PhET (probably rarely used within PhET as well), but wanted to check with other developers before making this change.

@jbphet @pixelzoom @jonathanolson @jessegreenberg @Denz1994 @mbarlow12 ok to proceed? If you are the last one to chime in, please reassign to me or @zepumph.

samreid commented 6 years ago

To be clear the proposed flag "?bypassHomeScreen" would still create a homescreen, but launch the sim on the 1st screen. You can get to the homescreen with the navbar home icon.

pixelzoom commented 6 years ago

Wouldn't it be more general/flexible to specify which screen to start on? E.g. initialScreen=1?

samreid commented 6 years ago

There is already a query parameter ?screenIndex in which you can specify the initial screen. We could rename it if desired.

pixelzoom commented 6 years ago

?screenIndex is the screen that's initially selected on the home screen. It does not start the sim on that screen. (And I'm wonder what the point of it is, and would probably recommend deleting it.)

[EDIT: Recommended deleting screenIndex.]

pixelzoom commented 6 years ago

Back to initialScreen... Semantics of the values should be the same as screens query parameter. E.g. ?screens=1,3&initialScreen=3. Numbers refer to the default set (and order) of screens, not indices that result from setting screens.

samreid commented 6 years ago

Currently, you can combine them like so: ?screenIndex=3&showHomeScreen=false

pixelzoom commented 6 years ago

screenIndex value apparently has different semantics that screens. E.g. &screens=1,3&screenIndex=3&showHomeScreen=false fails hard (not an assertion), while &screens=1,3&screenIndex=2&showHomeScreen=false works. Confusing.

If the purpose of ?screenIndex=3&showHomeScreen=false is to start the sim on a specific screen, why not collapse that to 1 query parameter, like initialScreen=3.

pixelzoom commented 6 years ago

I recommend 3 mutually-exclusive query parameters, where all screen numbers refer to indices of the default set of screens, numbered starting from 1.

screens - the screens to include, {number[]}, defaults to all screens initialScreen - the screen to display at startup, {number}, defaults to home screen homeScreen - whether to include the home screen, {boolean}, defaults to true

Delete screenIndex and showHomeScreen.

pixelzoom commented 6 years ago

At the risk of muddying the waters, I'll propose another alternative that only requires 2 query parameters, screens and initialScreen.

This approach identifies the home screen with index 0. That index would be valid in both screens and initialScreen, making homeScreen unnecessary. Examples:

For a sim that has 3 non-home screens, the default for screens would be 0,1,2,3. If you want to exclude the home screen, use ?screens=1,2,3. If you want to include the home screen, but exclude the first non-home screen, use ?screens=0,2,3.

The default for initialScreen is 0, the home screen. If you want to start with the first non-home screen, use ?initialScreen=1.

The advantage of this approach is 1 less query parameter, and the home screen is treated as a first-class screen. The disadvantage of this approach is that the user has to specify index 0 in screens, or they may inadvertently leave out the home screen. But presumably someone using screens should know what they're doing, and will notice that the home screen is missing.

zepumph commented 6 years ago

As a developer, I prefer this option. I want to hear from someone like @ariel-phet if the ?screens is used in the classroom, and how extensively. Is this a large api change for phet? Or are only power users that can adapt easily using this?

ariel-phet commented 6 years ago

@zepumph @pixelzoom a few comments:

  1. Currently, we have not advertised the ability to select screens to our users, so unlikely that any normal user (or even power user) would know how to set the screens.

  2. Although I like the cleanliness of the proposal by @pixelzoom that identifies the home screen with index 0, my designer side is a bit uncomfortable with the idea. The homescreen serves an entirely different purpose than the other screens in the sim. In addition, we have considered the possibility of using the homescreen in the future for additional settings or such that we do not feel will fit on the navbar. We have not yet made any such expansion, but I just see the homescreen as a different animal, that should be kept cognitively separate from the other screens.

pixelzoom commented 6 years ago

Also note that these query parameters can't be changed from their defaults for single-screen sims. I.e.:

screens:1, no other values allowed initialScreen:1, no other values allowed homeScreen:false, true not allowed

Rather than have to validate that the default haven't been changed for single-screen sims, perhaps it might be easiest to just disallow the use of these options for single-screen sims.

pixelzoom commented 6 years ago

@ariel-phet's second comment in https://github.com/phetsims/joist/issues/451#issuecomment-340127235 is unrelated to which approach we use. Both approaches (and this issue) deal with providing the ability to hide the home screen, albeit in slightly different ways. If we start putting non-navigation controls on the home screen, then (a) we can't hide the home screen, and (b) we need a home screen for single-screen sims (and you never know when a screen that has additional controls might be pulled out into a single-screen sim).

Imo, "additional settings" should not be solely accessible from the home screen. They should be accessible from the home screen and the navigation bar, by clicking on some UI control that displays the additional settings. Whether that's via the PhET menu or an addition control (e.g., button with a typical settings icon) is a design decision.

So... I don't think that we can provide the ability to hide the home screen without agreement that "additional settings" will not be tied solely to the home screen.

samreid commented 6 years ago

https://github.com/phetsims/joist/issues/451#issuecomment-340081541 sounds clearer to me than https://github.com/phetsims/joist/issues/451#issuecomment-340112627

zepumph commented 6 years ago

I agree, what do other devs think about proceeding with the following:

I recommend 3 mutually-exclusive query parameters, where all screen numbers refer to indices of the default set of screens, numbered starting from 1.

screens - the screens to include, {number[]}, defaults to all screens initialScreen - the screen to display at startup, {number}, defaults to home screen homeScreen - whether to include the home screen, {boolean}, defaults to true

Delete screenIndex and showHomeScreen.

pixelzoom commented 6 years ago

@zepumph asked:

I agree, what do other devs think about proceeding with the following: ...

If we provide this feature, then that's fine with me. But as I said in https://github.com/phetsims/joist/issues/451#issuecomment-340202681:

I don't think that we can provide the ability to hide the home screen without agreement that "additional settings" will not be tied solely to the home screen.

jonathanolson commented 6 years ago

I agree with @pixelzoom's proposals and thoughts above.

jbphet commented 6 years ago

I'm in agreement that @pixelzoom's first proposal (https://github.com/phetsims/joist/issues/451#issuecomment-340081541) sounds like a good plan, and I concur that if skipping the home screen is allowed then having "additional settings" on only that screen would be problematic and should be avoided.

jbphet commented 6 years ago

FYI, @zepumph said:

As a developer, I prefer this option. I want to hear from someone like @ariel-phet if the ?screens is used in the classroom, and how extensively. Is this a large api change for phet? Or are only power users that can adapt easily using this?

I just spoke with @kathy-phet about the usage of the screens query param (in relation to a different issue), and she told me that it is used by LoL, Nearpod, and by some teachers, so we should be careful not to alter how it works.

pixelzoom commented 6 years ago

@jbphet said:

... so we should be careful not to alter how it works.

That's unfortunate, because the way it works now is confusing and not a very good public interface.

kathy-phet commented 6 years ago

This still works:

I recommend 3 mutually-exclusive query parameters, where all screen numbers refer to indices of the default set of screens, numbered starting from 1. screens - the screens to include, {number[]}, defaults to all screens initialScreen - the screen to display at startup, {number}, defaults to home screen homeScreen - whether to include the home screen, {boolean}, defaults to true Delete screenIndex and showHomeScreen.

kathy-phet commented 6 years ago

The people I know only use the "screens=x,x" part.

pixelzoom commented 6 years ago

It still works. But if you want consistency across sims (as was requested when we made a similar change to the screens query parameter), then that will require republishing sims.

pixelzoom commented 6 years ago

Perhaps I misunderstood. If you're referring only to the screens query parameter, then we're likely OK.

samreid commented 6 years ago

Rather than adding a new query parameter initialScreen and deleting the existing query parameter screenIndex we would more likely rename the existing query parameter screenIndex to initialScreen

pixelzoom commented 6 years ago

... we would more likely rename the existing query parameter screenIndex to initialScreen

To clarify... Are you proposing to also keep the current behavior, where initialScreen would be the initial screen selected on the home screen, and ?initialScreen=3&showHomeScreen=false would be the required to actually start with that screen visible? That makes no sense to me - what is the point of using ?initialScreen=3 by itself? And if it's not useful by itself....?

But if you're going to do that, then please don't use initialScreen because it's not going to be the initial screen that you see. Use something like selectedScreen to indicate that it's selected.

samreid commented 6 years ago

Are you proposing to also keep the current behavior, where initialScreen would be the initial screen selected on the home screen

My apologies and you are right, I overlooked the change that initialScreen would bypass the homescreen, so it's not as simple as a rename.

zepumph commented 6 years ago

Eariler in this issue @ariel-phet said:

Although I like the cleanliness of the proposal by @pixelzoom that identifies the home screen with index 0, my designer side is a bit uncomfortable with the idea. The homescreen serves an entirely different purpose than the other screens in the sim. In addition, we have considered the possibility of using the homescreen in the future for additional settings or such that we do not feel will fit on the navbar. We have not yet made any such expansion, but I just see the homescreen as a different animal, that should be kept cognitively separate from the other screens.

It seems like this thought is in opposition to having an optional Home Screen. @ariel-phet, should we proceed with creating a homeScreen boolean query parameter that can toggle the presence of the home screen (this includes going back to it from the nav bar)? I think that there are 2 reasons that it may be good to continue with the implementation as stated above:

  1. If we ever have additional settings on the home screen, there will be some way to get to them from the rest of the sim (either in the nav bar or phet menu), so no biggy.
  2. Since the home screen "additional settings" feature is not yet set in stone, we should just go with this query parameter and then defer thinking about this until it is ready for dev/design time.

Assigning to @ariel-phet for guidance.

pixelzoom commented 6 years ago

I agree with what @zepumph said in 1. above, and will repost what I said in https://github.com/phetsims/joist/issues/451#issuecomment-340202681:

Imo, "additional settings" should not be solely accessible from the home screen. They should be accessible from the home screen and the navigation bar, by clicking on some UI control that displays the additional settings. Whether that's via the PhET menu or an addition control (e.g., button with a typical settings icon) is a design decision.

zepumph commented 6 years ago

@ariel-phet and I discussed this in the context of "additional settings". We are good to proceed with a HomeScreen query parameter. The current consensus comes from @pixelzoom:

I recommend 3 mutually-exclusive query parameters, where all screen numbers refer to indices of the default set of screens, numbered starting from 1. screens - the screens to include, {number[]}, defaults to all screens initialScreen - the screen to display at startup, {number}, defaults to home screen homeScreen - whether to include the home screen, {boolean}, defaults to true Delete screenIndex and showHomeScreen.

Any objections?

samreid commented 6 years ago

It sounds correct to me. What will the default value of the initialScreen be (that indicates to start on the home screen)?

pixelzoom commented 6 years ago
   /** 
    * Indicates whether to include the home screen. 
    * For multi-screen sims only, ignored for single-screen sims (which have no home screen).
    */
    homeScreen: {
      type: 'boolean',
      defaultValue: true
    },

   /** 
    * Specifies the initial screen that will be visible when the sim starts. 
    * See screens query parameter for screen numbering.  
    * The value is one of the values in the screens array, not an index into the screens array.  
    * For example ?screens=1,3&initialScreen=3, not ?screens=1,3&initialScreen=2.
    * For multi-screen sims only, ignored for single-screen sims.
    */
    initialScreen: {
      type: 'number',
      defautValue: 0 // the home screen
    },

    /**
     * Specifies the set of screens that appear in the sim, and their order.  
     * Uses 1-based numbering (not zero-based) and "," delimited string such as "1,3,4" to get 
     * the 1st, 3rd and 4th screen.  Note that the home screen (screen "0") is included by default. 
     * If you want to exclude the home screen, see the homeScreen query parameter.
     * For multi-screen sims only, ignored for single-screen sims.
     */
    screens: {
      type: 'array',
      elementSchema: {
        type: 'number'
      },
      defaultValue: null
    },

(EDIT: Fixed a couple of errors above.)

mbarlow12 commented 6 years ago

A quick thought on semantics (from https://github.com/phetsims/joist/issues/451#issuecomment-340817940) and @ariel-phet's design consideration (https://github.com/phetsims/joist/issues/451#issuecomment-340127235). Perhaps selectedScreen would be clearer than initialScreen. That would eliminate some potential for troublesome combinations (e.g. initialScreen:0, homeScreen: false...that might be the only example, though). The default value of 0 for initial/selected screen would not refer to the home screen in this case.

pixelzoom commented 6 years ago

@mbarlow12 said:

Perhaps selectedScreen would be clearer than initialScreen.

A screen can be selected on the home screen, but not yet visible - which was the problem with the current screenIndex query parameter.

zepumph commented 6 years ago

selectedScreen

To be clear, this query parameter is just for startup, there is a Sim.screenIndexProperty to keep track of the indices as a user interacts with the sim. Here initial seems explicit that it will only effect the startup condition.

(e.g. initialScreen:0, homeScreen: false...that might be the only example, though). The default value of 0 for initial/selected screen would not refer to the home screen in this case.

My understanding is that all indices are based on the full list, so initialScreen:0, homeScreen: false would throw an error because there is no homeScreen. Am I wrong here? That is how we handle the screens qp currently.

pixelzoom commented 6 years ago

If you want to handle invalid values for all cases (single- and multi-screen), you'll be looking at a lot of tricky logic. Another option is to ignore all 3 query parameters for single-screen sims (which I indicated in the doc above). Then you could either ignore initialScreen unless it's something other than 0', or handle theinitialScreen:0, homeScreen: false` case.

pixelzoom commented 6 years ago

Another option is to error out (rather than ignore) if any of these 3 query parameters are used with a single-screen sim. Even if the values are valid, it makes no sense to use these query parameters for a single-screen sim, and even less sense to spend time writing code to support it.

zepumph commented 6 years ago

Erroring out on a single screen sim seems reasonable to me as long as the error message is clear that the qp is superfluous/unneeded.

In general Erroring out may be a better use case for developers so that they can understand how to use these parameters. In this case I think of our LOL clients as developers also, but a teacher may not know how to open the console. . .

samreid commented 6 years ago

The value is one of the values in the screens array, not an index into the screens array.

It has been requested that we make it possible to clone/modify/shuffle screens for PhET-iO, see https://github.com/phetsims/phet-io/issues/1247. That will likely introduce a preprocessing step before we attain the screen list.

pixelzoom commented 6 years ago

@samreid said

It has been requested that we make it possible to clone/modify/shuffle screens for PhET-iO, see phetsims/phet-io#1247. That will likely introduce a preprocessing step before we attain the screen list.

Crucial requirement that was missing from this discussion. I'm no longer confident about the recommendations that I've made.

kathy-phet commented 6 years ago

For the PhET-iO functionality described above - cloning screens - I do not envision this being supported by the query parameters, this would be done through the API only due to its complexity.

zepumph commented 6 years ago

For the PhET-iO functionality described above - cloning screens - I do not envision this being supported by the query parameters, this would be done through the API only due to its complexity.

Agreed! I would go one step further and say that I don't think these query parameters should be supported with the phet-io strategy to clone/modify/shuffle screens for PhET-iO. If you are manipulating screens through the phet-io interface, then do that. If using query parameters, do that. I see them as mutually exclusive operations to manipulate screens.

samreid commented 6 years ago

Query parameters have the advantage that they are immediately available on startup (as opposed to PhET-iO calls which are asynchronous and designed to be called any time (though can be applied as initial expressions)), and easy to implement and test. I agree that general sim clients wouldn't want to use this query parameter, but I don't think we should rule out query parameters as the implementation strategy for screen cloning.

For instance, we could design a query parameter like: ?screenMap=1@introScreen,1@advancedScreen,3@frictionScreen which would launch the sim with screen 1 named as "introScreen" then another copy of screen 1 named as "advanced screen" then screen 3 named as "frictionScreen". This would create a new list of screens which can be selected/combined with the previously proposed query parameters.

samreid commented 6 years ago

To implement the proposal above, sims mains would need to be retrofitted like so (beers law lab for example):

  var screenFactories = [
    function( tandemName ) {
      return new ConcentrationScreen( tandem.createTandem( tandemName || 'concentrationScreen' ) )
    }, function( tandemName ) {
      return new BeersLawScreen( tandem.createTandem( tandemName || 'beersLawScreen' ) )
    }
  ];

  var screens = Sim.mapScreens( screenFactories );

  SimLauncher.launch( function() {
    var sim = new Sim( beersLawLabTitleString, screens, simOptions );
    sim.start();
  } );

I used the optional tandem so the default tandems can be associated with their screens (instead of letting them get separated).

Here's the auxiliary function in Sim.js

    mapScreens: function( screenFactories ) {
      var screens = [];
      var x = phet.chipper.queryParameters.screenMap;
      if ( x.length > 0 ) {

        // remap screens like ?screenMap=1@helloScreen,1@thereScreen
        var screenSpecs = x.split( ',' );
        for ( var i = 0; i < screenSpecs.length; i++ ) {
          var screenSpec = screenSpecs[ i ];
          var specStrings = screenSpec.split( '@' );
          var screenIndex = parseInt( specStrings[ 0 ], 10 ) - 1;
          var tandemName = specStrings[ 1 ];
          var screenFactory = screenFactories[ screenIndex ];
          screens.push( screenFactory( tandemName ) );
        }
      }
      else {

        // default screens
        for ( var k = 0; k < screenFactories.length; k++ ) {
          var factory = screenFactories[ k ];
          screens.push( factory() );
        }
      }
      return screens;
    }

And the query parameter would be like:

    screenMap: {
      type: 'string',
      defaultValue: ''
    },

This implementation has the desired behavior:

image

Note the "helloScreen" and "thereScreen" in the tandems.

zepumph commented 6 years ago

It does seem like query parameters are pretty straightforward in that case. What about other data we want to pass for the custom screens like the display name (needs to be URI encoded?) or the icon. I like this conversation for prototyping, couldn't we have a pretty similar interface but through TPhETIO, that way we could get everything set into the frame before the sim is even launched.

Also should we move back to https://github.com/phetsims/phet-io/issues/1247 for this? Maybe the best solution for this issue (about home screen query parameter) is to see where phetsims/phet-io#1247 goes and then take it from there.

samreid commented 6 years ago

What about other data we want to pass for the custom screens like the display name (needs to be URI encoded?) or the icon.

I think it makes sense to use Query Parameters to set up the screens (which has to be done before the simulation starts), then rely on the existing PhET-iO APIs for setting titles/icons and further customization.

couldn't we have a pretty similar interface but through TPhETIO, that way we could get everything set into the frame before the sim is even launched.

Sure, that could work nicely too (just harder to test because it requires a wrapper). But I think we should try it.

Also should we move back to phetsims/phet-io#1247 for this?

Yes, and I think we can continue here as long as we perceive the list of sims as a preprocessed list from query parameters or phet-io API.

zepumph commented 6 years ago

... I think we can continue here as long as we perceive the list of sims as a preprocessed list from query parameters or phet-io API.

Agreed, I still recommend the same suggestion from https://github.com/phetsims/joist/issues/451#issuecomment-340081541.

Still to decide is how they co-exist. Erroring out or ignoring through a heirarchy?

kathy-phet commented 6 years ago

For the advanced case of cloning a screen in PhET-iO, I still feel like we can require clients to use the API (using expressions to get it prior to start up?) approach for that. It's an advance use-case and so it doesn't seem like we should worry about presenting query option here -- it seems to overcomplicate the options (to me).

zepumph commented 6 years ago

@kathy-phet I responded in https://github.com/phetsims/phet-io/issues/1247#issuecomment-340936354

samreid commented 6 years ago

Let's try @zepumph idea to set it through TPhETIO API in https://github.com/phetsims/joist/issues/451#issuecomment-340933680