219 lines
4.3 KiB
C++
219 lines
4.3 KiB
C++
/*
|
|
Copyright (C) 2016 Paul Davis
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include <cairomm/context.h>
|
|
#include <cairomm/surface.h>
|
|
#include <pangomm/layout.h>
|
|
|
|
#include "push2.h"
|
|
#include "gui.h"
|
|
|
|
using namespace ARDOUR;
|
|
using namespace std;
|
|
using namespace PBD;
|
|
using namespace Glib;
|
|
using namespace ArdourSurface;
|
|
|
|
#include "pbd/i18n.h"
|
|
#include "menu.h"
|
|
|
|
Push2Menu::Push2Menu (Cairo::RefPtr<Cairo::Context> context)
|
|
: _dirty (true)
|
|
{
|
|
Pango::FontDescription fd2 ("Sans 10");
|
|
|
|
{
|
|
Glib::RefPtr<Pango::Layout> throwaway = Pango::Layout::create (context);
|
|
throwaway->set_font_description (fd2);
|
|
throwaway->set_text (X_("Hg")); /* ascender + descender) */
|
|
int h, w;
|
|
throwaway->get_pixel_size (w, h);
|
|
baseline = h;
|
|
nrows = Push2::rows / baseline;
|
|
}
|
|
|
|
for (int n = 0; n < 8; ++n) {
|
|
columns[n].layout = Pango::Layout::create (context);
|
|
columns[n].layout->set_font_description (fd2);
|
|
columns[n].top = -1;
|
|
columns[n].active = -1;
|
|
}
|
|
}
|
|
|
|
void
|
|
Push2Menu::fill_column (int col, vector<string> v)
|
|
{
|
|
if (col < 0 || col > 7) {
|
|
return;
|
|
}
|
|
|
|
columns[col].text = v;
|
|
|
|
if (v.empty()) {
|
|
columns[col].active = -1;
|
|
} else {
|
|
columns[col].active = 0;
|
|
}
|
|
|
|
set_text (col, 0);
|
|
|
|
_dirty = true;
|
|
}
|
|
|
|
void
|
|
Push2Menu::set_text (int col, int top_row)
|
|
{
|
|
if (top_row > (int) columns[col].text.size() - nrows || top_row < 0) {
|
|
return;
|
|
}
|
|
|
|
if (top_row == columns[col].top) {
|
|
return;
|
|
}
|
|
|
|
vector<string>::iterator s = columns[col].text.begin();
|
|
s += top_row;
|
|
|
|
string rows;
|
|
|
|
while (true) {
|
|
rows += *s;
|
|
++s;
|
|
if (s != columns[col].text.end()) {
|
|
rows += '\n';
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
columns[col].layout->set_text (rows);
|
|
columns[col].top = top_row;
|
|
|
|
_dirty = true;
|
|
}
|
|
|
|
void
|
|
Push2Menu::scroll (int col, int dir)
|
|
{
|
|
if (dir > 0) {
|
|
set_text (col, columns[col].top + 1);
|
|
} else {
|
|
set_text (col, columns[col].top - 1);
|
|
}
|
|
}
|
|
|
|
void
|
|
Push2Menu::set_active (int col, int index)
|
|
{
|
|
if (col < 0 || col > 7) {
|
|
return;
|
|
}
|
|
|
|
if (index < 0 || index > (int) columns[col].text.size()) {
|
|
return;
|
|
}
|
|
|
|
columns[col].active = index;
|
|
|
|
ActiveChanged (); /* emit signal */
|
|
|
|
_dirty = true;
|
|
}
|
|
|
|
void
|
|
Push2Menu::step_active (int col, int dir)
|
|
{
|
|
if (col < 0 || col > 7) {
|
|
return;
|
|
}
|
|
|
|
if (columns[col].text.empty()) {
|
|
return;
|
|
}
|
|
|
|
|
|
if (dir < 0) {
|
|
if (columns[col].active == -1) {
|
|
columns[col].active = 0;
|
|
} else {
|
|
columns[col].active = columns[col].active - 1;
|
|
if (columns[col].active < 0) {
|
|
columns[col].active = columns[col].text.size() - 1;
|
|
}
|
|
}
|
|
} else {
|
|
if (columns[col].active == -1) {
|
|
columns[col].active = 0;
|
|
} else {
|
|
columns[col].active = columns[col].active + 1;
|
|
if (columns[col].active >= (int) columns[col].text.size()) {
|
|
columns[col].active = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (columns[col].active < nrows/2) {
|
|
set_text (col, 0);
|
|
} else {
|
|
set_text (col, columns[col].active - (nrows/2) + 1);
|
|
}
|
|
|
|
_dirty = true;
|
|
}
|
|
|
|
int
|
|
Push2Menu::get_active (int col)
|
|
{
|
|
if (col < 0 || col > 7) {
|
|
return -1;
|
|
}
|
|
|
|
return columns[col].active;
|
|
}
|
|
|
|
void
|
|
Push2Menu::redraw (Cairo::RefPtr<Cairo::Context> context, bool force) const
|
|
{
|
|
for (int n = 0; n < 8; ++n) {
|
|
|
|
/* Active: move to column/now, draw background indicator
|
|
for active row.
|
|
*/
|
|
|
|
const double x = 10.0 + (n * 120.0);
|
|
const double y = 2.0;
|
|
|
|
if (columns[n].active >= 0) {
|
|
int effective_row = columns[n].active - columns[n].top;
|
|
context->rectangle (x, y + (effective_row * baseline), 120.0, baseline);
|
|
context->set_source_rgb (1.0, 1.0, 1.0);
|
|
context->fill ();
|
|
}
|
|
|
|
/* now draw all the text, in one go */
|
|
|
|
context->move_to (x, y);
|
|
context->set_source_rgb (0.23, 0.0, 0.349);
|
|
columns[n].layout->update_from_cairo_context (context);
|
|
columns[n].layout->show_in_cairo_context (context);
|
|
|
|
}
|
|
|
|
_dirty = false;
|
|
}
|