IjzerenHein / famous-flex

Animatable layouts, FlexScrollView & widgets for famo.us.
MIT License
279 stars 44 forks source link

LayoutController insert 0 not working #113

Closed hchoong closed 9 years ago

hchoong commented 9 years ago

I am trying to insert surface to the top of the layout, but the surface doesn't seem to be rendered. I checked the getDataSource() and the added surface is in the list, but not rendered on the screen.

Sample code I am using:

define(function(require, exports, module) {
  var View = require('famous/core/View');
  var Surface = require('famous/core/Surface');
  var LayoutController = require('famous-flex/LayoutController');
  var ListLayout = require('famous-flex/layouts/ListLayout');
  var CollectionLayout = require('famous-flex/layouts/CollectionLayout');

  function Debug(options) {
    View.apply(this, arguments);
    this.layout = new LayoutController({
      layout: ListLayout,
      flow: true,
      direction: 1,
      autoPipeEvents: true,
      alwaysLayout: true,
      layoutOptions: {
        margins: [0, 15]
      }
    });
    this.add(this.layout);

    this.contentHeaderSurface = new Surface({
      size: [undefined, 34],
      content: 'contentHeaderSurface'
    });
    this.layout.push(this.contentHeaderSurface);

    this.addButton = new Surface({
      size: [undefined, 40],
      content: 'Add Surface',
      properties: {
        backgroundColor: '#144170',
        color: '#fff',
        textAlign: 'center',
        padding: '8px'
      }
    });
    this.addButton.on('click', this._onaddButtonClick.bind(this));

    this.removeButton = new Surface({
      size: [undefined, 40],
      content: 'Remove Surface',
      properties: {
        backgroundColor: '#ffbf25',
        color: '#000',
        textAlign: 'center',
        padding: '8px'
      }
    });
    this.removeButton.on('click', this._onremoveButtonClick.bind(this));

    this.buttons_grid = new LayoutController({
      layout: CollectionLayout,
      layoutOptions: {
        direction: 1,
        cells: [2, 1],
        spacing: [15, 0]
      },
      dataSource: [
        this.addButton,
        this.removeButton
      ]
    });
    this.layout.push(this.buttons_grid);
  }

  Debug.prototype = Object.create(View.prototype);
  Debug.prototype.constructor = Debug;
  Debug.prototype._onremoveButtonClick = function() {
    this.layout.remove(this.contentHeaderSurface);
  };
  Debug.prototype._onaddButtonClick = function() {
    this.layout.insert(0, this.contentHeaderSurface);
  };
  module.exports = Debug;
});
hchoong commented 9 years ago

Insert is working for FlexScrollView but not for LayoutController. Can you suggest which way is better?

IjzerenHein commented 9 years ago

Hmm, that's weird. Just wondering, have you tried ensureVisible(..) on the newly inserted surface. Does that fix your problem?

EDIT: Ignore that completely, LayoutController doesn't have 'ensureVisible', I was a bit tipsy when I wrote that last night.

hchoong commented 9 years ago

ensureVisible(..) is only available for ScrollController. It doesn't work with LayoutController. I will use ScrollController and disable the scroll.

IjzerenHein commented 9 years ago

Hey Howard,

I know what the problem is. The layout-controller doesn't change the "first visible node" when you insert a node. Using ScrollController is an option, but do note that when you "insert" before the first visible node, it doesn't necessarily show that node. If you want to ensure that the node is visible also call ensureVisible on ScrollController.

An other option would be to to reset the whole datasource of the layoutcontroller, this way it will always render from the first node in the datasource:

layoutController.setDataSource([header,content]);
hchoong commented 9 years ago

I like the latter option since flex controller will calls the layout function when I add/remove elements. This way I can ensure the correct elements rendered on the screen and the performance should be the same.

IjzerenHein commented 9 years ago

Awesome, glad to hear that's a suitable solution.

As for fixing this.. I've decided not to fix this in the current famous-flex version. Instead I will be focusing on the mixed-mode version and will take this issue into account when writing the new LayoutController.

cheers