00001 #ifdef WIN32
00002 #pragma warning(disable : 4786 )
00003 #endif
00004
00005 #include "CSListbox.h"
00006 #include "CSIcon.h"
00007 #include "CSLAF.h"
00008 #include "CSDesktop.h"
00009 #include "CSMessage.h"
00010 #include "CSFont.h"
00011 #include "CSBorder.h"
00012
00013 const char *CSListbox::CLASS = "CSListbox";
00014
00015 CSListbox::CSListbox(int numberOfElementsDisplayed, int width) : CSGrafikElement(numberOfElementsDisplayed*16, width)
00016 {
00017 static char *functionName="CSListbox";
00018 LOG_ENTER
00019 mNumberOfElementsDisplayed = numberOfElementsDisplayed;
00020 initListbox();
00021 LOG_EXIT
00022 }
00023
00024 CSListbox::~CSListbox()
00025 {
00026 static char *functionName="~CSListbox";
00027 LOG_ENTER
00028 if (mScrollbar != 0)
00029 {
00030 removeElement(mScrollbar);
00031 delete(mScrollbar);
00032 mScrollbar = 0;
00033 }
00034 LOG_EXIT
00035 }
00036
00037 void CSListbox::initListbox()
00038 {
00039 static char *functionName="initListbox";
00040 LOG_ENTER
00041 MESSAGE_LIST_ITEM_SELECTED.setSubtype(LIST_ITEM_SELECTED_MESSAGE);
00042 setLayoutManager(new CSLayoutManagerStackHorizontal());
00043 mSelectedItem = -1;
00044 mStart = 0;
00045 mEnd = 0;
00046 mDisplayLength = 0;
00047 mScrollbar = 0;
00048 mHoverSelection = false;
00049 mSelectionBorder = 0;
00050
00051 rebuildElement();
00052 layoutSetup();
00053 LOG_EXIT
00054 }
00055
00056 void CSListbox::setItemsShown(int numberOfElementsDisplayed)
00057 {
00058 static char *functionName="setItemsShown";
00059 LOG_ENTER
00060 mNumberOfElementsDisplayed = numberOfElementsDisplayed;
00061 layoutChanged();
00062 LOG_EXIT
00063 }
00064
00065 void CSListbox::reactOnMessage(CSMessage *message)
00066 {
00067 reactOnMessageListbox(message);
00068 }
00069
00070 void CSListbox::reactOnMessageListbox(CSMessage *message)
00071 {
00072 static char *functionName="reactOnMessage";
00073 if (message->mIsHandled)
00074 {
00075 reactOnMessageGrafikElement(message);
00076 return;
00077 }
00078 switch (message->getType())
00079 {
00080 case GUI_MESSAGE:
00081 {
00082 GuiMessage *gm = (GuiMessage *) message;
00083 if (gm->receiver == this)
00084 {
00085 if (gm->getSubtype() == MOUSE_BUTTON_RELEASED_MESSAGE)
00086 {
00087 if (mHoverSelection)
00088 {
00089 MESSAGE_LIST_ITEM_SELECTED.selected = mSelectedItem;
00090 MESSAGE_LIST_ITEM_SELECTED.mIsHandled = false;
00091 sendMessage(MESSAGE_LIST_ITEM_SELECTED);
00092 }
00093 gm->mIsHandled = true;
00094 }
00095 }
00096 if (gm->receiver != this)
00097 {
00098 if (gm->getSubtype() == SCROLLBAR_POSITION_CHANGED_MESSAGE)
00099 {
00100 mStart = gm->start;
00101 mEnd = gm->end;
00102 gm->mIsHandled = true;
00103 }
00104 }
00105 else
00106 {
00107 switch (message->getSubtype())
00108 {
00109 case MOUSE_MOTION_MESSAGE:
00110 {
00111 if (mHoverSelection)
00112 {
00113 int x,y;
00114 x = gm->receiverX;
00115 y = gm->receiverY;
00116 setGrafikCursor(x,y);
00117 }
00118 gm->mIsHandled = true;
00119 break;
00120 }
00121
00122 case MOUSE_BUTTON_PRESSED_MESSAGE:
00123 {
00124 if (!mHoverSelection)
00125 {
00126 int x,y;
00127 x = gm->receiverX;
00128 y = gm->receiverY;
00129 setGrafikCursor(x,y);
00130 }
00131 gm->mIsHandled = true;
00132 break;
00133 }
00134 }
00135 }
00136 }
00137 }
00138 reactOnMessageGrafikElement(message);
00139 }
00140
00141
00142 void CSListbox::setGrafikCursor(int x, int y)
00143 {
00144 static char *functionName="setCursor";
00145
00146 int offsetX = getBorder()->getSizeWest() + mListInset.getSizeWest();
00147 int offsetY = getBorder()->getSizeNorth() + mListInset.getSizeNorth();
00148 int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00149 x -= offsetX;
00150 y -= offsetY;
00151 mSelectedItem = y/yAdd;
00152 mSelectedItem += mStart;
00153 if (!mHoverSelection)
00154 {
00155 MESSAGE_LIST_ITEM_SELECTED.selected = mSelectedItem;
00156 MESSAGE_LIST_ITEM_SELECTED.mIsHandled = false;
00157 sendMessage(MESSAGE_LIST_ITEM_SELECTED);
00158 }
00159 }
00160
00161 void CSListbox::paint(SDL_Surface *destination, SDL_Rect *parentViewport)
00162 {
00163 static char *functionName="paint";
00164 SDL_Rect rectSave;
00165 SDL_GetClipRect(destination, &rectSave);
00166
00167 SDL_Rect rectClip = getViewportArea();
00168 rectClip.x += parentViewport->x + getX();
00169 rectClip.y += parentViewport->y + getY();
00170
00171 SDLMain::adjustClipping(rectClip, rectSave);
00172
00173 SDL_SetClipRect(destination, &rectClip);
00174
00175 SDL_Rect viewArea = getViewportArea();
00176 SDL_Rect elementArea = getElementArea();
00177 SDL_Rect printArea = viewArea;
00178 printArea.x += parentViewport->x + elementArea.x;
00179 printArea.y += parentViewport->y + elementArea.y;
00180
00181 int x = mListInset.getSizeWest();
00182 int y = mListInset.getSizeNorth();
00183
00184 int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00185
00186 for (int i = mStart; ((i<mEnd) && (i<mItems.getSize())); i++)
00187 {
00188 if (mItems.getString(i).size())
00189 {
00190 std::string t = mItems.getString(i);
00191 putString(destination, &printArea, x, y, t);
00192
00193 if (i == mSelectedItem)
00194 {
00195 SDL_Rect selectedItemArea = printArea;
00196 selectedItemArea.x;
00197 selectedItemArea.y += y - mListInset.getSizeNorth();
00198
00199 selectedItemArea.h = getFont()->getHeight() + getVerticalElementSpacing();
00200 if (mScrollbar->getVisible())
00201 {
00202 selectedItemArea.w -= mScrollbar->getWidth();
00203 }
00204 mSelectionBorder->paint(destination, &selectedItemArea);
00205 mSelectionBorder->setState(BORDER_STATE_VISIBLE);
00206 }
00207 }
00208 y += yAdd;
00209 }
00210
00211 SDL_SetClipRect(destination, &rectSave);
00212 paintChildren(destination, parentViewport);
00213 }
00214
00215 void CSListbox::setSelected(int i)
00216 {
00217 mSelectedItem = i;
00218 }
00219
00220 void CSListbox::rebuildElement()
00221 {
00222 static char *functionName="rebuildElement";
00223 LOG_ENTER
00224 CSLAF *laf = CSLAF::getCurrentLAF();
00225 if (mSelectionBorder != 0)
00226 {
00227 delete mSelectionBorder;
00228 mSelectionBorder = 0;
00229 }
00230 mSelectionBorder = CSBorder::getBorder(BORDER_TYPE_SELECTED);
00231
00232 if (mScrollbar != 0)
00233 {
00234 mScrollbar->removeMessageListener(this);
00235 removeElement(mScrollbar);
00236 delete (mScrollbar);
00237 mScrollbar = 0;
00238 }
00239
00240 mScrollbar = new CSScrollbar(TYPE_VERTICAL);
00241 mScrollbar->addMessageListener(this, GUI_MESSAGE);
00242
00243 mScrollbar->setFocusable(getFocusable());
00244 addElement(mScrollbar, POSITION_EAST);
00245 LOG_EXIT
00246 }
00247
00248 void CSListbox::layoutSetupListbox()
00249 {
00250 static char *functionName="layoutSetupListbox";
00251 LOG_ENTER
00252 CSLAF *laf = CSLAF::getCurrentLAF();
00253 mListInset = CSInset(2);
00254
00255
00256
00257
00258 mHeight = mNumberOfElementsDisplayed * (getFont()->getHeight())
00259 + (mNumberOfElementsDisplayed-1) * (getVerticalElementSpacing())
00260 + getBorder()->getTotalHeight()
00261 + getInset().getTotalHeight()
00262 + mListInset.getTotalHeight();
00263 mMinHeight = mHeight - getBorder()->getTotalHeight() - getInset().getTotalHeight();
00264 mMinWidth = mWidth - getBorder()->getTotalWidth() - getInset().getTotalWidth();
00265
00266 int yAdd = getFont()->getHeight() + getVerticalElementSpacing();
00267
00268
00269
00270
00271
00272 mDisplayLength = (mMinHeight) / yAdd;
00273
00274
00275
00276 mEnd = mStart + mDisplayLength;
00277 mScrollbar->setDisplayStart(mStart);
00278 mScrollbar->setDisplayEnd(mEnd);
00279 mScrollbar->setDisplayLength(mDisplayLength);
00280 mScrollbar->setStart(0);
00281 mScrollbar->setEnd(mItems.getSize());
00282
00283 if (mDisplayLength < mItems.getSize())
00284 {
00285 mScrollbar->setVisible(true);
00286 }
00287 else
00288 {
00289 mScrollbar->setVisible(false);
00290 }
00291 LOG_EXIT
00292 }
00293