.. role:: ts-api-decorator

#############
OperatorStack
#############

.. js:module:: cee
   :noindex:

.. container:: ts-api-section

   .. js:class:: OperatorStack

      The ``OperatorStack`` manages registered ``Operator`` instances for a view. Any active operators on
      the stack will be called in a "Last In, First Called" order. An operator event listener method (i.e. onMouseDown, 
      onWheel, onKeyDown, etc.) will return an ``OperatorEventStatus`` to indicate whether the particular 
      event should be propagated to the next operator in the stack, or if it should be stopped.

      Since multiple operators can be added to the stack and respond to the same single event, the order of 
      operators matters and it is important to understand an operator propagates different events.
      It is recommend that more global operators, such as the ``NavigationOperator``, are added first, 
      and more specific and local operators are added last. This way, local operations can be captured and handled before
      they are propagated to the more global operations, if so desired.

      When a new operator is pushed to the stack, the operator stack will track the reference to that operator object. 
      You can then use the ``OperatorStack.get`` method to retrieve a reference to the operator object by name (regardless 
      of whether that operator object is active and on the stack or not). The prevents the need to instantiate and
      set up the same operator again, and preserves the state of any setup operators. If you push a new instance of an operator 
      with a previously used name, the old operator reference will be replaced with the new one. 

      By default, the ``OperatorStack`` is empty when a ``View`` is created. It is the developers responsibility to add
      any desired default operators in your application. You can remove operators with the ``OperatorStack.pop``, 
      ``OperatorStack.remove``, or ``OperatorStack.clear`` methods.



.. container:: api-index-section

   .. rubric:: Accessors

   .. rst-class:: api-index-list-item api-kind-accessor api-parent-kind-class

   * :js:attr:`~cee.OperatorStack.activeOperators`
   * :js:attr:`~cee.OperatorStack.hotKeyOperator`



.. container:: api-index-section

   .. rubric:: Methods

   .. rst-class:: api-index-list-item api-kind-method api-parent-kind-class

   * :js:meth:`~cee.OperatorStack.clear`
   * :js:meth:`~cee.OperatorStack.get`
   * :js:meth:`~cee.OperatorStack.has`
   * :js:meth:`~cee.OperatorStack.indexOf`
   * :js:meth:`~cee.OperatorStack.peek`
   * :js:meth:`~cee.OperatorStack.pop`
   * :js:meth:`~cee.OperatorStack.push`
   * :js:meth:`~cee.OperatorStack.remove`
   * :js:meth:`~cee.OperatorStack.set`
   * :js:meth:`~cee.OperatorStack.size`





------------

Accessors
=========

.. container:: ts-api-section

   .. js:function:: OperatorStack.activeOperators()



      Returns the array of active ``Operator`` objects


      :rtype: [Operator]



.. container:: ts-api-section

   .. js:function:: OperatorStack.hotKeyOperator()



      Sets the hot key operator for this operator stack. 
      The hot key (Alt/Opt) can be held to temporarily use
      this operator without reordering the stack. The operator
      must already be in the stack to be used with the hot key. Other
      stack operators will not be called while the hot key is held.
      To remove the hot key operator designation, but keep the operator
      on the stack, set the hot key operator to null.


      :rtype: Operator

   .. js:function:: OperatorStack.hotKeyOperator( operator)

      :param operator: None
      :type operator: Operator


      :rtype: void



Methods
=======

.. rst-class:: ts-api-section

clear
-----

.. js:method:: OperatorStack.clear()



   Removes all operators from the stack


   :rtype: void

.. rst-class:: ts-api-section

get
---

.. js:method:: OperatorStack.get( operatorName)

   :param operatorName: None
   :type operatorName: S


   Returns a reference to the operator object with the given name and type. 
   The desired operator does not need to be active on the stack.
   If the operator was pushed to the stack during the lifetime of the view, 
   it is registered and the reference to the operator can be returned.

   If the operator is not found, null will be returned. You can always
   check if the operator is registered by using the ``OperatorStack.has`` method

   Exmaple usage:

   .. code-block:: typescript

      // Standard Operator
      const standardOperator = view.operators.get(cee.StandardOperator.OPERATOR_ENUM);

      // Custom User-Provided Operator
      const myCustomOperator = view.operators.get(MyCustomOperatorName) as MyCustomOperator;
      const myCustomOperator = view.operators.get<MyCustomOperator>(MyCustomOperatorName);

      // Generic Operator
      const generic = view.operators.get("MyOperatorName");  // Returns Operator type w/o cast



   :rtype: GetOperatorType <S, T>

.. rst-class:: ts-api-section

has
---

.. js:method:: OperatorStack.has( operator)

   :param operator: None
   :type operator: string


   Returns true if the operator has been registered with the operator stack.


   :rtype: boolean

.. rst-class:: ts-api-section

indexOf
-------

.. js:method:: OperatorStack.indexOf( operator)

   :param operator: None
   :type operator: Operator


   Returns the index of an operator on the stack
   If the operator is not found on the stack, -1 is returned.


   :rtype: number

.. rst-class:: ts-api-section

peek
----

.. js:method:: OperatorStack.peek()



   Returns the operator at the top of the stack


   :rtype: Operator

.. rst-class:: ts-api-section

pop
---

.. js:method:: OperatorStack.pop()



   Removes an operator from the top of the stack


   :rtype: Operator

.. rst-class:: ts-api-section

push
----

.. js:method:: OperatorStack.push( operator[, setAsHotKeyOperator])

   :param operator: None
   :type operator: Operator
   :param setAsHotKeyOperator: :ts-api-decorator:`optional` None
   :type setAsHotKeyOperator: boolean


   Adds an operator on the stack if it's not already on the stack


   :rtype: boolean

.. rst-class:: ts-api-section

remove
------

.. js:method:: OperatorStack.remove( operatorInput)

   :param operatorInput: None
   :type operatorInput: string | Operator


   Removes an operator from the stack


   :rtype: void

.. rst-class:: ts-api-section

set
---

.. js:method:: OperatorStack.set( operator, position)

   :param operator: None
   :type operator: Operator
   :param position: None
   :type position: number


   Sets an operator to the 0 based index position on the stack.
   If there is already an operator in that position, it is replaced.
   If the operator is already on the stack, it is moved to the requested position.


   :rtype: boolean

.. rst-class:: ts-api-section

size
----

.. js:method:: OperatorStack.size()



   Returns the operator stack size


   :rtype: number

