Improve positioning in ListBoxes
[centerim5.git] / cppconsui / FreeWindow.cpp
blobd3699963a859b5d71d2ab76be7982b9f785326b3
1 /*
2 * Copyright (C) 2010-2013 by CenterIM developers
4 * This file is part of CenterIM.
6 * CenterIM is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * CenterIM is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 /**
22 * @file
23 * FreeWindow class implementation.
25 * @ingroup cppconsui
28 #include "FreeWindow.h"
30 #include "CoreManager.h"
32 #include <algorithm>
34 namespace CppConsUI
37 FreeWindow::FreeWindow(int x, int y, int w, int h, Type t)
38 : Container(w, h), win_x(x), win_y(y), win_w(w), win_h(h), copy_x(0)
39 , copy_y(0), copy_w(0), copy_h(0), realwindow(NULL), type(t), closable(true)
41 COREMANAGER->signal_resize.connect(sigc::mem_fun(this,
42 &FreeWindow::onScreenResizedInternal));
43 COREMANAGER->signal_resize.connect(sigc::mem_fun(this,
44 &FreeWindow::onScreenResized));
46 declareBindables();
49 FreeWindow::~FreeWindow()
51 hide();
53 delete realwindow;
56 void FreeWindow::moveResize(int newx, int newy, int neww, int newh)
58 if (newx == win_x && newy == win_y && neww == win_w && newh == win_h)
59 return;
61 win_x = newx;
62 win_y = newy;
63 win_w = neww;
64 win_h = newh;
66 updateArea();
69 void FreeWindow::updateArea()
71 int maxx = Curses::getmaxx();
72 int maxy = Curses::getmaxy();
74 // update virtual area
75 delete area;
76 int realw = win_w;
77 if (realw == AUTOSIZE) {
78 realw = getWishWidth();
79 if (realw == AUTOSIZE)
80 realw = maxx - win_x;
82 int realh = win_h;
83 if (realh == AUTOSIZE) {
84 realh = getWishHeight();
85 if (realh == AUTOSIZE)
86 realh = maxy - win_y;
88 area = Curses::Window::newpad(realw, realh);
90 // inform the container about the new area
91 updateContainer(realw, realh);
93 // update real area
94 int left = std::max(0, win_x);
95 int top = std::max(0, win_y);
96 int right = std::min(win_x + realw, maxx);
97 int bottom = std::min(win_y + realh, maxy);
99 copy_x = left - win_x;
100 copy_y = top - win_y;
101 copy_w = right - left - 1;
102 copy_h = bottom - top - 1;
104 delete realwindow;
105 // this could fail if the window falls outside the visible area
106 realwindow = Curses::Window::newwin(left, top, right - left, bottom - top);
109 void FreeWindow::draw()
111 if (!area || !realwindow)
112 return;
114 area->erase();
116 Container::draw();
118 /* Reverse the top right corner of the window if there isn't any focused
119 * widget and the window is the top window. This way the user knows which
120 * window is on the top and can be closed using the Esc key. */
121 if (!input_child && COREMANAGER->getTopWindow() == this)
122 area->mvchgat(win_w - 1, 0, 1, Curses::Attr::REVERSE, 0, NULL);
124 // copy the virtual window to a window, then display it on screen
125 area->copyto(realwindow, copy_x, copy_y, 0, 0, copy_w, copy_h, 0);
127 // update virtual ncurses screen
128 realwindow->touch();
129 realwindow->noutrefresh();
132 void FreeWindow::setVisibility(bool visible)
134 visible ? show() : hide();
137 Point FreeWindow::getAbsolutePosition()
139 return Point(win_x, win_y);
142 void FreeWindow::setWishSize(int neww, int newh)
144 if (neww == wish_width && newh == wish_height)
145 return;
147 Container::setWishSize(neww, newh);
148 updateArea();
151 bool FreeWindow::isWidgetVisible(const Widget& /*child*/) const
153 return true;
156 bool FreeWindow::setFocusChild(Widget& child)
158 cleanFocus();
160 focus_child = &child;
161 setInputChild(child);
163 if (COREMANAGER->getTopWindow() != this)
164 return false;
166 return true;
169 void FreeWindow::show()
171 COREMANAGER->addWindow(*this);
172 visible = true;
173 signal_show(*this);
176 void FreeWindow::hide()
178 if (!COREMANAGER->hasWindow(*this))
179 return;
181 COREMANAGER->removeWindow(*this);
182 visible = false;
183 signal_hide(*this);
186 void FreeWindow::close()
188 signal_close(*this);
189 delete this;
192 void FreeWindow::setClosable(bool new_closable)
194 closable = new_closable;
197 void FreeWindow::redraw()
199 COREMANAGER->redraw();
202 void FreeWindow::updateContainer(int realw, int realh)
204 Container::moveResize(0, 0, std::max(0, realw), std::max(0, realh));
205 Container::updateArea();
208 void FreeWindow::onScreenResizedInternal()
210 updateArea();
213 void FreeWindow::actionClose()
215 if (closable)
216 close();
219 void FreeWindow::declareBindables()
221 declareBindable("window", "close-window",
222 sigc::mem_fun(this, &FreeWindow::actionClose),
223 InputProcessor::BINDABLE_NORMAL);
226 } // namespace CppConsUI
228 /* vim: set tabstop=2 shiftwidth=2 textwidth=78 expandtab : */