File:  [LON-CAPA] / modules / damieng / graphical_editor / loncapa_daxe / web / nodes / option_foil.dart
Revision 1.12: download - view: text, annotated - select for diffs
Tue Feb 28 20:40:59 2017 UTC (7 years, 3 months ago) by damieng
Branches: MAIN
CVS tags: HEAD
updates following changes in Daxe Config API

/*
  This file is part of LONCAPA-Daxe.

  LONCAPA-Daxe is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  LONCAPA-Daxe is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Daxe.  If not, see <http://www.gnu.org/licenses/>.
*/

part of loncapa_daxe;

/**
 * Display for a foil inside an optionresponse.
 * Uses a simplified UI if the parent (OptionFoilgroup) is.
 */
class OptionFoil extends LCDBlock {
  
  OptionFoil.fromRef(x.Element elementRef) : super.fromRef(elementRef) {
  }
  
  OptionFoil.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) {
  }
  
  @override
  bool simpleUIPossible() {
    final RegExp numberedFoil = new RegExp("^[fF]oil[0-9]+\$");
    for (DaxeAttr att in attributes)
      if (!(att.name == 'value' ||
          (att.name == 'name' && numberedFoil.hasMatch(att.value)) ||
          (att.name == 'location' && att.value == 'random')))
        throw new SimpleUIException('foil: ' + LCDStrings.get('attribute_problem') + att.name);
    return SimpleUIText.checkNodeContents(this);
  }
  
  void setupRestrictions() {
    if (restrictedInserts == null)
      restrictedInserts = SimpleUIText.possibleDescendants;
  }
  
  @override
  h.Element html() {
    simpleUI = parent is OptionFoilgroup && (parent as OptionFoilgroup).simpleUI;
    if (!simpleUI)
      return super.html();
    setupRestrictions();
    
    h.TableRowElement tr = new h.TableRowElement();
    tr.id = id;
    OptionFoilgroup group = parent;
    h.TableCellElement td = new h.TableCellElement();
    h.ImageElement grip = new h.ImageElement(src:'images/grip.png', width:8, height:16);
    grip.classes.add('grip-icon');
    setupDrag(grip);
    td.append(grip);
    if (!group.checkboxes) {
      h.SelectElement select = new h.SelectElement();
      String foilValue = getAttribute('value');
      List<String> options = (parent as OptionFoilgroup).options;
      for (String value in options) {
        h.OptionElement opte = new h.OptionElement(data:value, selected:value==foilValue);
        select.append(opte);
      }
      if (foilValue != null && !options.contains(foilValue)) // FIXME: should not happen
        select.append(new h.OptionElement(data:foilValue, selected:true));
      select.onChange.listen((h.Event event) {
        if (select.selectedIndex >= 0)
          doc.doNewEdit(new UndoableEdit.changeAttribute(this,
              new DaxeAttr('value', options[select.selectedIndex]), updateDisplay:false));
      });
      td.append(select);
    } else {
      h.CheckboxInputElement cb = new h.CheckboxInputElement();
      cb.checked = (getAttribute('value') == group.checkedValue);
      cb.onChange.listen((h.Event event) {
        doc.doNewEdit(new UndoableEdit.changeAttribute(this,
            new DaxeAttr('value', cb.checked ? group.checkedValue : group.uncheckedValue), updateDisplay:false));
      });
      td.append(cb);
    }
    tr.append(td);
    td = new h.TableCellElement();
    for (DaxeNode dn=firstChild; dn!= null; dn=dn.nextSibling) {
      td.append(dn.html());
    }
    tr.append(td);
    td = new h.TableCellElement();
    h.ImageElement deleteImg = new h.ImageElement(src:'images/delete.png', width:16, height:16);
    deleteImg.classes.add('delete-icon');
    deleteImg.onClick.listen((h.MouseEvent e) => deleteFoil());
    td.append(deleteImg);
    tr.append(td);
    return tr;
  }
  
  @override
  h.Element getHTMLContentsNode() {
    if (!simpleUI)
      return super.getHTMLContentsNode();
    return(getHTMLNode().nodes[1]);
  }
  
  @override
  void updateAttributes() {
    if (!simpleUI) {
      super.updateAttributes();
      return;
    }
    updateHTML();
  }
  
  void deleteFoil() {
    doc.removeNode(this);
  }
  
  int getRank() {
    int nb = 1;
    for (DaxeNode dn=previousSibling; dn!=null; dn=dn.previousSibling) {
      if (dn is OptionFoil)
        nb++;
    }
    return nb;
  }
  
  /**
   * In advanced UI, suggest a list of option values for the value attribute.
   */
  @override
  h.TableRowElement attributeHTML(x.Element refAttr) {
    String name = doc.cfg.attributeName(refAttr);
    OptionFoilgroup group;
    if (parent is OptionFoilgroup)
      group  = parent;
    else if (parent.parent is OptionFoilgroup)
      group  = parent.parent;
    else
      group = null;
    List<String> options;
    if (group != null)
      options = group.parseOptions();
    else
      options = null;
    if (simpleUI || name != 'value' || options == null || options.length == 0)
      return super.attributeHTML(refAttr);
    // in advanced UI, suggest the option values (but keep it possible to use a Perl variable)
    h.TableRowElement tr = super.attributeHTML(refAttr);
    SimpleTypeControl attributeControl = attributeControls['value'];
    attributeControl.suggestedValues = options;
    h.Element ht = attributeControl.html();
    (ht.firstChild.nextNode as h.TextInputElement).classes.add('form_field');
    tr.childNodes[2].replaceWith(ht);
    return tr;
  }
  
  // NOTE: see RadioFoil for explanations about these 2 overrides
  
  @override
  String getAttribute(String name) {
    if (!simpleUI || name != 'name')
      return super.getAttribute(name);
    // for validation, return a value
    int nb = getRank();
    OptionFoilgroup group = parent as OptionFoilgroup;
    String prefix = group.simpleFoilNamePrefix;
    return "$prefix$nb";
  }
  
  @override
  x.Node toDOMNode(x.Document domDocument) {
    x.Node node = super.toDOMNode(domDocument);
    RadioFoil.replaceSingleParagraphByContents(node);
    // set name and value attributes if necessary
    if (!simpleUI || parent == null)
      return node;
    x.Element el = node as x.Element;
    int nb = getRank();
    OptionFoilgroup group = parent as OptionFoilgroup;
    String prefix = group.simpleFoilNamePrefix;
    el.setAttribute('name', "$prefix$nb");
    if (el.getAttribute('value') == null && group.options.length > 0)
      el.setAttribute('value', group.options[0]);
    return el;
  }
  
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>