news download themes documentation links










Container.cc

00001 // Container.cc
00002 // Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
00003 //                and Simon Bowden    (rathnor at users.sourceforge.net)
00004 //
00005 // Permission is hereby granted, free of charge, to any person obtaining a
00006 // copy of this software and associated documentation files (the "Software"),
00007 // to deal in the Software without restriction, including without limitation
00008 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00009 // and/or sell copies of the Software, and to permit persons to whom the
00010 // Software is furnished to do so, subject to the following conditions:
00011 //
00012 // The above copyright notice and this permission notice shall be included in
00013 // all copies or substantial portions of the Software.
00014 //
00015 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00018 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00020 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00021 // DEALINGS IN THE SOFTWARE.
00022 
00023 // $Id: Container.cc,v 1.11 2004/01/13 14:41:32 rathnor Exp $
00024 
00025 #include "Container.hh"
00026 
00027 #include "FbTk/Button.hh"
00028 #include "FbTk/EventManager.hh"
00029 
00030 Container::Container(const FbTk::FbWindow &parent):
00031     FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), 
00032     m_align(RELATIVE),
00033     m_max_size_per_client(60),
00034     m_selected(0),
00035     m_update_lock(false) {
00036     FbTk::EventManager::instance()->add(*this, *this);
00037 }
00038 
00039 Container::~Container() {
00040 
00041 }
00042 
00043 void Container::resize(unsigned int width, unsigned int height) {
00044     // do we need to resize?
00045     if (FbTk::FbWindow::width() == width &&
00046         FbTk::FbWindow::height() == height)
00047         return;
00048 
00049     FbTk::FbWindow::resize(width, height);
00050     repositionItems();
00051 }
00052 
00053 void Container::moveResize(int x, int y,
00054                            unsigned int width, unsigned int height) {
00055     FbTk::FbWindow::moveResize(x, y, width, height);
00056     repositionItems();
00057 }
00058 
00059 void Container::insertItems(ItemList &item_list, int pos) {
00060 
00061     // make sure all items have parent == this
00062     ItemList::iterator it = m_item_list.begin();
00063     ItemList::iterator it_end = m_item_list.end();
00064     for (; it != it_end; ++it) {
00065         if ((*it)->parent() != this)
00066             return;
00067     }
00068 
00069     if (pos > size() || pos < 0) {
00070         // insert last
00071         m_item_list.splice(m_item_list.end(), item_list);
00072     } else if (pos == 0) {
00073         // insert first
00074         m_item_list.splice(m_item_list.begin(), item_list);
00075     } else {
00076         // find insert point
00077         for (it = m_item_list.begin(); pos != 0; ++it, --pos)
00078             continue;
00079         m_item_list.splice(it, item_list);
00080     }
00081 
00082     m_item_list.unique();
00083 
00084     // update position
00085     repositionItems();
00086 }
00087 
00088 void Container::insertItem(Item item, int pos) {
00089     if (find(item) != -1)
00090         return;
00091 
00092     // it must be a child of this window
00093     if (item->parent() != this)
00094         return;
00095 
00096     if (pos >= size() || pos < 0) {
00097         m_item_list.push_back(item);
00098     } else if (pos == 0) {
00099         m_item_list.push_front(item);
00100     } else {
00101         ItemList::iterator it = m_item_list.begin();
00102         for (; pos != 0; ++it, --pos)
00103             continue;
00104 
00105         m_item_list.insert(it, item);
00106     }
00107 
00108     // make sure we dont have duplicate items
00109     m_item_list.unique();
00110 
00111     repositionItems();
00112 }
00113 
00114 void Container::removeItem(int index) {    
00115     if (index < 0 || index > size())
00116         return;
00117 
00118     ItemList::iterator it = m_item_list.begin();
00119     for (; index != 0; ++it, --index)
00120         continue;
00121 
00122     if (*it == selected())
00123         m_selected = 0;
00124 
00125     m_item_list.erase(it);
00126 
00127     repositionItems();
00128 }
00129 
00130 void Container::removeAll() {
00131     m_selected = 0;
00132     m_item_list.clear();
00133     if (!m_update_lock) {
00134         clear();
00135         updateTransparent();
00136     }
00137 
00138 }
00139 
00140 int Container::find(Item item) {
00141     ItemList::iterator it = m_item_list.begin();
00142     ItemList::iterator it_end = m_item_list.end();
00143     int index = 0;
00144     for (; it != it_end; ++it, ++index) {
00145         if ((*it) == item)
00146             break;
00147     }
00148 
00149     if (it == it_end)
00150         return -1;
00151 
00152     return index;
00153 }
00154 
00155 void Container::setSelected(int pos) {
00156     if (pos < 0 || pos >= size())
00157         m_selected = 0;
00158     else {
00159         ItemList::iterator it = m_item_list.begin();
00160         for (; pos != 0; --pos, ++it)
00161             continue;
00162         m_selected = *it;
00163         if (m_selected) {
00164             m_selected->clear();
00165             m_selected->updateTransparent();
00166         }
00167     }
00168         
00169 }
00170 
00171 void Container::setMaxSizePerClient(unsigned int size) {
00172     m_max_size_per_client = size;
00173 }
00174 
00175 void Container::setAlignment(Container::Alignment a) {
00176     m_align = a;
00177 }
00178 
00179 void Container::exposeEvent(XExposeEvent &event) {
00180     if (!m_update_lock) {
00181         clearArea(event.x, event.y, event.width, event.height);
00182         updateTransparent(event.x, event.y, event.width, event.height);
00183     }
00184 }
00185 
00186 void Container::repositionItems() {
00187     if (size() == 0 || m_update_lock)
00188         return;
00189 
00191 
00192     const int max_width_per_client = maxWidthPerClient();
00193 
00194     ItemList::iterator it = m_item_list.begin();
00195     const ItemList::iterator it_end = m_item_list.end();
00196     int borderW = m_item_list.front()->borderWidth();
00197 
00198     int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);
00199 
00200     int next_x = -borderW; // zero so the border of the first shows
00201     int extra = 0;
00202     int direction = 1;
00203     if (alignment() == RIGHT) {
00204         direction = -1;
00205         next_x = width() - max_width_per_client + borderW;
00206     }
00207 
00208     for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
00209           if (rounding_error != 0) {
00210               --rounding_error;
00211               extra = 1;
00212           } else {
00213               extra = 0;
00214           }
00215         // resize each clients including border in size
00216         (*it)->moveResize(next_x,
00217                           -borderW,
00218                           max_width_per_client + extra,
00219                           height());
00220         (*it)->clear();
00221         (*it)->updateTransparent();
00222     }
00223 
00224 }
00225 
00226 
00227 unsigned int Container::maxWidthPerClient() const {
00228     switch (alignment()) {
00229     case RIGHT:
00230     case LEFT:
00231         return m_max_size_per_client;
00232         break;
00233     case RELATIVE:
00234         int count = size();
00235         if (count == 0)
00236             return width();
00237         else {
00238             int borderW = m_item_list.front()->borderWidth();
00239             // there're count-1 borders to fit in with the windows
00240             // -> 1 per window plus end
00241             return (width() - (count - 1) * borderW) / count;
00242         }
00243         break;
00244     }
00245 
00246     // this will never happen anyway
00247     return 1;
00248 }

Fluxbox CVS-Jan-2003




      



Got comments about the page? Send them to webmaster.
If you have general Fluxbox related questions ask them on our irc channel or mailing lists.

Show Source








Designed by aLEczapKA