repo starts

This commit is contained in:
unknown
2008-08-04 22:20:45 +02:00
commit 6315a6c7ec
25 changed files with 5337 additions and 0 deletions

646
src/window.cpp Normal file
View File

@@ -0,0 +1,646 @@
/***************************************************************************
* Copyright (C) 2008 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* 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., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "window.h"
Window::Window(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : itsWindow(0), itsWinBorder(0), itsStartX(startx), itsStartY(starty), itsWidth(width), itsHeight(height), BBEnabled(1), itsTitle(title), itsColor(color), itsBaseColor(color), itsBgColor(clDefault), itsBaseBgColor(clDefault), itsBorder(border)
{
if (itsStartX < 0) itsStartX = 0;
if (itsStartY < 0) itsStartY = 0;
if (itsBorder != brNone)
{
itsWinBorder = newpad(itsHeight, itsWidth);
wattron(itsWinBorder,COLOR_PAIR(itsBorder));
box(itsWinBorder,0,0);
itsStartX++;
itsStartY++;
itsWidth -= 2;
itsHeight -= 2;
}
if (!itsTitle.empty())
{
itsStartY += 2;
itsHeight -= 2;
}
if (itsWidth > 0 && itsHeight > 0)
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
else
itsWindow = newwin(0, 0, 0, 0);
SetColor(itsColor);
}
Window::~Window()
{
delwin(itsWindow);
delwin(itsWinBorder);
}
void Window::SetColor(COLOR col, COLOR background)
{
if (col != clDefault)
wattron(itsWindow,COLOR_PAIR(background*8+col));
else
wattroff(itsWindow,COLOR_PAIR(itsColor));
itsColor = col;
itsBgColor = background;
}
void Window::SetBaseColor(COLOR col, COLOR background)
{
itsBaseColor = col;
itsBaseBgColor = background;
}
bool Window::have_to_recreate(BORDER border)
{
if (border == brNone && itsBorder != brNone)
{
delwin(itsWinBorder);
itsStartX--;
itsStartY--;
itsHeight += 2;
itsWidth += 2;
return true;
}
if (border != brNone && itsBorder == brNone)
{
itsWinBorder = newpad(itsHeight,itsWidth);
wattron(itsWinBorder,COLOR_PAIR(border));
box(itsWinBorder,0,0);
itsStartX++;
itsStartY++;
itsHeight -= 2;
itsWidth -= 2;
return true;
}
return false;
}
bool Window::have_to_recreate(string newtitle)
{
if (!newtitle.empty() && itsTitle.empty())
{
itsStartY += 2;
itsHeight -= 2;
return true;
}
if (newtitle.empty() && !itsTitle.empty())
{
itsStartY -= 2;
itsHeight += 2;
return true;
}
return false;
}
void Window::SetBorder(BORDER border)
{
if (have_to_recreate(border))
recreate_win();
itsBorder = border;
}
void Window::SetTitle(string newtitle)
{
if (itsTitle == newtitle)
return;
if (have_to_recreate(newtitle))
recreate_win();
itsTitle = newtitle;
}
void Window::recreate_win()
{
delwin(itsWindow);
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
SetColor(itsColor);
}
bool Window::reallocate_win(int newx, int newy)
{
if (newx < 0 || newy < 0 || (newx == itsStartX && newy == itsStartY)) return false;
itsStartX = newx;
itsStartY = newy;
if (itsBorder != brNone)
{
itsStartX++;
itsStartY++;
}
if (!itsTitle.empty())
itsStartY += 2;
return true;
}
void Window::MoveTo(int newx, int newy)
{
if (reallocate_win(newx, newy))
mvwin(itsWindow, itsStartY, itsStartX);
}
void Window::Resize(int width, int height)
{
if (itsBorder != brNone)
{
delwin(itsWinBorder);
itsWinBorder = newpad(height, width);
wattron(itsWinBorder,COLOR_PAIR(itsBorder));
box(itsWinBorder,0,0);
width -= 2;
height -= 2;
}
if (!itsTitle.empty())
width -= 2;
if (height > 0 && width > 0 && wresize(itsWindow, height, width) == OK)
{
itsHeight = height;
itsWidth = width;
}
}
void Window::show_border() const
{
if (itsBorder != brNone)
{
refresh();
prefresh(itsWinBorder,0,0,GetStartY(),GetStartX(),itsStartY+itsHeight,itsStartX+itsWidth);
}
if (!itsTitle.empty())
{
if (itsBorder != brNone)
{
attron(COLOR_PAIR(itsBorder));
mvhline(itsStartY-1, itsStartX, 0, itsWidth);
}
else
attron(COLOR_PAIR(itsBaseColor));
attron(A_BOLD);
mvaddstr(itsStartY-2, itsStartX, itsTitle.c_str());
attroff(COLOR_PAIR(itsBorder) | A_BOLD);
}
refresh();
}
void Window::Display()
{
show_border();
wrefresh(itsWindow);
}
void Window::Refresh()
{
wrefresh(itsWindow);
}
void Window::Clear()
{
for (int i = 0; i < GetHeight(); i++)
mvwhline(itsWindow, i, 0, 32, GetWidth());
wrefresh(itsWindow);
}
void Window::Hide(char x) const
{
for (int i = GetStartY(); i <= GetHeight()+1; i++)
mvhline(i, GetStartX(), x, GetWidth());
refresh();
}
void Window::Bold(bool bold) const
{
bold ? wattron(itsWindow, A_BOLD) : wattroff(itsWindow, A_BOLD);
}
void Window::Reverse(bool reverse) const
{
reverse ? wattron(itsWindow, A_REVERSE) : wattroff(itsWindow, A_REVERSE);
}
void Window::AltCharset(bool alt) const
{
alt ? wattron(itsWindow, A_ALTCHARSET) : wattroff(itsWindow, A_ALTCHARSET);
}
void Window::Delay(bool delay) const
{
nodelay(itsWindow, !delay);
}
void Window::Timeout(int timeout) const
{
wtimeout(itsWindow, timeout);
}
void Window::ReadKey(int &input) const
{
keypad(itsWindow, TRUE); input = wgetch(itsWindow); keypad(itsWindow, FALSE);
}
void Window::ReadKey() const
{
wgetch(itsWindow);
}
void Window::Write(const string &str, CLEAR_TO_EOL clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
string color, tmp;
for (string::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
waddstr(itsWindow,tmp.c_str());
tmp.clear();
if (is_valid_color(color))
{
const COLOR *colors = into_color(color);
SetColor(colors[0],colors[1]);
delete [] colors;
}
else
tmp += color;
color.clear();
}
}
if (!tmp.empty()) waddstr(itsWindow,tmp.c_str());
}
else
waddstr(itsWindow,str.c_str());
if (clrtoeol) wclrtoeol(itsWindow);
wrefresh(itsWindow);
}
#ifdef UTF8_ENABLED
void Window::Write(const wstring &str, CLEAR_TO_EOL clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
wstring color, tmp;
for (wstring::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
waddwstr(itsWindow,tmp.c_str());
tmp.clear();
if (is_valid_color(ToString(color.c_str())))
{
const COLOR *colors = into_color(ToString(color.c_str()));
SetColor(colors[0],colors[1]);
delete [] colors;
}
else
tmp += color;
color.clear();
}
}
if (!tmp.empty()) waddwstr(itsWindow,tmp.c_str());
}
else
waddwstr(itsWindow,str.c_str());
if (clrtoeol) wclrtoeol(itsWindow);
wrefresh(itsWindow);
}
void Window::WriteXY(int x, int y, const wstring &str, CLEAR_TO_EOL cleartoeol)
{
wmove(itsWindow,y,x);
Write(str, cleartoeol);
}
#endif
void Window::WriteXY(int x, int y, const string &str, CLEAR_TO_EOL cleartoeol)
{
wmove(itsWindow,y,x);
Write(str, cleartoeol);
}
string Window::GetString(const string &base, unsigned int length, void (*given_function)()) const
{
curs_set(1);
keypad(itsWindow,TRUE);
int input, minx, x, y, maxx;
wstring tmp;
getyx(itsWindow,y,x);
minx = maxx = x;
tmp = ToWString(base);
wmove(itsWindow,y,minx);
wprintw(itsWindow, "%ls",tmp.c_str());
maxx += tmp.length();
wrefresh(itsWindow);
string tmp_in;
wchar_t wc_in;
x = maxx;
do
{
if (given_function)
given_function();
wmove(itsWindow,y,x);
input = wgetch(itsWindow);
switch (input)
{
case ERR:
continue;
case KEY_UP:
case KEY_DOWN: break;
case KEY_RIGHT:
{
if (x < maxx)
x++;
break;
}
case KEY_BACKSPACE:
{
if (x <= minx) break;
}
case KEY_LEFT:
{
if (x > minx)
x--;
if (input != KEY_BACKSPACE) break; // backspace = left & delete.
}
case KEY_DC:
{
if ((maxx-x) < 1) break;
tmp.erase(tmp.end()-(maxx-x));
wmove(itsWindow,y,x); // for backspace
wdelch(itsWindow);
maxx--;
break;
}
case KEY_HOME:
{
x = minx;
break;
}
case KEY_END:
{
x = maxx;
break;
}
case 10: break;
default:
{
if (maxx-minx >= length)
break;
tmp_in += input;
if (mbtowc(&wc_in, tmp_in.c_str(), MB_CUR_MAX) < 0)
break;
if (maxx == x)
tmp.push_back(wc_in);
else
tmp.insert(tmp.end()-(maxx-x),wc_in);
winsstr(itsWindow, tmp_in.c_str());
tmp_in.clear();
x++;
maxx++;
}
}
}
while (input != 10);
keypad(itsWindow, FALSE);
curs_set(0);
return ToString(tmp);
}
void Window::Scrollable(bool scrollable) const
{
scrollok(itsWindow, scrollable);
idlok(itsWindow, scrollable);
}
void Window::GetXY(int &x, int &y) const
{
getyx(itsWindow, y, x);
}
void Window::GotoXY(int x, int y) const
{
wmove(itsWindow, y, x);
}
int Window::GetWidth() const
{
if (itsBorder != brNone)
return itsWidth+2;
else
return itsWidth;
}
int Window::GetHeight() const
{
int height = itsHeight;
if (itsBorder != brNone)
height += 2;
if (!itsTitle.empty())
height += 2;
return height;
}
int Window::GetStartX() const
{
if (itsBorder != brNone)
return itsStartX-1;
else
return itsStartX;
}
int Window::GetStartY() const
{
int starty = itsStartY;
if (itsBorder != brNone)
starty--;
if (!itsTitle.empty())
starty -= 2;
return starty;
}
string Window::GetTitle() const
{
return itsTitle;
}
COLOR Window::GetColor() const
{
return itsColor;
}
BORDER Window::GetBorder() const
{
return itsBorder;
}
void EnableColors()
{
if (has_colors())
{
start_color();
int num = 1;
if (use_default_colors() != ERR)
for (int i = -1; i < 8; i++)
for (int j = 0; j < 8; j++)
init_pair(num++, j, i);
else
for (int i = 1; i <= 8; i++)
init_pair(i, i, COLOR_BLACK);
}
}
char * ToString(const wchar_t *ws)
{
string s;
for (int i = 0; i < wcslen(ws); i++)
{
char *c = (char *)calloc(MB_CUR_MAX, sizeof(char));
wctomb(c, ws[i]);
s += c;
delete [] c;
}
return (char *)s.c_str();
}
string OmitBBCodes(const string &str)
{
if (str.empty())
return "";
bool collect = false;
string tmp, color, result;
for (string::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
result += tmp;
tmp.clear();
if (!is_valid_color(color))
tmp += color;
color.clear();
}
}
if (!tmp.empty()) result += tmp;
return result;
}
wchar_t * ToWString(const char *s)
{
wchar_t *ws = (wchar_t *)calloc(strlen(s)+1, sizeof(wchar_t));
mbstowcs(ws, s, strlen(s));
return ws;
}
string ToString(const wstring &ws)
{
string s;
for (wstring::const_iterator it = ws.begin(); it != ws.end(); it++)
{
char *c = (char *)calloc(MB_CUR_MAX, sizeof(char));
wctomb(c, *it);
s += c;
delete [] c;
}
return s;
}
wstring ToWString(const string &s)
{
wchar_t *ws = (wchar_t *)calloc(s.length()+1, sizeof(wchar_t));
mbstowcs(ws, s.c_str(), s.length());
wstring result = ws;
delete [] ws;
return result;
}