toplevel.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:18k
- /*
- * ===========================================================================
- * PRODUCTION $Log: toplevel.cpp,v $
- * PRODUCTION Revision 1000.1 2004/06/01 21:14:14 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: toplevel.cpp,v 1000.1 2004/06/01 21:14:14 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- * CTopLevel -- top-level MDI window
- */
- #include <ncbi_pch.hpp>
- #include <gui/widgets/toplevel/toplevel.hpp>
- #include <FL/Fl.H>
- #include <FL/Fl_Box.H>
- #include <FL/Fl_Button.H>
- #include <FL/Fl_Group.H>
- #include <FL/Fl_Pixmap.H>
- #include <FL/Fl_Double_Window.H>
- #include <FL/fl_draw.H>
- #include "icon_tray.hpp"
- #include <algorithm>
- #include <math.h>
- BEGIN_NCBI_SCOPE
- //
- // static pixmaps
- // these are for the buttons in the system tray
- //
- static const char* sc_minimize_xpm[] = {
- " 8 8 2 1",
- " c #111111",
- "X c None",
- "XXXXXXXX",
- "XXXXXXXX",
- "XXXXXXXX",
- "XXXXXXXX",
- "XXXXXXXX",
- "XXXXXXXX",
- " ",
- " "
- };
- static const char* sc_maximize_xpm[] = {
- " 8 8 2 1",
- " c #111111",
- "X c None",
- " ",
- " ",
- " XXXXXX ",
- " XXXXXX ",
- " XXXXXX ",
- " XXXXXX ",
- " XXXXXX ",
- " "
- };
- static const char* sc_close_xpm[] = {
- "8 8 3 1",
- " c #111111",
- ". c #616561",
- "X c None",
- " .XXXX. ",
- ". .XX. .",
- "X. .. .X",
- "XX. .XX",
- "XX. .XX",
- "X. .. .X",
- ". .XX. .",
- " .XXXX. ",
- };
- //
- // static accessors - forwarded to CChildFrame
- //
- Fl_Boxtype CTopLevel::GetSysButtonBox(void)
- {
- return CChildFrame::GetSysButtonBox();
- }
- void CTopLevel::SetSysButtonBox(Fl_Boxtype box)
- {
- CChildFrame::SetSysButtonBox(box);
- }
- Fl_Color CTopLevel::GetSysButtonColor(void)
- {
- return CChildFrame::GetSysButtonColor();
- }
- void CTopLevel::SetSysButtonColor(Fl_Color color)
- {
- CChildFrame::SetSysButtonColor(color);
- }
- Fl_Color CTopLevel::GetSelectedColor(void)
- {
- return CChildFrame::GetSelectedColor();
- }
- void CTopLevel::SetSelectedColor(Fl_Color color)
- {
- CChildFrame::SetSelectedColor(color);
- }
- Fl_Font CTopLevel::GetTitleFont(void)
- {
- return CChildFrame::GetTitleFont();
- }
- void CTopLevel::SetTitleFont(Fl_Font font)
- {
- CChildFrame::SetTitleFont(font);
- }
- Fl_Color CTopLevel::GetTitleColor(void)
- {
- return CChildFrame::GetTitleColor();
- }
- void CTopLevel::SetTitleColor(Fl_Color color)
- {
- CChildFrame::SetTitleColor(color);
- }
- int CTopLevel::GetTitleSize(void)
- {
- return CChildFrame::GetTitleSize();
- }
- void CTopLevel::SetTitleSize(int size)
- {
- CChildFrame::SetTitleSize(size);
- }
- int CTopLevel::GetTitleAlign(void)
- {
- return CChildFrame::GetTitleAlign();
- }
- void CTopLevel::SetTitleAlign(int align)
- {
- CChildFrame::SetTitleAlign(align);
- }
- //
- //
- // class CTopLevel
- //
- //
- CTopLevel::CTopLevel(int x, int y, int wid, int ht, const char* label)
- : Fl_Double_Window(x, y, wid, ht, label),
- m_Selected(NULL),
- m_IconTray(NULL),
- m_MinimizeXPM(new Fl_Pixmap(sc_minimize_xpm)),
- m_MaximizeXPM(new Fl_Pixmap(sc_maximize_xpm)),
- m_CloseXPM (new Fl_Pixmap(sc_close_xpm)),
- m_LastChildX(0),
- m_LastChildY(10)
- {
- }
- CTopLevel::~CTopLevel()
- {
- delete m_MaximizeXPM;
- delete m_MinimizeXPM;
- delete m_CloseXPM;
- }
- //
- // add a child to our window
- //
- void CTopLevel::AddChild(CChild* child)
- {
- if (!child) {
- return;
- }
- //
- // create a new frame to hold the child
- //
- child->hide();
- // determine where this child will occur
- m_LastChildX += CChildFrame::GetTitleBarHeight();
- m_LastChildY += CChildFrame::GetTitleBarHeight();
- if (m_LastChildX > w() - CChildFrame::GetTitleBarHeight()) {
- m_LastChildX = 0;
- }
- if (m_LastChildY > h() - CChildFrame::GetTitleBarHeight()) {
- m_LastChildY = 0;
- }
- //
- // positions for our frame and subwidgets
- //
- // pseudoconstants constrolling our layout
- const int button_w = 11 + Fl::box_dw(CChildFrame::GetSysButtonBox());
- const int button_h = 11 + Fl::box_dh(CChildFrame::GetSysButtonBox());
- const int x_step = button_w + 2;
- CChildFrame::SetTitleBarHeight(max (CChildFrame::GetTitleSize() + 3,
- button_h + 3));
- // frame positions - dependent on our child window
- Fl_Boxtype frame_box = FL_UP_BOX;
- int frame_x = m_LastChildX;
- int frame_y = m_LastChildY;
- int frame_w = child->w() + Fl::box_dw(frame_box);
- int frame_h = child->h() + Fl::box_dh(frame_box) +
- CChildFrame::GetTitleBarHeight();
- // reposition our child relative to the new frame
- child->position(frame_x + Fl::box_dx(frame_box),
- frame_y + Fl::box_dy(frame_box) +
- CChildFrame::GetTitleBarHeight());
- // title group - encompasses the entire title bar
- int title_group_x = 0 + Fl::box_dx(frame_box);
- int title_group_y = 0 + Fl::box_dy(frame_box);
- int title_group_w = frame_w - Fl::box_dw(frame_box) - 1;
- int title_group_h = CChildFrame::GetTitleBarHeight();
- // system buttons group
- int sysbutt_x = 0 + frame_w - Fl::box_dw(frame_box) - x_step * 3 + 2;
- int sysbutt_y = 0 + Fl::box_dy(frame_box);
- int sysbutt_w = title_group_w - (sysbutt_x - 0) - 2;
- int sysbutt_h = CChildFrame::GetTitleBarHeight();
- // title label
- int title_x = title_group_x;
- int title_y = title_group_y;
- int title_w = title_group_w - sysbutt_w - 5;
- int title_h = title_group_h;
- // offsets for buttons
- int button_y = sysbutt_y + (sysbutt_h - button_h + 1) / 2;
- // create the parent frame
- CChildFrame* frame = new CChildFrame(frame_x, frame_y, frame_w, frame_h);
- frame->box(frame_box);
- // title bar
- // this has a few system buttons in it
- Fl_Group* title_bar = new Fl_Group(title_group_x, title_group_y,
- title_group_w, title_group_h);
- title_bar->clear_visible_focus();
- // spacer to prevent system buttons from resizing
- // this also holds the title
- Fl_Group* spacer = new Fl_Group(title_x, title_y, title_w, title_h,
- child->label());
- spacer->box (FL_NO_BOX);
- spacer->color (CChildFrame::GetSelectedColor());
- spacer->align (CChildFrame::GetTitleAlign() | FL_ALIGN_INSIDE);
- spacer->labelcolor(CChildFrame::GetTitleColor());
- spacer->labelfont (CChildFrame::GetTitleFont());
- spacer->labelsize (CChildFrame::GetTitleSize());
- spacer->clear_visible_focus();
- spacer->end();
- title_bar->resizable(spacer);
- // system buttons, grouped to prevent resize and to facilitate easier event
- // screening
- Fl_Group* sys_buttons = new Fl_Group(sysbutt_x, sysbutt_y,
- sysbutt_w, sysbutt_h);
- sys_buttons->box(FL_NO_BOX);
- sys_buttons->clear_visible_focus();
- // minimize button
- Fl_Button* minimize = new Fl_Button(sysbutt_x, button_y,
- button_w, button_h);
- minimize->image (m_MinimizeXPM);
- minimize->box (CChildFrame::GetSysButtonBox());
- minimize->color (CChildFrame::GetSysButtonColor());
- minimize->tooltip ("Minimize this window");
- minimize->callback((Fl_Callback*)&CTopLevel::x_StaticCB_Minimize, this);
- minimize->clear_visible_focus();
- // maximize button
- Fl_Button* maximize = new Fl_Button(sysbutt_x + x_step, button_y,
- button_w, button_h);
- maximize->image (m_MaximizeXPM);
- maximize->box (CChildFrame::GetSysButtonBox());
- maximize->color (CChildFrame::GetSysButtonColor());
- maximize->tooltip ("Maximize this window");
- maximize->callback((Fl_Callback*)&CTopLevel::x_StaticCB_Maximize, this);
- maximize->clear_visible_focus();
- // close button
- Fl_Button* close = new Fl_Button(sysbutt_x + x_step * 2, button_y,
- button_w, button_h);
- close->image (m_CloseXPM);
- close->box (CChildFrame::GetSysButtonBox());
- close->color (CChildFrame::GetSysButtonColor());
- close->tooltip ("Hide this window");
- close->callback((Fl_Callback*)&CTopLevel::x_StaticCB_Close, this);
- close->clear_visible_focus();
- // end sys group
- sys_buttons->end();
- // end title bar
- title_bar->end();
- // end frame
- frame->end();
- add(*frame);
- // create a frame manager class
- frame->m_TitleBar = title_bar;
- frame->m_SysButtons = sys_buttons;
- frame->m_Title = spacer;
- frame->Attach(child);
- m_Children.push_back(frame);
- frame->show();
- child->show();
- // and select our current frame
- x_SetSelected(frame);
- }
- void CTopLevel::x_SetSelected(CChildFrame* frame)
- {
- if (m_Selected) {
- m_Selected->m_Title->box(FL_NO_BOX);
- m_Selected->m_Title->redraw();
- }
- // determine our new selection
- // if the selection is NULL and we have kids, we automatically select the
- // last child ( = topmost)
- m_Selected = frame;
- if ( !m_Selected ) {
- return;
- }
- // cycle the child to the end of the array of children
- // this has the effect of raising the window and provides us with correct
- // selection order
- TChildren::iterator iter =
- std::find(m_Children.begin(), m_Children.end(), m_Selected);
- if (iter != m_Children.end()) {
- CChildFrame* frame = *iter;
- m_Children.erase(iter);
- m_Children.push_back(frame);
- }
- // we re-add the frame
- // this keeps the child array in sync with m_Children
- add(m_Selected);
- //m_Selected->hide();
- m_Selected->show();
- // make sure the title bar is correctly highlighted
- m_Selected->m_Title->box(FL_ROUNDED_BOX);
- m_Selected->m_Title->redraw();
- }
- int CTopLevel::handle(int event)
- {
- switch (event) {
- //
- // FL_PUSH: handle mouse click events
- // We need to distinguish a few things here:
- //
- // title bar single click - begin drag or select new child
- // frame border single click - begin resize or select new child
- // system buttons single click - select new child and pass on to button
- //
- case FL_PUSH:
- if ( !m_Selected || !Fl::event_inside(m_Selected) ) {
- // try to select another child
- // we scan in reverse, as this scans top-most down
- TChildren::reverse_iterator start(m_Children.end());
- TChildren::reverse_iterator stop (m_Children.begin());
- for ( ; start != stop; ++start) {
- CChildFrame* child = *start;
- if (child->visible() && Fl::event_inside(child)) {
- x_SetSelected(child);
- if (Fl::event_inside(child->m_SysButtons)) {
- // we select the window, but let the child process
- // the event
- break;
- }
- // claim the event for our own, don't pass on to children
- // or parent
- return 1;
- }
- }
- }
- break;
- default:
- break;
- }
- return Fl_Double_Window::handle(event);
- }
- void CTopLevel::resize(int x, int y, int w, int h)
- {
- if (m_Selected && m_Selected->GetMaximized()) {
- m_Selected->resize(0, 0, w, h);
- }
- Fl_Double_Window::resize(x, y, w, h);
- }
- //
- // Force all windows to cascade
- //
- void CTopLevel::Cascade(void)
- {
- if (m_Selected && m_Selected->GetMaximized()) {
- return;
- }
- int pos_x = 0;
- int pos_y = 0;
- int step = CChildFrame::GetTitleBarHeight();
- NON_CONST_ITERATE (TChildren, iter, m_Children) {
- CChildFrame* frame = *iter;
- if ( !frame->visible() || frame->GetMinimized() ) {
- continue;
- }
- frame->position(pos_x, pos_y);
- pos_x += step;
- pos_y += step;
- if (pos_x > w() - 100) {
- pos_x = 0;
- }
- if (pos_y > h() - step) {
- pos_y = 0;
- }
- }
- }
- void CTopLevel::Tile(void)
- {
- if (m_Children.size() == 0 ||
- (m_Selected && m_Selected->GetMaximized())) {
- return;
- }
- // firstly, count the number of kids we evaluate
- int kids = 0;
- ITERATE (TChildren, iter, m_Children) {
- const CChildFrame* frame = *iter;
- if ( !frame->visible() || frame->GetMinimized() ) {
- continue;
- }
- ++kids;
- }
- // determine the optimal number of rows and columns
- float s = (float)::sqrt((double)kids);
- int kids_w = (int)s;
- int kids_h = kids_w;
- if (kids_w < s) {
- ++kids_w;
- }
- while (kids_w * kids_h < kids) {
- ++kids_h;
- }
- int child_width = w() / kids_w;
- int child_height = h() / kids_h;
- for (TChildren::size_type i = 0, j = 0; i < m_Children.size(); ++i) {
- CChildFrame* frame = m_Children[i];
- if ( !frame->visible() || frame->GetMinimized() ) {
- continue;
- }
- int pos_x = (j % kids_w) * child_width;
- int pos_y = (j / kids_w) * child_height;
- ++j;
- frame->resize(pos_x, pos_y, child_width, child_height);
- }
- }
- //
- // Window Maximization
- //
- void CTopLevel::x_Maximize(void)
- {
- if ( !m_Selected ) {
- return;
- }
- if ( m_Selected->GetMaximized()) {
- m_Selected->m_State = CChildFrame::eNormal;
- m_Selected->resize(m_Selected->m_SavedPos[0],
- m_Selected->m_SavedPos[1],
- m_Selected->m_SavedPos[2],
- m_Selected->m_SavedPos[3]);
- // must redraw the whole thing
- redraw();
- } else {
- m_Selected->m_SavedPos[0] = m_Selected->x();
- m_Selected->m_SavedPos[1] = m_Selected->y();
- m_Selected->m_SavedPos[2] = m_Selected->w();
- m_Selected->m_SavedPos[3] = m_Selected->h();
- m_Selected->m_State = CChildFrame::eMaximized;
- m_Selected->resize(0, 0, w(), h());
- m_Selected->redraw();
- }
- }
- void CTopLevel::x_StaticCB_Maximize(Fl_Widget* w, void* data)
- {
- if ( !data ) {
- return;
- }
- CTopLevel* toplevel = reinterpret_cast<CTopLevel*> (data);
- toplevel->x_Maximize();
- }
- //
- // Window Minimization / iconification
- //
- void CTopLevel::x_Minimize(void)
- {
- //FIXME: implement this
- #if 0
- if ( !m_Selected ) {
- return;
- }
- if ( !m_IconTray ) {
- m_IconTray = new CIconTray(0, 0, w(), h());
- m_IconTray->box(FL_NO_BOX);
- insert(*m_IconTray, 0);
- }
- m_IconTray->Add(m_Selected);
- redraw();
- #endif
- }
- void CTopLevel::x_StaticCB_Minimize(Fl_Widget*, void* data)
- {
- CTopLevel* frame = reinterpret_cast<CTopLevel*> (data);
- if (frame) {
- frame->x_Minimize();
- }
- }
- //
- // Window "close"
- // This is really hide - true deletion is handled elsewhere
- //
- void CTopLevel::x_Close(void)
- {
- if ( !m_Selected ) {
- return;
- }
- m_Selected->hide();
- }
- void CTopLevel::x_StaticCB_Close(Fl_Widget*, void* data)
- {
- if ( !data ) {
- return;
- }
- CTopLevel* toplevel = reinterpret_cast<CTopLevel*> (data);
- toplevel->x_Close();
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: toplevel.cpp,v $
- * Revision 1000.1 2004/06/01 21:14:14 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
- *
- * Revision 1.9 2004/05/21 22:27:56 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.8 2004/05/03 13:23:58 dicuccio
- * gui/utils --> gui/objutils where needed
- *
- * Revision 1.7 2003/07/25 13:38:44 dicuccio
- * Minor clean-up in issuing redraw events
- *
- * Revision 1.6 2003/03/25 13:17:50 dicuccio
- * Fix (hopefully) MIPS compile - be explicit about which sqrt() is being used
- *
- * Revision 1.5 2003/03/17 19:48:52 dicuccio
- * Fixed xpm specifications to make WorkShop compiler happy.
- *
- * Revision 1.4 2003/03/17 14:55:41 dicuccio
- * Lots of clean-up. Fixed memory leaks in test program; added more explicit
- * destruction pathway to support integration into Genome Workbench. Added
- * explicit calls to cascade / tile widgets in a toplevel workspace.
- *
- * Revision 1.3 2003/03/07 18:14:58 dicuccio
- * Code clean-up. Added missing accessors for look-n-feel statics; aligned
- * accessors in code
- *
- * Revision 1.2 2003/03/07 17:49:25 dicuccio
- * Small clean-ups. Added description for each class.
- *
- * Revision 1.1 2003/03/07 17:36:08 dicuccio
- * Initial revision
- *
- * ===========================================================================
- */