Subversion Repositories DIN Is Noise

Rev

Rev 2097 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* capturer.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#include "capturer.h"
#include "curve_editor.h"
#include "console.h"

using namespace std;

#define DECLARE_WIDGET_ARRAY_wa widget* wa [] = {&title, &all, &none, &invert, &play, &kill, &fold};
#define NUM_WIDGETS 7
#define NUM_WIDGETS_1 (NUM_WIDGETS - 1)

typedef std::vector<state_button*>::iterator caps_iter;

void capturer_t::setup (curve_editor* ce) {

  ed = ce;

  DECLARE_WIDGET_ARRAY_wa
  const char* texts [] = {"Captures", "All", "None", "Invert"};
  for (int i = 0; i < 4; ++i)  {
    label* l = dynamic_cast<label*>(wa[i]);
    l->set_text (texts[i]);
  }
  for (int i = 1; i < NUM_WIDGETS; ++i) dynamic_cast<button*>(wa[i])->set_listener (this);

  makefam (&title, &wa[1], NUM_WIDGETS_1);

  for (int i = 4; i < 6; ++i) {
    button* wi = dynamic_cast<button*>(wa [i]);
    wi->set_size (16);
  }

  title.set_moveable (1);
  title.movlis = this;

  fold.set_dir (arrow_button::right);
  play.set_dir (arrow_button::right);

  widget_load ("d_capturer", wa, NUM_WIDGETS);

  folded = 1;
  ncaps = 0;
  moved ();

}

capturer_t::capturer_t () {
  ++ref;
}

capturer_t::~capturer_t () {

  if (ncaps) {
    for (int i = 0; i < ncaps; ++i) {
      state_button* sb = caps[i];
      delete sb;
    }
  }

  if (--ref == 0) {
    DECLARE_WIDGET_ARRAY_wa
    widget_save ("d_capturer", wa, NUM_WIDGETS);
  }
}

int capturer_t::handle_input () {

  if (folded) {
    if (fold.handle_input()) return 1;
    else return title.handle_input ();
  } else {

    if (ncaps) {
      for (int i = 0; i < ncaps; ++i) {
        state_button* sb = caps[i];
        if (sb->handle_input()) return 1;
      }
    }

    DECLARE_WIDGET_ARRAY_wa
    for (int i = 0; i < NUM_WIDGETS; ++i) {
      widget* wi = wa[i];
      if (wi->handle_input()) return 1;
    }

  }

  return 0;

}

void capturer_t::set (mouse_macro& mm, int x, int y) {
  point<int>& p = sbpt [mm.sb];
  p.x = x; p.y = y;
}

void capturer_t::remove () {
  int p = ncaps;
  for (vector<state_button*>::iterator i = caps.begin (), j = caps.end(); i != j;) {
    state_button* sb = *i;
    if (sb->state) {
      ed->remove_mouse_capture (sb);
      title.remove_child (sb);
      delete sb;
      i = caps.erase (i);
      j = caps.end ();
      --ncaps;
    } else ++i;
  }
  rearrange ();
  cons << GREEN << "Removed " << (p - ncaps) << " mouse captures" << eol;
}

void capturer_t::rearrange () {
  int sx = title.extents.left;
  if (ncaps) {
    for (int i = 0; i < ncaps; ++i) {
      state_button* sb = caps[i];
      sb->set_pos (sx, sby);
      sx += state_button::SIZE2;
    }
  }
  sbx = sx;
}

void capturer_t::on_caps (const item_op& op) {
  if (ncaps) {
    for (int i = 0; i < ncaps; ++i) {
      state_button* sb = caps[i];
      sb->set_state (op (sb->state));
    }
  }
}

void capturer_t::clicked (button& b) {
  if (&b == &kill) {
    remove ();
  } else if (&b == &play) {
    ed->toggle_mouse_capture (caps);
  } else if (&b == &all) {
    on_caps (_sel);
  } else if (&b == &none) {
    on_caps (_desel);
  } else if (&b == &invert) {
    on_caps (_togg);
  } else if (&b == &fold) {
    if (fold.dir == arrow_button::down) {
      title.hide (widget::only_children);
      fold.show ();
      fold.set_dir (arrow_button::right);
      folded = 1;
    } else {
      title.show ();
      fold.set_dir (arrow_button::down);
      folded = 0;
    }
  }
}

void capturer_t::draw () {
  if (folded == 0) {
    DECLARE_WIDGET_ARRAY_wa
    for (int i = 0; i < NUM_WIDGETS; ++i) {
      widget* wi = wa[i];
      if (wi->visible) wi->draw ();
    }
    if (ncaps) {
      for (int i = 0; i < ncaps; ++i) {
        state_button* sb = caps[i];
        sb->draw ();
      }
    }
    glEnable (GL_LINE_STIPPLE);
    glLineStipple (1, 0xf00f);
    if (ncaps) {
      for (int i = 0; i < ncaps; ++i) {
        state_button* sb = caps[i];
        point<int>& p = sbpt [sb];
        glBegin (GL_LINES);
          glVertex2i (p.x, p.y);
          glVertex2i (sb->extents.midx, sb->extents.midy);
        glEnd ();
      }
    }
    glDisable (GL_LINE_STIPPLE);
  } else {
    fold.draw ();
    title.draw ();
  }
}

void capturer_t::moved () {
  sbx = title.extents.left + ncaps * state_button::SIZE2;
  sby = title.extents.bottom - title.extents.height;
}