00001 #ifndef OglGui_StringSelector_h
00002 #define OglGui_StringSelector_h
00003
00004 #include <algorithm>
00005 #include <string>
00006
00007 #ifndef OglGui_Window_h
00008 #include "OglGui/Window.h"
00009 #endif
00010
00011 #ifndef OglGui_StringListener_h
00012 #include "OglGui/StringListener.h"
00013 #endif
00014
00015 #ifndef OglGui_WindowScrollBar_h
00016 #include "OglGui/WindowScrollBar.h"
00017 #endif
00018
00019
00020
00021 namespace OglGui
00022 {
00023
00024 class StringSelector : public Window, ScrollBarListener
00025 {
00026 public:
00027
00028 StringSelector(Window* parent, int width, int height) :
00029 Window(parent, width, height)
00030 {
00031 Init(height/cLineHeight);
00032 }
00033
00034 StringSelector(Window* parent, int x, int y, int width, int height) :
00035 Window(parent, x, y, width, height)
00036 {
00037 Init(height/cLineHeight);
00038 }
00039
00040 void SetStringListener(StringListener* listener, void* listenerData = 0)
00041 {
00042 mStringListener = listener;
00043 mStrListenerData = listenerData;
00044 }
00045 void SetStringListener(StringListener* listener, int listenerData)
00046 {
00047 SetStringListener(listener, (void*) listenerData);
00048 }
00049
00050 ScrollBar* SBar()
00051 {
00052 return mScrollBar;
00053 }
00054
00055 int GetFirstVis() const
00056 {
00057 return mFirstVis;
00058 }
00059
00060 void SetFirstVis(int nr, bool signalScrollBar = false)
00061 {
00062 if (signalScrollBar)
00063 {
00064 mScrollBar->SetNewPos(nr);
00065
00066 }
00067 if (nr == mFirstVis)
00068 return;
00069 if (mNrVisible > mStrings.size())
00070 return;
00071 if ((nr < 0) || (nr > mStrings.size() - mNrVisible))
00072 return;
00073 mFirstVis = nr;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void MakeCurrentVisible()
00087 {
00088 bool lastLiner = mCurrent == mFirstVis + mNrVisible;
00089 int visIdx = lastLiner ? mCurrent-mNrVisible+1 : mCurrent;
00090 if ((mCurrent < mFirstVis) || (mCurrent > mFirstVis + mNrVisible-1))
00091 {
00092
00093
00094 mScrollBar->SetNewPos(visIdx);
00095 }
00096 }
00097
00098
00099 void AddString(strconst str, bool intelliScroll = false)
00100 {
00101 int pos = mStrings.size();
00102 mStrings.push_back(str);
00103 if (intelliScroll & (mFirstVis == pos - mNrVisible))
00104 {
00105 mCurrent = pos;
00106 SetFirstVis(mFirstVis + 1);
00107 }
00108 if (mScrollBar)
00109 mScrollBar->SetRange(mStrings.size(), mNrVisible);
00110 }
00111
00112
00113
00114 bool Contains(strconst str) const
00115 {
00116 if (std::find(mStrings.begin(), mStrings.end(), str) == mStrings.end())
00117 return false;
00118 return true;
00119 }
00120
00121 std::string GetString(int strInd) const
00122 {
00123 return mStrings[strInd];
00124 }
00125
00126 void SetCurrentString(int idx, bool makeVisible=false)
00127 {
00128 mCurrent = idx;
00129 if (makeVisible)
00130 MakeCurrentVisible();
00131 }
00132
00133 std::string GetCurrentString() const
00134 {
00135 return mStrings[mCurrent];
00136 }
00137
00138 int GetCurrentStringIdx() const
00139 {
00140 return mCurrent;
00141 }
00142
00143 void CurrentStringUpDown(bool down, bool makeVisible=false)
00144 {
00145 int nIdx = mCurrent + (down ? 1 : -1);
00146 if (nIdx<0 || nIdx>mStrings.size()-1)
00147 return;
00148 mCurrent = nIdx;
00149 if (makeVisible)
00150 MakeCurrentVisible();
00151 }
00152
00153 void RemoveStrings()
00154 {
00155 mStrings.clear();
00156 mCurrent = 0;
00157 mFirstVis = 0;
00158 if (mScrollBar)
00159 mScrollBar->SetRange(0, mNrVisible);
00160 }
00161
00162
00163
00164 virtual void DisplayFunc()
00165 {
00166 Window::DisplayFunc();
00167
00168 int lH = cLineHeight;
00169 int w = WndWidth();
00170 OGC oldOGC;
00171
00172 OGCSave(&oldOGC);
00173
00174
00175 int lastVis = mFirstVis + mNrVisible;
00176 if (lastVis > mStrings.size())
00177 lastVis = mStrings.size();
00178 for (int i=mFirstVis ; i<mStrings.size() ; i++)
00179 {
00180 int n = i - mFirstVis;
00181 int y = mOglWnd->height - (n+1) * lH;
00182 if (mDoTextShadow)
00183 oglSys.ShadowPrintf(mOglWnd, lH+2, y+6, mShadowColor,
00184 mTextColor, "%s", mStrings[i].c_str());
00185 else
00186 oglSys.PosColPrintf(mOglWnd, lH+2, y+6, mTextColor,
00187 "%s", mStrings[i].c_str());
00188 if (i == mCurrent)
00189 {
00190 int oldBlendInfo[3];
00191 oglSys.StartBlend(oldBlendInfo);
00192 SetSolidFillColor(mHighLightColor);
00193 FillRectangle(lH, y, w - lH, lH);
00194 oglSys.EndBlend(oldBlendInfo);
00195 if (mHighlightBorderType > 0)
00196 DrawBevRect(mHighlightBorderType, lH, y, w-lH, lH);
00197 else
00198 DrawBevRect(-mHighlightBorderType, lH+3, y+3, lH-6, lH-6);
00199 }
00200 }
00201 OGCRestore(&oldOGC);
00202 }
00203
00204
00205 virtual void ReshapeFunc(INT w, INT h)
00206 {
00207 mNrVisible = h / cLineHeight;
00208 mScrollBar->SetRange(mStrings.size(), mNrVisible);
00209 Window::ReshapeFunc(w, h);
00210 }
00211
00212 virtual int SetState(int nState)
00213 {
00214 mScrollBar->SetState(nState ? 1 : 0);
00215 return Window::SetState(nState);
00216 }
00217
00218 void ActivateListener()
00219 {
00220 if (!mStringListener)
00221 return;
00222 mStringListener->StringSelectionEvent(this,mCurrent,mStrListenerData);
00223 }
00224
00225 virtual void MouseFunc(int msg, int but, int state, int x, int y)
00226 {
00227 if (!GetState())
00228 return;
00229
00230 Window::MouseFunc(msg, but, state, x, y);
00231
00232 if (msg == oglMouseWheelUp)
00233 mScrollBar->ChangePos(-1);
00234 if (msg == oglMouseWheelDown)
00235 mScrollBar->ChangePos(1);
00236
00237 if ((msg==oglMouseDown) && (but==oglLeftButton))
00238 {
00239 int idx, clipY = (y < 0) ? 0 : y;
00240 if (clipY >= mOglWnd->height)
00241 clipY = mOglWnd->height;
00242 clipY = mOglWnd->height - clipY;
00243 if ((idx = clipY / cLineHeight + mFirstVis) < mStrings.size())
00244 {
00245 mCurrent = idx;
00246 ActivateListener();
00247 }
00248 }
00249 }
00250
00251 virtual void KeyboardFunc(int c, int state)
00252 {
00253 if (!GetState()) return;
00254
00255 Window::KeyboardFunc(c, state);
00256 if (state)
00257 return;
00258 if (c == '\r')
00259 return ActivateListener();
00260 if (c==oglUP || c==oglDOWN)
00261 CurrentStringUpDown(c==oglDOWN,true);
00262
00263 else if (mScrollBar)
00264 mScrollBar->ScrollKeys(c, state);
00265 }
00266
00267 void OnScroll(ScrollBar *src, int position, void* data)
00268 {
00269 SetFirstVis(position);
00270 }
00271
00272 private:
00273
00274 void Init(int nrVisible)
00275 {
00276 GuiGeneralName("StringSelector");
00277 mCurrent = 0;
00278 mNrVisible = nrVisible;
00279 mFirstVis = 0;
00280 mStringListener = 0;
00281
00282 mDoTextShadow = false;
00283 mShadowColor = oglWHITE;
00284 mTextColor = oglBLACK;
00285
00286 mHighLightColor = 0x4080ff80;
00287 mHighlightBorderType = BEV_ETCHED;
00288
00289 mOglWnd->borderType = BEV_ETCHED;
00290
00291 mScrollBar = new WindowScrollBar(this, false, false, 16);
00292 mScrollBar->SetScrollBarListener(this, 0);
00293 mScrollBar->SetRange(0, nrVisible);
00294
00295 mScrollBar->ScrollKeyHandling(false);
00296 mScrollBar->MapKeysTo(this);
00297
00298 SetDisableOGLViewKeys(true);
00299 SetDisableOGLViewMouse(true);
00300 }
00301
00302 static const int cLineHeight = 20;
00303 int mCurrent;
00304 int mNrVisible;
00305 int mFirstVis;
00306 bool mDoTextShadow;
00307 ULONG mTextColor;
00308 ULONG mShadowColor;
00309 ULONG mHighLightColor;
00310 int mHighlightBorderType;
00311
00312 StringListener* mStringListener;
00313 void* mStrListenerData;
00314 std::vector<std::string> mStrings;
00315
00316 WindowScrollBar* mScrollBar;
00317 };
00318
00319 }
00320 #endif