And putting my money where my mouth is... This example could probably be improved but it covers the basic idea. I looked around for something already made, but didn't see a simple version which could handle both implicit value assignment (auto-incrementing values) and explicit values, never mind a mix of the two. The assignment syntax is not as clean as I'd like (with the strings/objects), but it's flexible, so whatever.

For use in QML, put this in an external file:

lib.js:
-----------------
function Enum()
{
  this.exists = function(value) {
    return (typeof this[value] !== "undefined");
  };

  let lastValue = 0,
    i;
  for (i in arguments) {
    let arg = arguments[i],
      name, value;

    if (typeof arg === "object") {
      name = Object.keys(arg)[0];
      value = Object.values(arg)[0];
    }
    else if (typeof arg === "string") {
      name = arg;
      value = lastValue;
    }
    else {
      continue;
    }

    if (this.exists(name))
      throw "Duplicate enum name: " + name;

    this[this[name] = value] = name;
    lastValue = value + 1;
  }

  Object.freeze(this);  // don't allow modification
}
-------------------


Test.qml:
------------
import QtQuick 2.9
import "lib.js" as Lib

Item {
  // ... other properties, etc

  readonly property var positions: new Lib.Enum(
    'Unspecified',   // automatic value, = 0
    {BackFace : 5},  // explicit value
    'FrontFace'      // auto next value, = 6
  );

  function test() {
    console.log(positions.BackFace, positions[positions.BackFace]);
    // qml: 5 BackFace

    console.log(positions.FrontFace, positions[positions.FrontFace],
                positions.exists(positions.FrontFace));
    // qml: 6 FrontFace true

    // can't change the value, though strangely(?) no error/warning
    // even with readonly property
    positions["BackFace"] = 25;
    console.log(positions.BackFace);  // qml: 5

    var face = positions.FrontFace;
    switch(face) {
      case positions.BackFace:
        console.log("The back");
        break;
      case positions.FrontFace:
        console.log("The front");
        break;
      case positions.Unspecified:
        console.log("Not specified");
        break;
    }
    // qml: The front
  }

  Component.onCompleted: test();
}
-------------


JavaScript demo:
https://plnkr.co/edit/p9BM4o2SPtvGB3ZC?open=lib%2Fscript.js&preview
(there's a console view which can be opened on the lower right)

Cheers,
-Max



On 3/20/2020 4:56 AM, Max Paperno wrote:

On 3/20/2020 4:44 AM, Max Paperno wrote:

Obviously one could come up with a little helper function/object which makes this prettier. And you could make it auto-assign incremental values if one isn't provided in the "constructor" (like a C enum does)

Err, sorry, I meant a helper object which also provides reverse mapping from symbol to name.

Something like

var Enum;
(function (Enum) {
     Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));

var a = Enum.A;
var nameOfA = Enum[a]; // "A"

See:
https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings

Also their enum type implementation in general seems nice.

-Max

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to