GUI
EditBox.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 by Maciej Wiecierzewski
3  */
4 
5 #include "EditBox.h"
6 
7 #include <iostream>
8 
9 #include "GUISystem.h"
10 #include "Renderer.h"
11 
12 using namespace gui;
13 
14 EditBox::EditBox(GUISystem *guiSystem, int x, int y, int w, int h) :
15  Widget(x, y, w, h),
16  backspaceCode(8),
17  vScrollbar(guiSystem->addScrollbar(w-15, 0, 15, h)),
18  hScrollbar(guiSystem->addScrollbar(0, h-15, w, 15)),
19  cursorPos(0),
20  cursorLine(0),
21  lines(0),
22  lineHeight(35),
23  multiline(false),
24  vScroll(false),
25  hScroll(false)
26 {
27  hScrollbar->setParent(this);
28  hScrollbar->setVisibility(false);
29 
30  vScrollbar->setParent(this);
31  vScrollbar->setVisibility(false);
32 }
33 
34 void EditBox::render(Renderer *renderer)
35 {
36  int x = xAbs, y = yAbs;
37  renderer->setTarget(x, y, w, h);
38 
39  lineHeight = renderer->getLineHeight();
40 
41  int cursorX, cursorY;
42  getCursorXY(renderer, cursorX, cursorY);
43 
44  int textPos = 0;
45  float textArea = (lines+1) * lineHeight;
46 
47  if(textArea > h)
48  textPos = vScrollbar->getSliderPosition() * (h - textArea);
49 
50  renderer->drawFilledRect(0, 0, w, h, backgroundColor);
51  renderer->drawRect(1, 1, w-1, h-1, frameColor, 2);
52  renderer->drawMultilineText(4, textPos, w, 35, text, textColor);
53 
54  if(focused)
55  {
56  renderer->drawLine(cursorX+4, textPos+cursorY+2, cursorX+4, textPos+cursorY+lineHeight, cursorColor, 1);
57  }
58 }
59 
60 void EditBox::keyChar(int unichar)
61 {
62  if(unichar <= 26)
63  return;
64 
65  char character = static_cast<char>(unichar);
66  std::string str;
67  str.push_back(character);
68 
69  text.insert(cursorPos, str);
70  cursorPos++;
71 
74  countLines();
75 }
76 
77 void EditBox::keyDown(int keyCode)
78 {
79  if(keyCode == KEY_BACKSPACE)
80  {
81  if(cursorPos > 0)
82  {
83  text.erase(--cursorPos, 1);
84  }
85  }
86  else if((keyCode == KEY_LEFT) && cursorPos > 0)
87  {
88  cursorPos--;
89  }
90  else if((keyCode == KEY_RIGHT) && cursorPos < text.length())
91  {
92  cursorPos++;
93  }
94  else if(keyCode == KEY_ENTER && multiline)
95  {
96  text.insert(cursorPos, "\n");
97  cursorPos++;
98  }
99 
100  findCursorLine();
101  countLines();
103 }
104 
106 {
107  multiline = true;
108 }
109 
110 void EditBox::setText(const std::string &text)
111 {
112  this->text = text;
113  countLines();
114 }
115 
116 std::string EditBox::getText()
117 {
118  return text;
119 }
120 
122 {
123  float textArea = (lines+1) * lineHeight;
124 
125  if(textArea > h)
126  {
127  if(!vScroll)
128  {
129  vScroll = true;
130  vScrollbar->setVisibility(true);
131  }
132 
133  float sliderLengh = h / textArea;
134  vScrollbar->setSliderLength(sliderLengh);
135  }
136  else if(vScroll)
137  {
138  vScroll = false;
139  vScrollbar->setVisibility(false);
140  }
141 }
142 
143 void EditBox::getCursorXY(Renderer *renderer, int& cursorX, int& cursorY)
144 {
145  if(cursorPos == 0)
146  {
147  cursorX = 0;
148  cursorY = 0;
149  return;
150  }
151 
152  int lineBegin;
153  for(lineBegin = cursorPos-1; lineBegin > 0 && text[lineBegin] != '\n'; lineBegin--) {}
154  if(text[lineBegin] == '\n')
155  lineBegin++;
156 
157  std::string line = text.substr(lineBegin, cursorPos - lineBegin);
158 
159  cursorX = renderer->getTextWidth(line);
160  cursorY = cursorLine * lineHeight;
161 }
162 
164 {
165  cursorLine = 0;
166 
167  for(int i = cursorPos-1; i > 0; i--)
168  {
169  if(text[i] == '\n')
170  cursorLine++;
171  }
172 }
173 
175 {
176  lines = 1;
177 
178  for(unsigned int i = 0; i < text.length(); i++)
179  {
180  if(text[i] == '\n')
181  lines++;
182  }
183 }