  */
 
 #include <du-ino_function.h>
+#include <du-ino_widgets.h>
 #include <avr/pgmspace.h>
 
 #define ENV_PEAK              10.0 // V

    Display.draw_char(54, 56, '1', DUINO_SH1106::White);
    Display.draw_char(69, 56, '2', DUINO_SH1106::White);
    Display.draw_char(76, 56, 0x10, DUINO_SH1106::White);

    // draw sliders & labels
    for(uint8_t i = 0; i < 8; ++i)
    {
      Display.fill_rect(11 * (i % 4) + (i > 3 ? 85 : 1), 51 - v[i], 9, 3, DUINO_SH1106::White);
      Display.draw_char(11 * (i % 4) + (i > 3 ? 87 : 3), 56, label[i % 4], DUINO_SH1106::White);
    }

    Display.fill_rect(1, 55, 9, 9, DUINO_SH1106::Inverse);
    Display.fill_rect(53, 55, 7, 9, DUINO_SH1106::Inverse);

    Display.display_all();
  }


    }
  }

  void widget_save_click_callback()
  {
    if(!saved_)
    {
      save_params(0, v, 8);
      Display.fill_rect(widget_save_->x() + 2, widget_save_->y() + 2, 3, 3, DUINO_SH1106::Black);
      widget_save_->display();
    }
  }

  void widget_adsr_scroll_callback(uint8_t selected, int delta)
  {
    v[selected] += delta;
    if(v[selected] < 0)
    {
      v[selected] = 0;
    }
    if(v[selected] > V_MAX)
    {
      v[selected] = V_MAX;
    }
    if(v[selected] != v_last[selected])
    {
      // update slider
      Display.fill_rect(widgets_adsr_[selected]->x() - 1, 51 - v_last[selected], 9, 3, DUINO_SH1106::Black);
      Display.fill_rect(widgets_adsr_[selected]->x() - 1, 51 - v[selected], 9, 3, DUINO_SH1106::White);
      Display.display(widgets_adsr_[selected]->x() - 1, widgets_adsr_[selected]->x() + 7, 1, 6);

      // update ADSR value
      uint8_t e = selected > 3 ? 1 : 0;
      switch(selected % 4)
      {
        case 0:
          adsr_values[e].A = uint16_t(v[selected]) * 24;
          break;
        case 1:
          adsr_values[e].D = uint16_t(v[selected]) * 24;
          break;
        case 2:
          adsr_values[e].S = (float(v[selected]) / float(V_MAX)) * ENV_PEAK;
          break;
        case 3:
          adsr_values[e].R = uint16_t(v[selected]) * 24;
          break;
      }

      // update last encoder value
      v_last[selected] = v[selected];

      mark_save();
    }
  }

 private:
  void mark_save()
  {
    if(saved_)
    {
      saved_ = false;
      Display.fill_rect(widget_save_->x() + 2, widget_save_->y() + 2, 3, 3, DUINO_SH1106::Black);
      widget_save_->display();
    }
  }

  DU_ADSR_Values adsr_values[2];
  uint8_t env;
  unsigned long gate_time, release_time;
  float cv_current, cv_released;
  int8_t v[8], v_last[8];
  uint8_t last_selected_env;
  bool last_gate;

  DUINO_WidgetContainer<2> * container_outer_;
  DUINO_WidgetContainer<8> * container_adsr_;
  DUINO_DisplayWidget * widget_save_;
  DUINO_DisplayWidget * widgets_adsr_[8];
};

DU_ADSR_Function * function;
