Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* item_list.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 "item_list.h"
#include "font.h"
#include "input.h"
#include "utils.h"
#include "tokenizer.h"
#include <sstream>
using namespace std;
extern int mousex, mouseyy;
extern char BUFFER [];
extern int line_height;
item_list::item_list () {
cur = hov = -1;
nsel = 0;
sel_lis = 0; // selection
set_listener (this); // click
}
void item_list::calc () {
n = items.size ();
n_1 = n - 1;
nums.resize (n);
for (int i = 0; i < n; ++i) {
sprintf (BUFFER, " [%d]", i+1);
nums[i] = BUFFER;
}
}
void item_list::add (const string& item) {
items.push_back ( itemt (item) );
calc ();
}
void item_list::clear () {
cur = hov = -1;
nsel = 0;
items.clear ();
}
void item_list::remove (int i) {
nsel -= items[i].sel;
items.erase (items.begin () + i);
calc ();
}
void item_list::insert (int i, const string& t) {
if (n && i < n) {
items.insert (items.begin() + i, itemt(t));
calc ();
}
}
void item_list::set_pos (int x, int y) {
posx = x;
posy = y;
extents.left = extents.right = posx;
extents.top = extents.bottom = posy;
for (int i = 0; i < n; ++i) extents.right = max (extents.right, posx + get_char_width (items[i].name));
extents.bottom -= (n * line_height);
yt = extents.top - line_height;
extents.calc ();
}
void item_list::draw () {
int x = extents.left, y = yt, xp = 0;
for (int i = 0; i < n; ++i) {
if (items[i].sel) glColor3f (0, 1, 1);
else glColor3f (clr.r, clr.g, clr.b);
xp = draw_string (items[i].name, x, y);
draw_string (nums[i], xp, y);
y -= line_height;
}
}
void item_list::select (int w) {
for (int i = 0; i < n; ++i) items[i].sel = w;
nsel = n * w;
if (sel_lis) sel_lis->selected (*this, get_first ());
}
void item_list::invert_select () {
for (int i = 0; i < n; ++i) {
int& si = items[i].sel;
nsel -= si;
si = !si;
nsel += si;
}
if (sel_lis) sel_lis->selected (*this, get_first ());
}
int item_list::select_these (tokenizer& tz) {
int m; tz >> m;
if (m) {
select (0);
for (int i = 0, j = 0; i < m; ++i) {
tz >> j;
items[j].sel = 1;
++nsel;
}
if (sel_lis) sel_lis->selected (*this, get_first ());
}
return m;
}
int item_list::handle_input () {
int r = button::handle_input ();
if (hover && n) {
hov = -1;
int m = (mouseyy - extents.bottom) / line_height;
if (m > -1 && m < n) hov = n_1 - m;
}
return r;
}
void item_list::clicked (button& b) {
if (hov != -1) {
cur = hov;
int& si = items[cur].sel;
if (SHIFT) {
if (!si) ++nsel;
si = 1;
} else if (CTRL) {
if (si) {
si = 0;
--nsel;
} else {
si = 1;
++nsel;
}
} else {
select (0);
si = 1;
nsel = 1;
}
if (sel_lis) sel_lis->selected (*this, cur);
}
}
string item_list::get_selected () {
std::stringstream ss;
for (int i = 0; i < n; ++i) if (items[i].sel) ss << i << spc;
return ss.str ();
}
int item_list::get_first () {
for (int i = 0; i < n; ++i) if (items[i].sel) return i;
return -1;
}