<commit_before><!-- GNU LGPL v2.1+: http://www.gnu.org/licenses/lgpl.html -->

<docs>
  ## vc-part-thumb - Vue template to display a part thumbnail
  ### Props:
  - **part** - The BsePart to display.
  - **tick** - The BseTrack tick position.
</docs>

<template>

  <canvas ref="canvas" class="vc-part-thumb" @click="Shell.open_part_edit (part)"
	  :style="{ left: this.pxoffset + 'px', width: this.canvas_width + 'px', }" ></canvas>

</template>

<style lang="scss">
  @import 'mixins.scss';
  .vc-part-thumb {
    display: inline-block; position: absolute; top: 0px; bottom: 0px;
    height: $vc-track-list-row-height;
    border-radius: $vc-theme-border-radius;
    --part-thumb-font-color: $vc-part-thumb-font-color; --part-thumb-font: $vc-part-thumb-font;
    --part-thumb-note-color: $vc-part-thumb-note-color; --part-thumb-colors: $vc-part-thumb-colors;
  }
</style>

<script>
const Util = require ('./utilities.js');

const tick_quant = 384; // FIXME
module.exports = {
  name: 'vc-part-thumb',
  props: {
    'part': { type: Bse.Part, },
    'tick': { type: Number, },
    'index': { type: Number, },
    'track-index': { type: Number, },
  },
  computed: {
    tickscale: function() { return 10 / 384.0; }, // FIXME
    pxoffset: function() { return this.tick * 10 / 384.0; }, // FIXME
    canvas_width: function() {
      const part = this.part;
      let last_tick = part ? part.get_last_tick() : 0;
      return this.tickscale * Math.floor ((last_tick + tick_quant - 1) / tick_quant) * tick_quant;
    },
  },
  customized_render (createElement, result) { // FIXME
    // queue render_canvas into main loop so $el / canvas are updated
    clearTimeout (this.timer);
    const RENDER_ASYNC = true;
    if (RENDER_ASYNC)
      this.timer = setTimeout (() => render_canvas.call (this), 0);
    else
      Promise.resolve().then (() => render_canvas.call (this));
    return result;
  },
  beforeDestroy() {
    clearTimeout (this.timer);
  },
};

function render_canvas () {
  // canvas setup
  const canvas = this.$refs['canvas'], ctx = canvas.getContext ('2d');
  const style = getComputedStyle (canvas), part = this.part;
  const width = canvas.clientWidth, height = canvas.clientHeight;
  canvas.width = width; canvas.height = height;
  ctx.clearRect (0, 0, width, height);
  const part_name = part.get_name();
  // color setup
  const colors = Util.split_comma (style.getPropertyValue ('--part-thumb-colors'));
  let cindex;
  cindex = this.trackIndex;			// - color per track
  cindex = (cindex + 1013904223) * 1664557;	//   LCG randomization step
  cindex = this.index;				// - color per part
  cindex = Util.fnv1a_hash (part_name);		// - color from part name
  const bgcol = colors[(cindex >>> 0) % colors.length];
  // paint part background
  ctx.fillStyle = bgcol;
  ctx.fillRect (0, 0, width, height);<commit_msg>EBEAST: part-thumb: use mounted() and $watch to track rendering<commit_after><!-- GNU LGPL v2.1+: http://www.gnu.org/licenses/lgpl.html -->

<docs>
  ## vc-part-thumb - Vue template to display a part thumbnail
  ### Props:
  - **part** - The BsePart to display.
  - **tick** - The BseTrack tick position.
</docs>

<template>

  <canvas ref="canvas" class="vc-part-thumb" @click="Shell.open_part_edit (part)"
	  :style="{ left: this.pxoffset + 'px', width: this.canvas_width + 'px', }" ></canvas>

</template>

<style lang="scss">
  @import 'mixins.scss';
  .vc-part-thumb {
    display: inline-block; position: absolute; top: 0px; bottom: 0px;
    height: $vc-track-list-row-height;
    border-radius: $vc-theme-border-radius;
    --part-thumb-font-color: $vc-part-thumb-font-color; --part-thumb-font: $vc-part-thumb-font;
    --part-thumb-note-color: $vc-part-thumb-note-color; --part-thumb-colors: $vc-part-thumb-colors;
  }
</style>

<script>
const Util = require ('./utilities.js');

const tick_quant = 384; // FIXME
module.exports = {
  name: 'vc-part-thumb',
  props: {
    'part': { type: Bse.Part, },
    'tick': { type: Number, },
    'index': { type: Number, },
    'track-index': { type: Number, },
  },
  computed: {
    tickscale: function() { return 10 / 384.0; }, // FIXME
    pxoffset: function() { return this.tick * 10 / 384.0; }, // FIXME
    canvas_width: function() {
      const part = this.part;
      let last_tick = part ? part.get_last_tick() : 0;
      return this.tickscale * Math.floor ((last_tick + tick_quant - 1) / tick_quant) * tick_quant;
    },
  },
  methods: {
    render_canvas: render_canvas,
  },
  mounted() {
    /* DOM and $el is in place, now:
     * a) render into the canvas, we call render_canvas() for this;
     * b) re-render the canvases if anything changes, for this we install a watcher
     */
    if (!this.unwatch_render_canvas)
      this.unwatch_render_canvas = this.$watch (this.render_canvas, () => this.$forceUpdate());
    this.render_canvas();
  },
  beforeDestroy() {
    if (this.unwatch_render_canvas) {
      this.unwatch_render_canvas();
      this.unwatch_render_canvas = undefined;
    }
  },
};

function render_canvas () {
  // canvas setup
  const canvas = this.$refs['canvas'], ctx = canvas.getContext ('2d');
  const style = getComputedStyle (canvas), part = this.part;
  const width = canvas.clientWidth, height = canvas.clientHeight;
  canvas.width = width; canvas.height = height;
  ctx.clearRect (0, 0, width, height);
  const part_name = part.get_name();
  // color setup
  const colors = Util.split_comma (style.getPropertyValue ('--part-thumb-colors'));
  let cindex;
  cindex = this.trackIndex;			// - color per track
  cindex = (cindex + 1013904223) * 1664557;	//   LCG randomization step
  cindex = this.index;				// - color per part
  cindex = Util.fnv1a_hash (part_name);		// - color from part name
  const bgcol = colors[(cindex >>> 0) % colors.length];
  // paint part background
  ctx.fillStyle = bgcol;
  ctx.fillRect (0, 0, width, height);
{'fraction_non_alphanumeric': 0.16456343792633016, 'fraction_numerical': 0.015518417462482947, 'mean_word_length': 3.1478076379066477, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2816140', 'n_tokens_mistral': 2081, 'n_tokens_neox': 2019, 'n_words': 499}