00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00041 #include <string>
00042
00043 #include "omicron/internal.h"
00044 #include "omicron/render.h"
00045 #include "omicron/gui.h"
00046 #include "omicron/image.h"
00047
00048
00049 uiedit_c::uiedit_c()
00050 {
00051 classname = "edit";
00052
00053 selstart =
00054 selend = 0;
00055 hilite = false;
00056 mousedown = false;
00057 cursorpos = 0;
00058 left = 0;
00059
00060 styleflags = UI_BORDER_SUNKEN|UI_TRANSPARENT;
00061
00062 bgcolor = gv.gui->get_color(UIC_WINDOW);
00063
00064 fnt = gv.gui->get_font(UIF_FONT8);
00065 }
00066
00067 uiedit_c::~uiedit_c()
00068 {
00069 AssertThis;
00070
00071 }
00072
00073 void uiedit_c::paint()
00074 {
00075 AssertThis;
00076
00077 color_t c = disabled ? gv.gui->get_color(UIC_DISABLED) :
00078 gv.gui->get_color(UIC_TEXT);
00079 std::string str(text);
00080
00081
00082 ushort selx1, selx2;
00083 sshort cursorx;
00084 ushort sstart, send;
00085
00086 sstart = selstart;
00087 send = selend;
00088 if (sstart>send)
00089 {
00090 ushort tmp = sstart;
00091 sstart = send; send = tmp;
00092 }
00093
00094 if ((signed)sstart<0) sstart = 0;
00095 if (send>str.length()) send = (ushort)str.length();
00096
00097 cursorx = gv.renderer->get_string_pixelwidth(str.substr(0, cursorpos).c_str(), fnt);
00098
00099 if (cursorx>=width)
00100 left = cursorx-width+1;
00101 else if (cursorx<left)
00102 left = cursorx;
00103
00104 selx1 = gv.renderer->get_string_pixelwidth(str.substr(0,sstart).c_str(), fnt);
00105 selx2 = gv.renderer->get_string_pixelwidth(str.substr(sstart,send-sstart).c_str(), fnt);
00106
00107 img->filled_rectangle(0, 0, width, height, gv.gui->get_color(UIC_EDIT));
00108 img->filled_rectangle(selx1-left, 0, selx2-left, height, gv.gui->get_color(UIC_SELECTION));
00109
00110 if (this == gv.gui->get_focus())
00111 img->vline(cursorx+1-left, 0+1, height-1, gv.gui->get_color(UIC_BLACK));
00112
00113 img->draw_string(1-left+2, 1+2, str.c_str(), fnt, c);
00114
00115 uiobject_c::paint();
00116 }
00117
00118 ushort uiedit_c::find_pos_for_point(ushort x)
00119 {
00120 AssertThisV;
00121
00122 ushort pos = 0;
00123 ushort xx = 0;
00124 char *buf = new char[strlen(text)+2];
00125 char oc;
00126
00127 memset(buf, 0, strlen(text)+2);
00128 strcpy(buf, text);
00129
00130 while(xx<x && pos<=strlen(buf)+1)
00131 {
00132 oc = buf[pos];
00133 buf[pos] = 0;
00134 xx = gv.renderer->get_string_pixelwidth(buf, fnt);
00135 buf[pos] = oc;
00136
00137 pos++;
00138 }
00139
00140 SafeArrayDelete(buf);
00141 return pos-2;
00142 }
00143
00144 void uiedit_c::event(uievent_s *eve)
00145 {
00146 AssertThis;
00147
00148 AssertReturn1(eve);
00149
00150 switch(eve->event)
00151 {
00152 case UIE_MOUSEOVER:
00153 hilite = true;
00154 set_needs_refresh();
00155 break;
00156
00157 case UIE_MOUSEOUT:
00158 hilite = false;
00159 set_needs_refresh();
00160 break;
00161
00162 case UIE_GETFOCUS:
00163 case UIE_LOSTFOCUS:
00164 set_needs_refresh();
00165 break;
00166
00167 case UIE_MOUSEDOWN:
00168 cursorpos = selend = selstart = find_pos_for_point((sshort)eve->x);
00169 mousedown = true;
00170 set_needs_refresh();
00171 break;
00172
00173 case UIE_MOUSEUP:
00174 mousedown = false;
00175 set_needs_refresh();
00176 break;
00177
00178 case UIE_MOUSEMOVE:
00179 if (mousedown)
00180 {
00181 cursorpos = selend = find_pos_for_point((sshort)eve->x);
00182 set_needs_refresh();
00183 }
00184 break;
00185
00186 case UIE_CHAR:
00187 {
00188 char tmp[16];
00189
00190 switch(eve->key)
00191 {
00192 case UI_KEY_BACKSPACE:
00193 if (selstart != selend)
00194 replace_selection("");
00195
00196 selstart--;
00197 replace_selection("");
00198 break;
00199
00200
00201 case UI_KEY_DELETE:
00202 if (selstart != selend)
00203 replace_selection("");
00204
00205 selend++;
00206 replace_selection("");
00207 break;
00208
00209 case UI_KEY_LEFT:
00210 cursorpos --;
00211
00212 if (eve->mod & UI_KEYFLAG_SHIFT)
00213 --selstart;
00214 else
00215 selend = --selstart;
00216
00217 break;
00218
00219 case UI_KEY_RIGHT:
00220 cursorpos = selend = --selstart;
00221 break;
00222
00223 default:
00224 sprintf(tmp, "%c", eve->key&0xFF);
00225 replace_selection(tmp);
00226 break;
00227 }
00228 }
00229 break;
00230 }
00231 }
00232
00233 void uiedit_c::replace_selection(char *txt)
00234 {
00235 AssertThis;
00236
00237 AssertReturn1(txt);
00238
00239 ushort buflen = strlen(text)+strlen(txt)+1;
00240 char *tmp = new char[buflen];
00241
00242 sshort sstart, send;
00243
00244 sstart = selstart;
00245 send = selend;
00246 if (sstart>send)
00247 {
00248 ushort tmp = sstart;
00249 sstart = send; send = tmp;
00250 }
00251
00252 if (sstart<0)
00253 sstart = 0;
00254
00255 if (send>(signed)strlen(text))
00256 send = strlen(text);
00257
00258 memset(tmp, 0, buflen);
00259
00260 memcpy(tmp, text, sstart);
00261 memcpy(tmp+sstart, txt, strlen(txt));
00262 memcpy(tmp+sstart+strlen(txt), text+send, send-sstart);
00263
00264 selstart = selend = cursorpos = sstart+strlen(txt);
00265
00266 set_text(tmp);
00267 SafeArrayDelete(tmp);
00268 }