Pictures in drop down menu

762 views
Skip to first unread message

Cherie Pun

unread,
Sep 2, 2015, 8:31:55 AM9/2/15
to Blockly
Hi,

Is it possible to use pictures instead of words in the drop down menu?

Cheers,
Cherie

Neil Fraser

unread,
Sep 2, 2015, 5:42:25 PM9/2/15
to blo...@googlegroups.com
Not at the moment.  Though the expressiveness of Unicode characters should not be underestimated. 
http://jrgraphix.net/r/Unicode/2600-26FF

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Cherie Pun

unread,
Sep 3, 2015, 4:08:14 AM9/3/15
to Blockly, ro...@neil.fraser.name
Thanks Neil. Is it possible then to append a picture next to the drop down menu and then dynamically change it according to the chosen option in the drop down?

Kind regards,
Cherie

Neil Fraser

unread,
Sep 3, 2015, 9:56:39 AM9/3/15
to blo...@googlegroups.com
Curiously, a dropdown changing an image doesn't seem to have been done before.  Here is a sample block that does this:

Blockly.Blocks['demo_image'] = {
  /**
   * Demo block for image changing.
   * @this Blockly.Block
   */
  init: function() {
    var options = [
      ['no', 'https://neil.fraser.name/common/no.gif'],
      ['yes', 'https://neil.fraser.name/common/yes.gif']
    ];
    var thisBlock = this;
    var dropdown = new Blockly.FieldDropdown(options,
        function(newOp) {
          thisBlock.updateImage_(newOp);
        });
    this.appendDummyInput()
        .appendField(dropdown, 'SOURCE')
        .appendField(new Blockly.FieldImage('', 11, 11, '*'), 'IMAGE');
    this.setColour(20);
  },
  /**
   * Modify this block to have the chosen image.
   * @param {string} newOp URL of image.
   * @private
   * @this Blockly.Block
   */
  updateImage_: function(newOp) {
    this.getField('IMAGE').setValue(newOp);
  },
  /**
   * Create XML to represent the selected image.
   * @return {Element} XML storage element.
   * @this Blockly.Block
   */
  mutationToDom: function() {
    var container = document.createElement('mutation');
    container.setAttribute('img', this.getFieldValue('IMAGE'));
    return container;
  },
  /**
   * Parse XML to restore the selected image.
   * @param {!Element} xmlElement XML storage element.
   * @this Blockly.Block
   */
  domToMutation: function(xmlElement) {
    this.updateImage_(xmlElement.getAttribute('img'));
  }
};


And add this to your toolbox:

  <block type="demo_image">
    <mutation img="https://neil.fraser.name/common/no.gif"></mutation>
  </block>

Most of the complexity here comes from the mutator functions.  These are needed to preserve and restore the current image when the block is converted back and forth between XML.  This happens when blocks are saved, created from the toolbox, duplicated, and so on.

Neil Fraser

unread,
Sep 3, 2015, 10:56:53 AM9/3/15
to blo...@googlegroups.com
Never mind the previous response, it turns out one can set image fields to EDITABLE.  This saves them in XML.  Using this technique the code is way simpler:

Blockly.Blocks['demo_image'] = {
  /**
   * Demo block for image changing.
   * @this Blockly.Block
   */
  init: function() {
    var options = [
      ['no', 'https://neil.fraser.name/common/no.gif'],
      ['yes', 'https://neil.fraser.name/common/yes.gif']
    ];
    var dropdown = new Blockly.FieldDropdown(options,
        function(newOp) {
          this.sourceBlock_.getField('IMAGE').setValue(newOp);

        });
    this.appendDummyInput()
        .appendField(dropdown, 'SOURCE')
        .appendField(new Blockly.FieldImage('', 11, 11, '*'), 'IMAGE');
    this.getField('IMAGE').EDITABLE = true;
    this.setColour(20);
  }
};

And add this to your toolbox:

  <block type="
demo_image">
    <field name="SOURCE">https://neil.fraser.name/common/no.gif</field>
    <field name="IMAGE">https://neil.fraser.name/common/no.gif</field>
  </block>


On 3 September 2015 at 01:08, Cherie Pun <cherie...@gmail.com> wrote:

Cherie Pun

unread,
Sep 3, 2015, 11:36:46 AM9/3/15
to Blockly, ro...@neil.fraser.name
Thanks a lot Neil! I actually tried something similar to your first solution but deleting and recreating image field every time. Then I ran into the problem of loading saved blocks and picture is not loaded correctly.
Thank you very much for your help, I will try your second solution now! :)

Kind regards,
Cherie

Cherie Pun

unread,
Sep 3, 2015, 11:42:30 AM9/3/15
to Blockly, ro...@neil.fraser.name
Why do I have to add this code in the toolbox?
  <block type="
demo_image">
   
<field name="SOURCE">https://neil.fraser.name/common/no.gif</field>
   
<field name="IMAGE">https://neil.fraser.name/common/no.gif</field>
 
</block>


Cheers,

Cherie

On Thursday, 3 September 2015 15:56:53 UTC+1, Neil Fraser wrote:

Neil Fraser

unread,
Sep 3, 2015, 11:48:24 AM9/3/15
to blo...@googlegroups.com
The 'SOURCE' will set the dropdown.  If you are ok with defaulting to the first entry, you can skip this.
The 'IMAGE' will set the inital image.  If you hardcode this value in the init, then you can skip this too.
new Blockly.FieldImage('https://neil.fraser.name/common/no.gif', 11, 11, '*')

Cherie Pun

unread,
Sep 3, 2015, 12:01:23 PM9/3/15
to Blockly, ro...@neil.fraser.name
Thanks. Another question, what's the use of setting the image field to EDITABLE? It seems that the second solution is doing things similar to the first one.

Thanks,
Cherie

Neil Fraser

unread,
Sep 3, 2015, 12:16:33 PM9/3/15
to blo...@googlegroups.com
EDITABLE means that the field's contents will be saved as part of the XML and also restored from XML.  Without it, the contents needs to be manually saved and restored using a mutation field.  Most fields are editable, but text labels and images are normally static so they don't save their contents to the XML.

Yes, both solutions are doing exactly the same thing.  The first one does it all manually, the second gets Blockly to do it all for you.

Cherie Pun

unread,
Sep 3, 2015, 12:53:29 PM9/3/15
to Blockly, ro...@neil.fraser.name
I see, thanks for the clear explanaiont. I got it working!

Cheers,
Cherie
Reply all
Reply to author
Forward
0 new messages