javascriptphaser-frameworkphaserjs

How can i add another panel into a Rex ScrollablePanel when click a button?


Basically, i want to create a mini chat dialog, when i type and click send, it will display into a scrollable table. First i add an click event:

 this.dialogChatInput.addListener("click");
    this.dialogChatInput.on("click", (event) => {
      if (event.target.id === "sendButton") {
        var inputChat = this.dialogChatInput.getChildByName("nameFieldChat");

        if (inputChat.value !== "") {
          console.log(`Chat : ${inputChat.value}`);
          
        }
      }
    });

Then i try to create an srcrollable table:

var panel = this.rexUI.add
      .scrollablePanel({
        x: this.dialogKhungHienThi.x + 225,
        y: this.dialogKhungHienThi.y,
        height: 1200,

        scrollMode: 0,

        background: this.rexUI.add.roundRectangle({
          // strokeColor: transparent,
          strokeWidth: 2,
        }),
        panel: {
          child: CreatePanel(this),
        },

        slider: {
          track: this.rexUI.add.roundRectangle({
            width: 20,
            height: 20,
            radius: 40,
            color: COLOR_TRACK,
          }),
          thumb: this.rexUI.add.roundRectangle({
            radius: 50,
            color: COLOR_THUMB,
          }),
        },

        space: { panel: 4 },
      })
      .layout();

Outside Create() i have function to create panel:

var CreatePanel = function (scene, data) {
  var panel = scene.rexUI.add.sizer({
    width: 100,
    orientation: "y",
    space: { item: 4 },
  });

  if (ngu) {
    var name = `item-${i}`;
    var label = scene.rexUI.add.label(
      {
        height: 350,
        width: 1000,
        background: scene.rexUI.add.roundRectangle({
          // color: COLOR_PRIMARY,
        }),
        icon: scene.add.image(0, 0, "avatarDemo").setScale(2),
        text: scene.add
          .text(10, 10, ` ${hour} :  ${minute}: ${second} `, {
            font: "70px Arial",
            fill: "#ffffff",
            stroke: "black",
            strokeThickness: 15,
          })
          .setFontSize("70px"),
        wrapText: true,
        name: name,
      },
      this
    );
    panel.add(label, { expand: true });
  }

  return panel;
};

i try to move my var panel inside onclick() but it didnt work? Can anybody have any suggestion?


Solution

  • Well the easy solution is to create a funciton on the scene, that you can call from the button - event. Something like this addLine.
    And in the function you simply add a control to the panel, and update the layout of the surrounding controls.

    There might be better solutions, but this is the first that comes to mind.

    Short Demo:

    /* let button = document.querySelector('#button');
    
    button.addEventListener('click', () => {
        // Depending on how many scenes you are using you would have to change this line
        game.scene.scenes[0].addLine('Button Click');
    });*/
    
    class Demo extends Phaser.Scene {
        preload() {
            this.load.scenePlugin({
                key: 'rexuiplugin',
                url: 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rexuiplugin.min.js',
                sceneKey: 'rexUI'
            });
        }
        create() {
            this.textPanel = CreatePanel(this);
            this.chatBox = this.rexUI.add
                .scrollablePanel({
                    x: config.width / 2 + 50,
                    y: config.height / 2,
                    width: 380,
                    height: 160,
                    background: this.rexUI.add.roundRectangle(0, 0, 2, 2, 10, 0xcdcdcd),
                    scrollMode: 0,
                    scroller: true,
                    panel: {
                        child: this.textPanel,
                    },
                    slider: {
                        track: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, 0xffffff),
                        thumb: this.rexUI.add.roundRectangle(0, 0, 0, 0, 13, 0x0),
                    },
                    space: {
                        left: 10,
                        right: 10,
                        top: 10,
                        bottom: 10,
                        panel: 10,
                    }
                })
                .layout();
    
            this.addLine('Enter Text and press the Button');
        }
    
        // function to add Lines
        addLine(text) {
            let newLineControl = this.rexUI.add.label({
                orientation: 1,
                text: this.add.text(0, 0, text),
                expandTextWidth: true,
            });
            this.textPanel.add(newLineControl);
    
            // You have to re-layout every wrapping control
            this.textPanel.layout();
            this.chatBox.layout();
            
            this.demoDOMElements();
        }
        
        demoDOMElements(){
            let textbox = this.add.dom(4, 4, 'input', 'width: 100px; font: 16px Arial')
                .setOrigin(0);
            textbox.node.valiue = "Initial Text";
            let button = this.add.dom(4, 30, 'button', 'width: 100px; font: 16px Arial', 'Add Line')
                .setOrigin(0);
    
            button.addListener('click');
            button.on('click', function (event){
              this.addLine(textbox.node.value);
            }, this);
            
        }
    }
    
    var CreatePanel = function (scene, data) {
        var panel = scene.rexUI.add.sizer({
            width: 100,
            orientation: "y",
            space: { item: 4 },
        });
        return panel;
    };
    
    var config = { width: 510, height: 180, scene: Demo, parent: 'phaser', dom: {
            createContainer: true
        }};
    
    // globale Variabel for Phaser GameObject
    var game = new Phaser.Game(config);
    console.clear();
    <script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
    <!-- <button id="button"> add Line </button> -->
    <br />
    <div id="phaser"></div>