Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CEGUIListHeader.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIListHeader.cpp
00003         created:        13/4/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implementation of ListHeader widget base class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "elements/CEGUIListHeader.h"
00027 #include "CEGUIExceptions.h"
00028 
00029 #include <sstream>
00030 
00031 
00032 // Start of CEGUI namespace section
00033 namespace CEGUI
00034 {
00035 const String ListHeader::EventNamespace("ListHeader");
00036 
00037 /*************************************************************************
00038         Properties for this class
00039 *************************************************************************/
00040 ListHeaderProperties::SortSettingEnabled        ListHeader::d_sortSettingProperty;
00041 ListHeaderProperties::ColumnsSizable            ListHeader::d_sizableProperty;
00042 ListHeaderProperties::ColumnsMovable            ListHeader::d_movableProperty;
00043 ListHeaderProperties::SortColumnID                      ListHeader::d_sortColumnIDProperty;
00044 ListHeaderProperties::SortDirection                     ListHeader::d_sortDirectionProperty;
00045 
00046 
00047 /*************************************************************************
00048         Constants
00049 *************************************************************************/
00050 // Event names
00051 const String ListHeader::EventSortColumnChanged( (utf8*)"SortColumnChanged" );
00052 const String ListHeader::EventSortDirectionChanged( (utf8*)"SortDirectionChanged" );
00053 const String ListHeader::EventSegmentSized( (utf8*)"SegmentSized" );
00054 const String ListHeader::EventSegmentClicked( (utf8*)"SegmentClicked" );
00055 const String ListHeader::EventSplitterDoubleClicked( (utf8*)"SplitterDoubleClicked" );
00056 const String ListHeader::EventSegmentSequenceChanged( (utf8*)"SegmentSequenceChanged" );
00057 const String ListHeader::EventSegmentAdded( (utf8*)"SegmentAdded" );
00058 const String ListHeader::EventSegmentRemoved( (utf8*)"SegmentRemoved" );
00059 const String ListHeader::EventSortSettingChanged( (utf8*)"SortSettingChanged" );
00060 const String ListHeader::EventDragMoveSettingChanged( (utf8*)"DragMoveSettingChanged" );
00061 const String ListHeader::EventDragSizeSettingChanged( (utf8*)"DragSizeSettingChanged" );
00062 const String ListHeader::EventSegmentRenderOffsetChanged( (utf8*)"SegmentOffsetChanged" );
00063 
00064 // values
00065 const float     ListHeader::ScrollSpeed = 8.0f;
00066 const float     ListHeader::MinimumSegmentPixelWidth    = 20.0f;
00067 
00068 
00069 /*************************************************************************
00070         Constructor for the list header base class.
00071 *************************************************************************/
00072 ListHeader::ListHeader(const String& type, const String& name) :
00073         Window(type, name),
00074         d_sortSegment(NULL),
00075         d_sizingEnabled(true),
00076         d_sortingEnabled(true),
00077         d_movingEnabled(true),
00078         d_uniqueIDNumber(0),
00079         d_segmentOffset(0.0f),
00080         d_sortDir(ListHeaderSegment::None)
00081 {
00082         addListHeaderEvents();
00083         addHeaderProperties();
00084 }
00085 
00086 
00087 /*************************************************************************
00088         Destructor for the list header base class.
00089 *************************************************************************/
00090 ListHeader::~ListHeader(void)
00091 {
00092 }
00093 
00094 
00095 /*************************************************************************
00096         Return the current number of segments in the header.
00097 *************************************************************************/
00098 uint ListHeader::getColumnCount(void) const
00099 {
00100         return (uint)d_segments.size();
00101 }
00102 
00103 
00104 /*************************************************************************
00105         Given a zero based column index, return the ListHeaderSegment.
00106 *************************************************************************/
00107 ListHeaderSegment& ListHeader::getSegmentFromColumn(uint column) const
00108 {
00109         if (column >= getColumnCount())
00110         {
00111                 throw InvalidRequestException((utf8*)"ListHeader::getSegmentFromColumn - requested column index is out of range for this ListHeader.");
00112         }
00113         else
00114         {
00115                 return *d_segments[column];
00116         }
00117 
00118 }
00119 
00120 
00121 /*************************************************************************
00122         Return the ListHeaderSegment with the requested ID.
00123 *************************************************************************/
00124 ListHeaderSegment& ListHeader::getSegmentFromID(uint id) const
00125 {
00126         for (uint i = 0; i < getColumnCount(); ++i)
00127         {
00128                 if (d_segments[i]->getID() == id)
00129                 {
00130                         return *d_segments[i];
00131                 }
00132 
00133         }
00134 
00135         // No such segment found, throw exception
00136         throw InvalidRequestException((utf8*)"ListHeader::getSegmentFromID - no segment with the requested ID is attached to this ListHeader.");
00137 }
00138 
00139 
00140 /*************************************************************************
00141         Return the sort-key segment.
00142 *************************************************************************/
00143 ListHeaderSegment& ListHeader::getSortSegment(void) const
00144 {
00145         if (d_sortSegment == NULL)
00146         {
00147                 throw   InvalidRequestException((utf8*)"ListHeader::getSortSegment - Sort segment was NULL!  (No segments are attached to the ListHeader?)");
00148         }
00149         else
00150         {
00151                 return *d_sortSegment;
00152         }
00153 
00154 }
00155 
00156 
00157 /*************************************************************************
00158         Given a segment, return it's zero based column index.
00159 *************************************************************************/
00160 uint ListHeader::getColumnFromSegment(const ListHeaderSegment& segment) const
00161 {
00162         for (uint i = 0; i < getColumnCount(); ++i)
00163         {
00164                 if (d_segments[i] == &segment)
00165                 {
00166                         return i;
00167                 }
00168 
00169         }
00170 
00171         // No such segment found, throw exception
00172         throw InvalidRequestException((utf8*)"ListHeader::getColumnFromSegment - the given ListHeaderSegment is not attached to this ListHeader.");
00173 }
00174 
00175 
00176 /*************************************************************************
00177         Return the column index that has a segment with the requested ID.
00178 *************************************************************************/
00179 uint ListHeader::getColumnFromID(uint id) const
00180 {
00181         for (uint i = 0; i < getColumnCount(); ++i)
00182         {
00183                 if (d_segments[i]->getID() == id)
00184                 {
00185                         return i;
00186                 }
00187 
00188         }
00189 
00190         // No such segment found, throw exception
00191         throw InvalidRequestException((utf8*)"ListHeader::getColumnFromID - no column with the requested ID is available on this ListHeader.");
00192 }
00193 
00194 
00195 /*************************************************************************
00196         Return the current sort-key column
00197 *************************************************************************/
00198 uint ListHeader::getSortColumn(void) const
00199 {
00200         return getColumnFromSegment(getSortSegment());
00201 }
00202 
00203 
00204 /*************************************************************************
00205         return the zero based column index of the segment with the requested
00206         text.
00207 *************************************************************************/
00208 uint ListHeader::getColumnWithText(const String& text) const
00209 {
00210         for (uint i = 0; i < getColumnCount(); ++i)
00211         {
00212                 if (d_segments[i]->getText() == text)
00213                 {
00214                         return i;
00215                 }
00216 
00217         }
00218 
00219         // No such segment found, throw exception
00220         throw InvalidRequestException((utf8*)"ListHeader::getColumnWithText - no column with the text '" + text + "' is attached to this ListHeader.");
00221 }
00222 
00223 
00224 /*************************************************************************
00225         return the pixel offset to the given segment
00226 *************************************************************************/
00227 float ListHeader::getPixelOffsetToSegment(const ListHeaderSegment& segment) const
00228 {
00229         float offset = 0.0f;
00230 
00231         for (uint i = 0; i < getColumnCount(); ++i)
00232         {
00233                 if (d_segments[i] == &segment)
00234                 {
00235                         return offset;
00236                 }
00237 
00238                 offset += d_segments[i]->getAbsoluteWidth();
00239         }
00240 
00241         // No such segment found, throw exception
00242         throw InvalidRequestException((utf8*)"ListHeader::getPixelOffsetToSegment - the given ListHeaderSegment is not attached to this ListHeader.");
00243 }
00244 
00245 
00246 /*************************************************************************
00247         return the pixel offset to the segment with the given column index
00248 *************************************************************************/
00249 float ListHeader::getPixelOffsetToColumn(uint column) const
00250 {
00251         if (column >= getColumnCount())
00252         {
00253                 throw InvalidRequestException((utf8*)"ListHeader::getPixelOffsetToColumn - requested column index is out of range for this ListHeader.");
00254         }
00255         else
00256         {
00257                 float offset = 0.0f;
00258 
00259                 for (uint i = 0; i < column; ++i)
00260                 {
00261                         offset += d_segments[i]->getAbsoluteWidth();
00262                 }
00263 
00264                 return offset;
00265         }
00266 
00267 }
00268 
00269 
00270 /*************************************************************************
00271         Return the total pixel width of all segments
00272 *************************************************************************/
00273 float ListHeader::getTotalSegmentsPixelExtent(void) const
00274 {
00275         float extent = 0.0f;
00276 
00277         for (uint i = 0; i < getColumnCount(); ++i)
00278         {
00279                 extent += d_segments[i]->getAbsoluteWidth();
00280         }
00281 
00282         return extent;
00283 }
00284 
00285 
00286 /*************************************************************************
00287         Return the pixel width of the segment at the specified column index.
00288 *************************************************************************/
00289 float ListHeader::getColumnPixelWidth(uint column) const
00290 {
00291         if (column >= getColumnCount())
00292         {
00293                 throw InvalidRequestException((utf8*)"ListHeader::getColumnPixelWidth - requested column index is out of range for this ListHeader.");
00294         }
00295         else
00296         {
00297                 return d_segments[column]->getAbsoluteWidth();
00298         }
00299 
00300 }
00301 
00302 
00303 /*************************************************************************
00304         return the current sort direction
00305 *************************************************************************/
00306 ListHeaderSegment::SortDirection ListHeader::getSortDirection(void) const
00307 {
00308         return d_sortDir;
00309 }
00310 
00311 
00312 /*************************************************************************
00313         Return whether sorting is enabled for this header.
00314 *************************************************************************/
00315 bool ListHeader::isSortingEnabled(void) const
00316 {
00317         return d_sortingEnabled;
00318 }
00319 
00320 
00321 /*************************************************************************
00322         Return whether segment sizing is enabled for this header
00323 *************************************************************************/
00324 bool ListHeader::isColumnSizingEnabled(void) const
00325 {
00326         return d_sizingEnabled;
00327 }
00328 
00329 
00330 /*************************************************************************
00331         Return whether segment dragging is enabled for this header.
00332 *************************************************************************/
00333 bool ListHeader::isColumnDraggingEnabled(void) const
00334 {
00335         return d_movingEnabled;
00336 }
00337 
00338 
00339 /*************************************************************************
00340         Set whether the ability to change sort segment / direction is enabled
00341 *************************************************************************/
00342 void ListHeader::setSortingEnabled(bool setting)
00343 {
00344         if (d_sortingEnabled != setting)
00345         {
00346                 d_sortingEnabled = setting;
00347 
00348                 // make the setting change for all component segments.
00349                 for (uint i = 0; i <getColumnCount(); ++i)
00350                 {
00351                         d_segments[i]->setClickable(d_sortingEnabled);
00352                 }
00353 
00354                 // Fire setting changed event.
00355                 WindowEventArgs args(this);
00356                 onSortSettingChanged(args);
00357         }
00358 
00359 }
00360 
00361 
00362 /*************************************************************************
00363         Set the sort direction on the current sort segment / column.
00364 *************************************************************************/
00365 void ListHeader::setSortDirection(ListHeaderSegment::SortDirection direction)
00366 {
00367         if (d_sortDir != direction)
00368         {
00369                 d_sortDir = direction;
00370 
00371                 // set direction of current sort segment
00372                 if (d_sortSegment != NULL)
00373                 {
00374                         d_sortSegment->setSortDirection(direction);
00375                 }
00376 
00377                 // Fire sort direction changed event.
00378                 WindowEventArgs args(this);
00379                 onSortDirectionChanged(args);
00380         }
00381 
00382 }
00383 
00384 
00385 /*************************************************************************
00386         Set the current sort segment.
00387 *************************************************************************/
00388 void ListHeader::setSortSegment(const ListHeaderSegment& segment)
00389 {
00390         setSortColumn(getColumnFromSegment(segment));
00391 }
00392 
00393 
00394 /*************************************************************************
00395         Set the current sort segment via column index.
00396 *************************************************************************/
00397 void ListHeader::setSortColumn(uint column)
00398 {
00399         if (column >= getColumnCount())
00400         {
00401                 throw InvalidRequestException((utf8*)"ListHeader::setSortColumn - specified column index is out of range for this ListHeader.");
00402         }
00403         else
00404         {
00405                 // if column is different to current sort segment
00406                 if (d_sortSegment != d_segments[column])
00407                 {
00408                         // set sort direction on 'old' sort segment to none.
00409                         if (d_sortSegment != NULL)
00410                         {
00411                                 d_sortSegment->setSortDirection(ListHeaderSegment::None);
00412                         }
00413 
00414                         // set-up new sort segment
00415                         d_sortSegment = d_segments[column];
00416                         d_sortSegment->setSortDirection(d_sortDir);
00417 
00418                         // Fire sort column changed event
00419                         WindowEventArgs args(this);
00420                         onSortColumnChanged(args);
00421                 }
00422 
00423         }
00424 
00425 }
00426 
00427 
00428 /*************************************************************************
00429         Set the current sort segment via ID code.
00430 *************************************************************************/
00431 void ListHeader::setSortColumnFromID(uint id)
00432 {
00433         setSortSegment(getSegmentFromID(id));
00434 }
00435 
00436 
00437 /*************************************************************************
00438         Set whether or not segments may be sized.
00439 *************************************************************************/
00440 void ListHeader::setColumnSizingEnabled(bool setting)
00441 {
00442         if (d_sizingEnabled != setting)
00443         {
00444                 d_sizingEnabled = setting;
00445 
00446                 // make the setting change for all component segments.
00447                 for (uint i = 0; i <getColumnCount(); ++i)
00448                 {
00449                         d_segments[i]->setSizingEnabled(d_sizingEnabled);
00450                 }
00451 
00452                 // Fire setting changed event.
00453                 WindowEventArgs args(this);
00454                 onDragSizeSettingChanged(args);
00455         }
00456 
00457 }
00458 
00459 
00460 /*************************************************************************
00461         Set whether columns may be dragged into new orders.
00462 *************************************************************************/
00463 void ListHeader::setColumnDraggingEnabled(bool setting)
00464 {
00465         if (d_movingEnabled != setting)
00466         {
00467                 d_movingEnabled = setting;
00468 
00469                 // make the setting change for all component segments.
00470                 for (uint i = 0; i <getColumnCount(); ++i)
00471                 {
00472                         d_segments[i]->setDragMovingEnabled(d_movingEnabled);
00473                 }
00474 
00475                 // Fire setting changed event.
00476                 WindowEventArgs args(this);
00477                 onDragMoveSettingChanged(args);
00478         }
00479 
00480 }
00481 
00482 
00483 /*************************************************************************
00484         Add a new column segment to the header.
00485 *************************************************************************/
00486 void ListHeader::addColumn(const String& text, uint id, float width)
00487 {
00488         // add just inserts at end.
00489         insertColumn(text, id, width, getColumnCount());
00490 }
00491 
00492 
00493 /*************************************************************************
00494         Insert a new column segment into the header
00495 *************************************************************************/
00496 void ListHeader::insertColumn(const String& text, uint id, float width, uint position)
00497 {
00498         // if position is too big, insert at end.
00499         if (position > getColumnCount())
00500         {
00501                 position = getColumnCount();
00502         }
00503 
00504         ListHeaderSegment* seg = createInitialisedSegment(text, id, width);
00505         d_segments.insert((d_segments.begin() + position), seg);
00506 
00507         // add window as a child of this
00508         addChildWindow(seg);
00509 
00510         layoutSegments();
00511 
00512         // Fire segment added event.
00513         WindowEventArgs args(this);
00514         onSegmentAdded(args);
00515 
00516         // if sort segment is invalid, make it valid now we have a segment attached
00517         if (d_sortSegment == NULL)
00518         {
00519                 setSortColumn(position);
00520         }
00521 }
00522 
00523 
00524 /*************************************************************************
00525         Remove a column from the header
00526 *************************************************************************/
00527 void ListHeader::removeColumn(uint column)
00528 {
00529         if (column >= getColumnCount())
00530         {
00531                 throw InvalidRequestException((utf8*)"ListHeader::removeColumn - specified column index is out of range for this ListHeader.");
00532         }
00533         else
00534         {
00535                 ListHeaderSegment* seg = d_segments[column];
00536 
00537                 // remove from the list of segments
00538                 d_segments.erase(d_segments.begin() + column);
00539 
00540                 // have we removed the sort column?
00541                 if (d_sortSegment == seg)
00542                 {
00543                         // any other columns?
00544                         if (getColumnCount() > 0)
00545                         {
00546                                 // put first column in as sort column
00547                                 d_sortDir = ListHeaderSegment::None;
00548                                 setSortColumn(0);
00549                         }
00550                         // no columns, set sort segment to NULL
00551                         else
00552                         {
00553                                 d_sortSegment = NULL;
00554                         }
00555 
00556                 }
00557 
00558                 // detach segment window from the header (this)
00559                 removeChildWindow(seg);
00560 
00561                 // destroy the segment (done in derived class, since that's where it was created).
00562                 destroyListSegment(seg);
00563 
00564                 layoutSegments();
00565 
00566                 // Fire segment removed event.
00567                 WindowEventArgs args(this);
00568                 onSegmentRemoved(args);
00569         }
00570 
00571 }
00572 
00573 
00574 /*************************************************************************
00575         Move a column segment to a new position
00576 *************************************************************************/
00577 void ListHeader::moveColumn(uint column, uint position)
00578 {
00579         if (column >= getColumnCount())
00580         {
00581                 throw InvalidRequestException((utf8*)"ListHeader::moveColumn - specified column index is out of range for this ListHeader.");
00582         }
00583         else
00584         {
00585                 // if position is too big, move to end.
00586                 if (position >= getColumnCount())
00587                 {
00588                         position = getColumnCount() - 1;
00589                 }
00590 
00591                 ListHeaderSegment* seg = d_segments[column];
00592 
00593                 // remove original copy of segment
00594                 d_segments.erase(d_segments.begin() + column);
00595 
00596                 // insert the segment at it's new position
00597                 d_segments.insert(d_segments.begin() + position, seg);
00598 
00599                 // Fire sequence changed event
00600                 HeaderSequenceEventArgs args(this, column, position);
00601                 onSegmentSequenceChanged(args);
00602 
00603                 layoutSegments();
00604         }
00605 
00606 }
00607 
00608 
00609 /*************************************************************************
00610         Insert a new column segment into the header
00611 *************************************************************************/
00612 void ListHeader::insertColumn(const String& text, uint id, float width, const ListHeaderSegment& position)
00613 {
00614         insertColumn(text, id, width, getColumnFromSegment(position));
00615 }
00616 
00617 
00618 /*************************************************************************
00619         Remove a segment from the header
00620 *************************************************************************/
00621 void ListHeader::removeSegment(const ListHeaderSegment& segment)
00622 {
00623         removeColumn(getColumnFromSegment(segment));
00624 }
00625 
00626 
00627 /*************************************************************************
00628         Move a column segment to a new position.
00629 *************************************************************************/
00630 void ListHeader::moveColumn(uint column, const ListHeaderSegment& position)
00631 {
00632         moveColumn(column, getColumnFromSegment(position));
00633 }
00634 
00635 
00636 /*************************************************************************
00637         Move a segment to a new position
00638 *************************************************************************/
00639 void ListHeader::moveSegment(const ListHeaderSegment& segment, uint position)
00640 {
00641         moveColumn(getColumnFromSegment(segment), position);
00642 }
00643 
00644 
00645 /*************************************************************************
00646         Move a segment to a new position
00647 *************************************************************************/
00648 void ListHeader::moveSegment(const ListHeaderSegment& segment, const ListHeaderSegment& position)
00649 {
00650         moveColumn(getColumnFromSegment(segment), getColumnFromSegment(position));
00651 }
00652 
00653 
00654 /*************************************************************************
00655         Set the current segment offset value (metrics dependant)
00656 *************************************************************************/
00657 void ListHeader::setSegmentOffset(float offset)
00658 {
00659         if (d_segmentOffset != offset)
00660         {
00661                 d_segmentOffset = offset;
00662                 layoutSegments();
00663                 requestRedraw();
00664         
00665                 // Fire event.
00666                 WindowEventArgs args(this);
00667                 onSegmentOffsetChanged(args);
00668         }
00669 
00670 }
00671 
00672 
00673 /*************************************************************************
00674         Set the pixel width of the specified column.    
00675 *************************************************************************/
00676 void ListHeader::setColumnPixelWidth(uint column, float width)
00677 {
00678         if (column >= getColumnCount())
00679         {
00680                 throw InvalidRequestException((utf8*)"ListHeader::setColumnPixelWidth - specified column index is out of range for this ListHeader.");
00681         }
00682         else
00683         {
00684                 d_segments[column]->setWidth(Absolute, width);
00685 
00686                 layoutSegments();
00687 
00688                 // Fire segment sized event.
00689                 WindowEventArgs args(d_segments[column]);
00690                 onSegmentSized(args);
00691         }
00692 
00693 }
00694 
00695 
00696 /*************************************************************************
00697         Create initialise and return a ListHeaderSegment object, with all
00698         events subscribed and ready to use.
00699 *************************************************************************/
00700 ListHeaderSegment* ListHeader::createInitialisedSegment(const String& text, uint id, float width)
00701 {
00702         // Build unique name
00703         std::stringstream name;
00704         name << getName().c_str() << "__auto_seg_" << d_uniqueIDNumber;
00705 
00706         // create segment.
00707         ListHeaderSegment* newseg = createNewSegment(name.str());
00708         d_uniqueIDNumber++;
00709 
00710         // setup segment;
00711         newseg->setMetricsMode(Relative);
00712         newseg->setSize(Size(width, 1.0f));
00713         newseg->setMinimumSize(absoluteToRelative_impl(NULL, Size(MinimumSegmentPixelWidth, 0.0f)));
00714         newseg->setText(text);
00715         newseg->setID(id);
00716 
00717         // subscribe events we listen to
00718         newseg->subscribeEvent(ListHeaderSegment::EventSegmentSized, Event::Subscriber(&CEGUI::ListHeader::segmentSizedHandler, this));
00719         newseg->subscribeEvent(ListHeaderSegment::EventSegmentDragStop, Event::Subscriber(&CEGUI::ListHeader::segmentMovedHandler, this));
00720         newseg->subscribeEvent(ListHeaderSegment::EventSegmentClicked, Event::Subscriber(&CEGUI::ListHeader::segmentClickedHandler, this));
00721         newseg->subscribeEvent(ListHeaderSegment::EventSplitterDoubleClicked, Event::Subscriber(&CEGUI::ListHeader::segmentDoubleClickHandler, this));
00722         newseg->subscribeEvent(ListHeaderSegment::EventSegmentDragPositionChanged, Event::Subscriber(&CEGUI::ListHeader::segmentDragHandler, this));
00723 
00724         return newseg;
00725 }
00726 
00727 
00728 /*************************************************************************
00729         Layout the segments
00730 *************************************************************************/
00731 void ListHeader::layoutSegments(void)
00732 {
00733         Point pos(-d_segmentOffset, 0.0f);
00734 
00735         for (uint i = 0; i < getColumnCount(); ++i)
00736         {
00737                 d_segments[i]->setPosition(pos);
00738                 pos.d_x += d_segments[i]->getWidth();
00739         }
00740 
00741 }
00742 
00743 
00744 /*************************************************************************
00745         Handler called when the sort column is changed.
00746 *************************************************************************/
00747 void ListHeader::onSortColumnChanged(WindowEventArgs& e)
00748 {
00749         fireEvent(EventSortColumnChanged, e, EventNamespace);
00750 }
00751 
00752 
00753 /*************************************************************************
00754         Handler called when the sort direction is changed.
00755 *************************************************************************/
00756 void ListHeader::onSortDirectionChanged(WindowEventArgs& e)
00757 {
00758         fireEvent(EventSortDirectionChanged, e, EventNamespace);
00759 }
00760 
00761 
00762 /*************************************************************************
00763         Handler called when a segment is sized by the user.
00764         e.window points to the segment.
00765 *************************************************************************/
00766 void ListHeader::onSegmentSized(WindowEventArgs& e)
00767 {
00768         fireEvent(EventSegmentSized, e, EventNamespace);
00769 }
00770 
00771 
00772 /*************************************************************************
00773         Handler called when a segment is clicked by the user.
00774         e.window points to the segment.
00775 *************************************************************************/
00776 void ListHeader::onSegmentClicked(WindowEventArgs& e)
00777 {
00778         fireEvent(EventSegmentClicked, e, EventNamespace);
00779 }
00780 
00781 
00782 /*************************************************************************
00783         Handler called when a segment splitter / sizer is double-clicked.
00784         e.window points to the segment.
00785 *************************************************************************/
00786 void ListHeader::onSplitterDoubleClicked(WindowEventArgs& e)
00787 {
00788         fireEvent(EventSplitterDoubleClicked, e, EventNamespace);
00789 }
00790 
00791 
00792 /*************************************************************************
00793         Handler called when the segment / column order changes.
00794 *************************************************************************/
00795 void ListHeader::onSegmentSequenceChanged(WindowEventArgs& e)
00796 {
00797         fireEvent(EventSegmentSequenceChanged, e, EventNamespace);
00798 }
00799 
00800 
00801 /*************************************************************************
00802         Handler called when a new segment is added to the header.
00803 *************************************************************************/
00804 void ListHeader::onSegmentAdded(WindowEventArgs& e)
00805 {
00806         fireEvent(EventSegmentAdded, e, EventNamespace);
00807 }
00808 
00809 
00810 /*************************************************************************
00811         Handler called when a segment is removed from the header.
00812 *************************************************************************/
00813 void ListHeader::onSegmentRemoved(WindowEventArgs& e)
00814 {
00815         fireEvent(EventSegmentRemoved, e, EventNamespace);
00816 }
00817 
00818 
00819 /*************************************************************************
00820         Handler called then setting that controls the users ability to
00821         modify the search column & direction changes.
00822 *************************************************************************/
00823 void ListHeader::onSortSettingChanged(WindowEventArgs& e)
00824 {
00825         fireEvent(EventSortSettingChanged, e, EventNamespace);
00826 }
00827 
00828 
00829 /*************************************************************************
00830         Handler called when the setting that controls the users ability to
00831         drag and drop segments changes.
00832 *************************************************************************/
00833 void ListHeader::onDragMoveSettingChanged(WindowEventArgs& e)
00834 {
00835         fireEvent(EventDragMoveSettingChanged, e, EventNamespace);
00836 }
00837 
00838 
00839 /*************************************************************************
00840         Handler called when the setting that controls the users ability t
00841         size segments changes.
00842 *************************************************************************/
00843 void ListHeader::onDragSizeSettingChanged(WindowEventArgs& e)
00844 {
00845         fireEvent(EventDragSizeSettingChanged, e, EventNamespace);
00846 }
00847 
00848 
00849 /*************************************************************************
00850         Handler called when the base rendering offset for the segments
00851         (scroll position) changes.
00852 *************************************************************************/
00853 void ListHeader::onSegmentOffsetChanged(WindowEventArgs& e)
00854 {
00855         fireEvent(EventSegmentRenderOffsetChanged, e, EventNamespace);
00856 }
00857 
00858 
00859 /*************************************************************************
00860         Handler method for when a segment is sized.
00861 *************************************************************************/
00862 bool ListHeader::segmentSizedHandler(const EventArgs& e)
00863 {
00864         layoutSegments();
00865 
00866         // Fire segment sized event.
00867         WindowEventArgs args(((WindowEventArgs&)e).window);
00868         onSegmentSized(args);
00869 
00870         return true;
00871 }
00872 
00873 
00874 /*************************************************************************
00875         Handler method for when a segment is dragged & dropped.
00876 *************************************************************************/
00877 bool ListHeader::segmentMovedHandler(const EventArgs& e)
00878 {
00879         Point mousePos(MouseCursor::getSingleton().getPosition());
00880 
00881         // segment must be dropped within the window
00882         if (isHit(mousePos))
00883         {
00884                 // get mouse position as something local
00885                 Point localMousePos(screenToWindow(mousePos));
00886 
00887                 // set up to allow for current offsets
00888                 float currwidth = -d_segmentOffset;
00889 
00890                 // get required figures as pixels
00891                 if (getMetricsMode() == Relative)
00892                 {
00893                         localMousePos = relativeToAbsolute(localMousePos);
00894                         currwidth = relativeToAbsoluteX(currwidth);
00895                 }
00896 
00897                 // calculate column where dragged segment was dropped
00898         uint col;
00899                 for (col = 0; col < getColumnCount(); ++col)
00900                 {
00901                         currwidth += d_segments[col]->getAbsoluteWidth();
00902 
00903                         if (localMousePos.d_x < currwidth)
00904                         {
00905                                 // this is the column, exit loop early
00906                                 break;
00907                         }
00908 
00909                 }
00910 
00911                 // find original column for dragged segment.
00912                 ListHeaderSegment* seg = ((ListHeaderSegment*)((WindowEventArgs&)e).window);
00913                 uint curcol = getColumnFromSegment(*seg);
00914 
00915                 // move column
00916                 moveColumn(curcol, col);
00917         }
00918 
00919         return true;
00920 }
00921 
00922 
00923 /*************************************************************************
00924         Hanlder for when a segment is clicked (to change sort segment / direction)
00925 *************************************************************************/
00926 bool ListHeader::segmentClickedHandler(const EventArgs& e)
00927 {
00928         // double-check we allow this action
00929         if (d_sortingEnabled)
00930         {
00931                 ListHeaderSegment* seg = ((ListHeaderSegment*)((WindowEventArgs&)e).window);
00932 
00933                 // is this a new sort column?
00934                 if (d_sortSegment != seg)
00935                 {
00936                         d_sortDir = ListHeaderSegment::Descending;
00937                         setSortSegment(*seg);
00938                 }
00939                 // not a new segment, toggle current direction
00940                 else if (d_sortSegment != NULL)
00941                 {
00942                         ListHeaderSegment::SortDirection currDir = d_sortSegment->getSortDirection();
00943 
00944                         // set new direction based on the current value.
00945                         switch (currDir)
00946                         {
00947                         case ListHeaderSegment::None:
00948                                 setSortDirection(ListHeaderSegment::Descending);
00949                                 break;
00950 
00951                         case ListHeaderSegment::Ascending:
00952                                 setSortDirection(ListHeaderSegment::Descending);
00953                                 break;
00954 
00955                         case ListHeaderSegment::Descending:
00956                                 setSortDirection(ListHeaderSegment::Ascending);
00957                                 break;
00958                         }
00959 
00960                 }
00961 
00962                 // Notify that a segment has been clicked
00963                 WindowEventArgs args(((WindowEventArgs&)e).window);
00964                 onSegmentClicked(args);
00965         }
00966 
00967         return true;
00968 }
00969 
00970 
00971 /*************************************************************************
00972         Handler called when a segment splitter is double-clicked.
00973 *************************************************************************/
00974 bool ListHeader::segmentDoubleClickHandler(const EventArgs& e)
00975 {
00976         WindowEventArgs args(((WindowEventArgs&)e).window);
00977         onSplitterDoubleClicked(args);
00978 
00979         return true;
00980 }
00981 
00982 
00983 /*************************************************************************
00984         Handler called whenever the mouse moves while dragging a segment
00985 *************************************************************************/
00986 bool ListHeader::segmentDragHandler(const EventArgs& e)
00987 {
00988         // what we do here is monitor the position and scroll if we can when mouse is outside area.
00989 
00990         // get mouse position as something local
00991         Point localMousePos(screenToWindow(MouseCursor::getSingleton().getPosition()));
00992 
00993         MetricsMode mmode = getMetricsMode();
00994 
00995         // get required figures as pixels
00996         if (mmode == Relative)
00997         {
00998                 localMousePos = relativeToAbsolute(localMousePos);
00999         }
01000 
01001         // scroll left?
01002         if (localMousePos.d_x < 0.0f)
01003         {
01004                 if (d_segmentOffset > 0.0f)
01005                 {
01006                         float adjust = ScrollSpeed;
01007                         
01008                         if (mmode == Relative)
01009                         {
01010                                 adjust = absoluteToRelativeX(adjust);
01011                         }
01012                         
01013                         setSegmentOffset(ceguimax(0.0f, d_segmentOffset - adjust));
01014                 }
01015 
01016         }
01017         // scroll right?
01018         else if (localMousePos.d_x >= getAbsoluteWidth())
01019         {
01020                 float adjust    = ScrollSpeed;
01021                 float pixOffset = d_segmentOffset;
01022                 float maxOffset = ceguimax(0.0f, getTotalSegmentsPixelExtent() - getAbsoluteWidth());
01023 
01024                 // convert values as required so calculations can be done in a consistent way
01025                 if (mmode == Relative)
01026                 {
01027                         maxOffset = absoluteToRelativeX(maxOffset);
01028                         pixOffset = relativeToAbsoluteX(pixOffset);
01029                         adjust = absoluteToRelativeX(adjust);
01030                 }
01031 
01032                 // if we have not scrolled to the limit
01033                 if (d_segmentOffset < maxOffset)
01034                 {
01035                         // scroll, but never beyond the limit
01036                         setSegmentOffset(ceguimin(maxOffset, d_segmentOffset + adjust));
01037                 }
01038 
01039         }
01040 
01041         return true;
01042 }
01043 
01044 
01045 /*************************************************************************
01046         Add ListHeader specific events  
01047 *************************************************************************/
01048 void ListHeader::addListHeaderEvents(void)
01049 {
01050         addEvent(EventSortColumnChanged);
01051         addEvent(EventSortDirectionChanged);
01052         addEvent(EventSegmentSized);
01053         addEvent(EventSegmentClicked);
01054         addEvent(EventSplitterDoubleClicked);
01055         addEvent(EventSegmentSequenceChanged);
01056         addEvent(EventSegmentAdded);
01057         addEvent(EventSegmentRemoved);
01058         addEvent(EventSortSettingChanged);
01059         addEvent(EventDragMoveSettingChanged);
01060         addEvent(EventDragSizeSettingChanged);
01061         addEvent(EventSegmentRenderOffsetChanged);
01062 }
01063 
01064 /*************************************************************************
01065         Add ListHeader specific properties
01066 *************************************************************************/
01067 void ListHeader::addHeaderProperties(void)
01068 {
01069         addProperty(&d_sizableProperty);
01070         addProperty(&d_movableProperty);
01071         addProperty(&d_sortSettingProperty);
01072         addProperty(&d_sortColumnIDProperty);
01073         addProperty(&d_sortDirectionProperty);
01074 }
01075 
01076 
01077 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:32 2005 for Crazy Eddies GUI System by  doxygen 1.4.3