move code responsible for screen resize to SIGWINCH handler
[ncmpcpp.git] / src / scrollpad.cpp
blob96d2c5799289e63b0ed0826844c80f55351b6902
1 /***************************************************************************
2 * Copyright (C) 2008-2009 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include <cassert>
23 #include "scrollpad.h"
25 using namespace NCurses;
27 Scrollpad::Scrollpad(size_t startx,
28 size_t starty,
29 size_t width,
30 size_t height,
31 const std::string &title,
32 Color color,
33 Border border)
34 : Window(startx, starty, width, height, title, color, border),
35 itsBeginning(0),
36 itsFoundForEach(0),
37 itsFoundValueBegin(-1),
38 itsFoundValueEnd(-1),
39 itsRealHeight(1)
43 Scrollpad::Scrollpad(const Scrollpad &s) : Window(s)
45 itsBuffer << s.itsBuffer;
46 itsBeginning = s.itsBeginning;
47 itsRealHeight = s.itsRealHeight;
50 void Scrollpad::Flush()
52 itsRealHeight = 1;
54 std::basic_string<my_char_t> s = itsBuffer.Str();
56 size_t x = 0;
57 int x_pos = 0;
58 int space_pos = 0;
60 for (size_t i = 0; i < s.length(); ++i)
62 x += s[i] != '\t' ? wcwidth(s[i]) : 8-x%8; // tab size
64 if (s[i] == ' ') // if space, remember its position;
66 space_pos = i;
67 x_pos = x;
70 if (x >= itsWidth)
72 // if line is over, there was at least one space in this line and we are in the middle of the word, restore position to last known space and make it EOL
73 if (space_pos > 0 && (s[i] != ' ' || s[i+1] != ' '))
75 i = space_pos;
76 x = x_pos;
77 s[i] = '\n';
81 if (x >= itsWidth || s[i] == '\n')
83 itsRealHeight++;
84 x = 0;
85 space_pos = 0;
88 itsRealHeight = std::max(itsHeight, itsRealHeight);
89 Recreate(itsWidth, itsRealHeight);
90 itsBuffer.SetTemp(&s);
91 static_cast<Window &>(*this) << itsBuffer;
92 itsBuffer.SetTemp(0);
95 bool Scrollpad::SetFormatting(short val_b, const std::basic_string<my_char_t> &s, short val_e, bool for_each)
97 bool result = itsBuffer.SetFormatting(val_b, s, val_e, for_each);
98 if (result)
100 itsFoundForEach = for_each;
101 itsFoundValueBegin = val_b;
102 itsFoundValueEnd = val_e;
103 itsFoundPattern = s;
105 else
106 ForgetFormatting();
107 return result;
110 void Scrollpad::ForgetFormatting()
112 itsFoundForEach = 0;
113 itsFoundValueBegin = -1;
114 itsFoundValueEnd = -1;
115 itsFoundPattern.clear();
118 void Scrollpad::RemoveFormatting()
120 if (itsFoundValueBegin >= 0 && itsFoundValueEnd >= 0)
121 itsBuffer.RemoveFormatting(itsFoundValueBegin, itsFoundPattern, itsFoundValueEnd, itsFoundForEach);
124 void Scrollpad::Refresh()
126 int MaxBeginning = itsRealHeight-itsHeight;
127 assert(MaxBeginning >= 0);
128 if (itsBeginning > MaxBeginning)
129 itsBeginning = MaxBeginning;
130 prefresh(itsWindow, itsBeginning, 0, itsStartY, itsStartX, itsStartY+itsHeight-1, itsStartX+itsWidth-1);
133 void Scrollpad::Resize(size_t new_width, size_t new_height)
135 AdjustDimensions(new_width, new_height);
136 Flush();
139 void Scrollpad::Scroll(Where where)
141 int MaxBeginning = /*itsContent.size() < itsHeight ? 0 : */itsRealHeight-itsHeight;
143 switch (where)
145 case wUp:
147 if (itsBeginning > 0)
148 itsBeginning--;
149 break;
151 case wDown:
153 if (itsBeginning < MaxBeginning)
154 itsBeginning++;
155 break;
157 case wPageUp:
159 itsBeginning -= itsHeight;
160 if (itsBeginning < 0)
161 itsBeginning = 0;
162 break;
164 case wPageDown:
166 itsBeginning += itsHeight;
167 if (itsBeginning > MaxBeginning)
168 itsBeginning = MaxBeginning;
169 break;
171 case wHome:
173 itsBeginning = 0;
174 break;
176 case wEnd:
178 itsBeginning = MaxBeginning;
179 break;
184 void Scrollpad::Clear(bool clear_screen)
186 itsRealHeight = itsHeight;
187 itsBuffer.Clear();
188 wclear(itsWindow);
189 delwin(itsWindow);
190 itsWindow = newpad(itsHeight, itsWidth);
191 SetTimeout(itsWindowTimeout);
192 SetColor(itsColor, itsBgColor);
193 ForgetFormatting();
194 keypad(itsWindow, 1);
195 if (clear_screen)
196 Refresh();
199 void Scrollpad::Reset()
201 itsBeginning = 0;
204 #ifdef _UTF8
205 Scrollpad &Scrollpad::operator<<(const std::string &s)
207 itsBuffer << ToWString(s);
208 return *this;
210 #endif // _UTF8