Rev 1338 |
Rev 1450 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* widget.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "widget.h"
#include "viewwin.h"
#include "tokenizer.h"
#include "input.h"
#include "basic_editor.h"
#include "container.h"
#include "file-utils.h"
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
extern int mousex, mouseyy;
extern int lmb, mmb, rmb;
extern viewport view;
widget::widget (int left, int bottom, int right, int top) : extents (left, bottom, right, top), clr (R, G, B), movr (*this) {
size = -1;
posx = posy = 0;
hover = 0;
enabled = 1;
visible = 1;
moveable = 0;
movlis = 0;
set_name_this ();
}
widget::~widget () {}
void widget::set_name (const std::string& _name) {
tokenizer tz (_name);
name = "";
while (1) {
string word;
tz >> word;
if (word == "") break;
name = name + '_' + word;
}
if (name == "") set_name_this ();
}
void widget::set_name_this () {
stringstream ss; ss << this; ss >> name;
}
int widget::handle_input () {
int movr_result = 0; if (moveable) movr_result = movr.handle_input ();
if (inbox (extents, mousex, mouseyy)) hover = 1; else hover = 0;
int widget_handled = hover | movr_result;
basic_editor::hide_cursor += widget_handled;
return widget_handled;
}
#ifdef __WIDGET_MOVE__
void widget::draw_guides () {
extern int line_height;
int y = guide.starty;
int dy = guide.mult * line_height;
glColor3f (0.5, 0.5, 1);
while (y > 0) {
glBegin (GL_LINES);
glVertex2f (0, y);
glVertex2f (view.xmax, y);
y -= dy;
glEnd ();
}
glColor3f (0.2, 0.2, 0.2);
const box<int>& e = extents;
bb[0]=e.left;bb[1]=view.ymax;
bb[2]=e.left;bb[3]=0;
bb[4]=e.right;bb[5]=view.ymax;
bb[6]=e.right;bb[7]=0;
bb[8]=0; bb[9]=e.bottom;
bb[10]=view.xmax; bb[11]=e.bottom;
bb[12]=0; bb[13]=e.top;
bb[14]=view.xmax; bb[15]=e.top;
glVertexPointer (2, GL_INT, 0, bb);
glDrawArrays (GL_LINES, 0, 8);
}
#endif
void widget::draw_bbox () {
const box<int>& e = extents;
bb[0]=e.left;bb[1]=e.bottom;
bb[2]=e.right;bb[3]=e.bottom;
bb[4]=e.right;bb[5]=e.top;
bb[6]=e.left;bb[7]=e.top;
glColor3f (clr.r, clr.g, clr.b);
glVertexPointer (2, GL_INT, 0, bb);
glDrawArrays (GL_LINE_LOOP, 0, 4);
}
void widget::fill_bbox () {
const box<int>& e = extents;
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (clr.r, clr.g, clr.b, 0.1f);
glRecti (e.left, e.bottom, e.right, e.top);
glDisable (GL_BLEND);
}
void widget::draw_and_fill_bbox () {
fill_bbox ();
draw_bbox ();
}
void widget::set_pos (int x, int y) {
posx = x;
posy = y;
set_extents (x, y, x + extents.width, y + extents.height);
}
void widget::set_extents (int l, int b, int r, int t) {
extents (l, b, r, t);
}
void widget::move (int dx, int dy, int mc) {
if (mc) {
// move children
size_vw n = children.size ();
if (n) for (size_vw i = 0; i < n; ++i) children[i]->move (dx, dy);
}
// new position
int x = posx + dx;
int y = posy + dy;
set_pos (x, y);
if (movlis) movlis->moved ();
}
void widget::show () {
visible = 1;
for (size_vw i = 0, j = children.size (); i < j; ++i) children[i]->show ();
}
void widget::hide (int what) {
if (what == all) visible = 0;
for (size_vw i = 0, j = children.size (); i < j; ++i) children[i]->hide ();
}
void widget::add_child (widget* w) {
children.push_back (w);
}
void widget::remove_child (widget* w) {
erase (children, w);
}
void widget::load (ifstream& file) {
string ignore;
file >> ignore >> posx >> posy;
set_pos (posx, posy);
}
void widget::save (ofstream& file) {
file << name << ' ' << posx << ' ' << posy << endl;
}
mover::mover (widget& _w, int* _pmb) : w (_w){
pmb = _pmb;
}
int mover::handle_input () {
int ret = 0;
int mb = *pmb;
if (mb) {
if (mb_clicked == 0) {
if (move) {
move = 0;
widget::focus = 0;
ret = 1;
} else if (w.hover) {
move = 1;
widget::focus = &w;
prevx = mousex;
prevy = mouseyy;
ret = 1;
}
mb_clicked = 1;
}
} else {
if (move) {
int dx = mousex - prevx, dy = mouseyy - prevy;
if (shift_down())
w.move (0, dy);
else if (ctrl_down ())
w.move (dx, 0);
else
w.move (dx, dy);
prevx = mousex; prevy = mouseyy;
ret = 1;
}
mb_clicked = 0;
}
return ret;
}
void widget::set_color (float r, float g, float b) {
clr.r = r;
clr.g = g;
clr.b = b;
}
void widget::set_color (unsigned char ur, unsigned char ug, unsigned char ub) {
float r, g, b; hex2rgb (ur, ug, ub, r, g, b); set_color (r, g, b);
}
void widget::enable () {
enabled = 1;
set_color (R, G, B);
}
void widget::disable () {
enabled = 0;
set_color (0.5f, 0.5f, 0.5f);
}
void widget::set_moveable (int m, int mc, int* pmb) {
moveable = m;
if (mc) {
size_vw n = children.size ();
if (n) for (size_vw i = 0; i < n; ++i) children[i]->set_moveable (m, mc, pmb);
}
movr.pmb = pmb;
}
void widget_load (const std::string& fname, std::vector<widget*>& vec) {
file_in fi (fname);
ifstream& f = fi();
for (int i = 0, j = vec.size (); i < j; ++i) vec[i]->load (f);
}
void widget_load (const string& fname, widget** pw, int n) {
file_in fi (fname);
ifstream& f = fi ();
for (int i = 0; i < n; ++i) pw[i]->load (f);
}
void widget_save (const std::string& fname, std::vector<widget*>& vec) {
file_out fo (fname);
ofstream& f = fo ();
for (int i = 0, j = vec.size (); i < j; ++i) vec[i]->save (f);
}
void widget_save (const string& fname, widget** pw, int n) {
file_out fo (fname);
ofstream& f = fo ();
for (int i = 0; i < n; ++i) pw[i]->save (f);
}
is_lmb_t::is_lmb_t () { tie = 0; }
int is_lmb_t::operator() (widget* w) {
if (tie == 0) return lmb;
else {
if (tie == w)
return lmb;
else
return 0;
}
}
void is_lmb_t::clear (widget* _tie) {
if (tie) {
if (_tie == 0 || tie == _tie)
tie = 0;
}
}
void set_focus (widget* w) {
if (widget::focus == 0)
widget::focus = w;
else if (widget::focus != w)
widget::next_focus = w;
}
void defocus () {
widget::focus = widget::next_focus;
widget::next_focus = 0;
}
void defocus (widget* w) {
if (widget::focus == w) {
widget::focus = widget::next_focus;
widget::next_focus = 0;
}
}
void make_hierarchy (widget** wa, int n) {
for (int i = 0, j = n - 1; i < j; ++i) {
widget* wi = wa[i], *wj = wa[i+1];
wi->add_child (wj);
wi = wj;
}
}
void make_family (widget* parent, widget** children, int n) {
for (int i = 0; i < n; ++i) parent->add_child (children[i]);
}