      1 /*
      2     Copyright 2008-2017
      3         Matthias Ehmann,
      4         Michael Gerhaeuser,
      5         Carsten Miller,
      6         Bianca Valentin,
      7         Alfred Wassermann,
      8         Peter Wilfahrt
      9
     10     This file is part of JSXGraph.
     11
     12     JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
     13
     14     You can redistribute it and/or modify it under the terms of the
     15
     16       * GNU Lesser General Public License as published by
     17         the Free Software Foundation, either version 3 of the License, or
     18         (at your option) any later version
     19       OR
     20       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
     21
     22     JSXGraph is distributed in the hope that it will be useful,
     23     but WITHOUT ANY WARRANTY; without even the implied warranty of
     24     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     25     GNU Lesser General Public License for more details.
     26
     27     You should have received a copy of the GNU Lesser General Public License and
     28     the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
     29     and <http://opensource.org/licenses/MIT/>.
     30  */
     31
     32
     33 /*global JXG: true, define: true, window: true*/
     34 /*jslint nomen: true, plusplus: true*/
     35
     36 /* depends:
     37  jxg
     38  utils/env
     39  utils/type
     40  */
     41
     42 /**
     43  * @fileoverview In this file the Text element is defined.
     44  */
     45
     46 define([
     47     'jxg', 'utils/env', 'utils/type'
     48 ], function (JXG, Env, Type) {
     49
     50     "use strict";
     51
     52     var priv = {
     53             ButtonClickEventHandler: function () {
     54                 if (this._handler) {
     55                     this._handler();
     56                 }
     57                 this.board.update();
     58             }
     59         };
     60
     61     /**
     62      * @class This element is used to provide a constructor for special texts containing a form button element.
     63      *
     64      * @pseudo
     65      * @description
     66      * @name Button
     67      * @augments Text
     68      * @constructor
     69      * @type JXG.Text
     70      *
     71      * @param {number,function_number,function_String_function} x,y,label,handler Parent elements for button elements.
     72      *                     <p>
     73      *                     x and y are the coordinates of the lower left corner of the text box.
     74      *                      The position of the text is fixed,
     75      *                     x and y are numbers. The position is variable if x or y are functions.
     76      *                     <p>
     77      *                     The label of the input element may be given  as string.
     78      *                     <p>
     79      *                     The (optional) handler function which is called when the button is pressed.
     80      *
     81      * @example
     82      *  var p = board.create('point', [0.5, 0.5], {id: 'p1'});
     83      *
     84      *  // Create a button element at position [1,2].
     85      *  var button1 = board.create('button', [1, 2, 'Change Y with JavaScript', function() {
     86      *      p.moveTo([p.X(), p.Y() + 0.5], 100);
     87      *  }], {});
     88      *
     89      *  // Create a button element at position [1,4].
     90      *  var button2 = board.create('button', [1, 4, 'Change Y with JessieCode',
     91      *      "$('p1').Y = $('p1').Y() - 0.5;"
     92      *  ], {});
     93      *
     94      * </pre><div class="jxgbox" id="f19b1bce-dd00-4e35-be97-ff1817d11514" style="width: 500px; height: 300px;"></div>
     95      * <script type="text/javascript">
     96      *  var t1_board = JXG.JSXGraph.initBoard('f19b1bce-dd00-4e35-be97-ff1817d11514', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});
     97      *  var p = t1_board.create('point', [0, -1], {id: 'p1'});
     98      *
     99      *  // Create a button element at position [1,2].
    100      *  var button1 = t1_board.create('button', [1, 2, 'Change Y with JavaScript', function() {
    101      *      p.moveTo([p.X(), p.Y() + 0.5], 100);
    102      *  }], {});
    103      *
    104      *  // Create a button element at position [1,4].
    105      *  var button2 = t1_board.create('button', [1, 4, 'Change Y with JessieCode',
    106      *      "$('p1').Y = $('p1').Y() - 0.5;"
    107      *  ], {});
    108      *
    109      * </script><pre>
    110      * [x, y, label, handler]
    111      */
    112     JXG.createButton = function (board, parents, attributes) {
    113         var t, par,
    114             attr = Type.copyAttributes(attributes, board.options, 'button');
    115
    116         //if (parents.length < 3) {
    117             //throw new Error("JSXGraph: Can't create button with parent types '" +
    118             //    (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." +
    119             //    "\nPossible parents are: [x, y, label, handler]");
    120         //}
    121
    122         par = [parents[0], parents[1], '<button type="button" style="width:100%;"></button>'];
    123
    124         t = board.create('text', par, attr);
    125         t.type = Type.OBJECT_TYPE_BUTTON;
    126
    127         t.rendNodeButton = t.rendNode.childNodes[0];
    128         t.rendNodeButton.id = t.rendNode.id + '_button';
    129         t.rendNodeButton.innerHTML = parents[2];
    130
    131         t.rendNodeTag = t.rendNodeButton; // Needed for unified treatment in setAttribute
    132         t.rendNodeTag.disabled = !!attr.disabled;
    133
    134         // This sets the font-size of the button text
    135         t.visPropOld.fontsize = "0px";
    136         board.renderer.updateTextStyle(t, false);
    137
    138         if (parents[3]) {
    139             if (Type.isString(parents[3])) {
    140                 t._jc = new JXG.JessieCode();
    141                 t._jc.use(board);
    142                 t._handler = function () {
    143                     t._jc.parse(parents[3]);
    144                 };
    145             } else {
    146                 t._handler = parents[3];
    147             }
    148         }
    149
    150         Env.addEvent(t.rendNodeButton, 'click', priv.ButtonClickEventHandler, t);
    151
    152         Env.addEvent(t.rendNodeButton, 'mousedown', function(evt) { evt.stopPropagation(); }, t);
    153         Env.addEvent(t.rendNodeButton, 'touchstart', function(evt) { evt.stopPropagation(); }, t);
    154         Env.addEvent(t.rendNodeButton, 'pointerdown', function(evt) { evt.stopPropagation(); }, t);
    155
    156         return t;
    157     };
    158
    159     JXG.registerElement('button', JXG.createButton);
    160
    161     return {
    162         createButton: JXG.createButton
    163     };
    164 });
    165