]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #20 main menu size processing
authorsbh <sergey.belash@opencascade.com>
Fri, 8 Aug 2014 06:37:13 +0000 (10:37 +0400)
committersbh <sergey.belash@opencascade.com>
Fri, 8 Aug 2014 06:37:13 +0000 (10:37 +0400)
src/XGUI/XGUI_Command.cpp
src/XGUI/XGUI_Command.h
src/XGUI/XGUI_MainMenu.cpp
src/XGUI/XGUI_MainMenu.h
src/XGUI/XGUI_MainWindow.cpp
src/XGUI/XGUI_MainWindow.h
src/XGUI/XGUI_MenuGroupPanel.cpp
src/XGUI/XGUI_MenuGroupPanel.h
src/XGUI/XGUI_Workshop.cpp

index b289f8014ec6b65c6efe2084978bebd0fe0a6068..f260a1691ab43575caa8d72e2686c62ed33af402 100644 (file)
@@ -1,6 +1,33 @@
 #include "XGUI_Command.h"
+#include <QEvent>
 
-#include <QToolButton>
+
+XGUI_MenuButton::XGUI_MenuButton(const QIcon& theIcon,
+                                 const QString& theText,
+                                 QWidget * theParent)
+    : QPushButton(theIcon, theText, theParent)
+
+{
+  setFlat(true);
+  setMinimumSize(MIN_BUTTON_WIDTH, MIN_BUTTON_HEIGHT);
+  setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+  QString aStyleSheet = "QPushButton { text-align: left; }";
+  //aStyleSheet += "QPushButton:hover { border: 1px solid gray; border-radius: 3px; }";
+  setStyleSheet(aStyleSheet);
+  installEventFilter(this);
+}
+
+//void XGUI_MenuButton::enterEvent(QEvent * event)
+//{
+//  if(isEnabled()) {
+//    setFlat(false);
+//  }
+//}
+
+//void XGUI_MenuButton::leaveEvent(QEvent * event)
+//{
+//  setFlat(true);
+//}
 
 XGUI_Command::XGUI_Command(const QString& theId, QObject * parent, bool isCheckable)
     : QWidgetAction(parent), myCheckable(isCheckable)
@@ -24,16 +51,8 @@ XGUI_Command::~XGUI_Command()
 QWidget* XGUI_Command::createWidget(QWidget* theParent)
 {
   if (theParent->inherits("XGUI_MenuGroupPanel")) {
-    QToolButton* aButton = new QToolButton(theParent);
-    aButton->setIcon(icon());
-    aButton->setText(text());
-    aButton->setStyleSheet("QToolButton::menu-indicator { image: none; }");
-    aButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-    aButton->setAutoRaise(true);
-    aButton->setArrowType(Qt::NoArrow);
+    XGUI_MenuButton* aButton = new XGUI_MenuButton(icon(), text(), theParent);
     aButton->setCheckable(myCheckable);
-    aButton->setMinimumSize(MIN_BUTTON_WIDTH, MIN_BUTTON_HEIGHT);
-    aButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     QKeySequence aKeys = shortcut();
     QString aToolTip = toolTip();
     if (!aKeys.isEmpty())
index 4247a7ca4b8be681ee54c0649bd5aea6f4cbdadd..fcd99b3c8c6bca97c200d50f3c7a19b835dea89e 100644 (file)
@@ -3,10 +3,23 @@
 
 #include "XGUI.h"
 #include <QWidgetAction>
+#include <QPushButton>
 
 #define MIN_BUTTON_HEIGHT 25
 #define MIN_BUTTON_WIDTH 60
 
+class XGUI_EXPORT XGUI_MenuButton: public QPushButton
+{
+  Q_OBJECT
+ public:
+  XGUI_MenuButton(const QIcon & icon, const QString & text, QWidget * parent = 0);
+
+// protected:
+//  virtual void enterEvent(QEvent * event);
+//  virtual void leaveEvent(QEvent * event);
+
+};
+
 /**\class XGUI_Command
  * \ingroup GUI
  * \brief Represents a command item in the application menu (Workbench)
index 9f79a1db88b6fd44796cbd4e33577fbed8f552ee..a16076e54024327846d11e202388ea3930ffdaef 100644 (file)
@@ -1,5 +1,6 @@
 #include <XGUI_MainMenu.h>
 #include <XGUI_Workbench.h>
+#include <XGUI_MenuGroupPanel.h>
 #include <XGUI_MainWindow.h>
 #include <XGUI_Command.h>
 
@@ -8,17 +9,27 @@
 #include <QLabel>
 #include <QDockWidget>
 #include <QEvent>
+#include <QPushButton>
+#include <QTabBar>
 
 XGUI_MainMenu::XGUI_MainMenu(XGUI_MainWindow *parent)
-    : QObject(parent), myDesktop(parent)
+    : QWidget(parent), myDesktop(parent)
 {
-  parent->setTabPosition(Qt::TopDockWidgetArea, QTabWidget::North);
-  myDesktop->setStyleSheet("QTabBar::tab {height: 24px;}");
-  myGeneralPage = addWorkbench(tr("General"));
+  myGeneralPage = new XGUI_MenuGroupPanel(this);
+  myGeneralPage->setObjectName("Default");
   myGeneralPage->parentWidget()->setMaximumWidth(200);
   myGeneralPage->installEventFilter(this);
-//  QString aStyle = myDesktop->styleSheet();
-//  aStyle += " QTabBar::tab {min-height: 24px;}";
+  myGeneralPage->setFrameStyle(QFrame::StyledPanel);
+
+  myMenuTabs = new QTabWidget(this);
+  myMenuTabs->setStyleSheet("QTabBar::tab {height: 24px;} QTabWidget:pane {border: 0px;}");
+  QHBoxLayout* aMainLayout = new QHBoxLayout(this);
+  aMainLayout->addWidget(myGeneralPage);
+  aMainLayout->addWidget(myMenuTabs);
+  aMainLayout->setContentsMargins(0, 2, 2, 0);
+  aMainLayout->setSpacing(2);
+  setLayout(aMainLayout);
+  setFixedHeight(menuHeight());
 }
 
 XGUI_MainMenu::~XGUI_MainMenu(void)
@@ -27,27 +38,13 @@ XGUI_MainMenu::~XGUI_MainMenu(void)
 
 XGUI_Workbench* XGUI_MainMenu::addWorkbench(const QString& theId, const QString& theTitle)
 {
-  QDockWidget* aDock = new QDockWidget(myDesktop);
-  aDock->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);
-  aDock->setAllowedAreas(Qt::TopDockWidgetArea);
   QString aTitle = theTitle;
   if (aTitle.isEmpty()) {
     aTitle = tr(theId.toLatin1().constData());
   }
-  aDock->setWindowTitle(aTitle);
-  aDock->setMinimumHeight(30);
-  aDock->setContentsMargins(0, 0, 0, 0);
-
-  XGUI_Workbench* aPage = new XGUI_Workbench(aDock);
+  XGUI_Workbench* aPage = new XGUI_Workbench(myMenuTabs);
   aPage->setObjectName(theId);
-  aDock->setWidget(aPage);
-
-  myDesktop->addDockWidget(Qt::TopDockWidgetArea, aDock);
-  if (myMenuTabs.length() > 1) {
-    myDesktop->tabifyDockWidget(myMenuTabs.last(), aDock);
-  }
-
-  myMenuTabs.append(aDock);
+  myMenuTabs->addTab(aPage, aTitle);
   return aPage;
 }
 
@@ -71,24 +68,48 @@ bool XGUI_MainMenu::eventFilter(QObject *theWatched, QEvent *theEvent)
   return QObject::eventFilter(theWatched, theEvent);
 }
 
+void XGUI_MainMenu::insertConsole(QWidget* theConsole)
+{
+  int aConsoleTabId = myMenuTabs->addTab(theConsole, "Console");
+
+  QTabBar* aTabBar = myMenuTabs->findChild<QTabBar*>();
+  QPushButton* aCloseTabButton = new QPushButton();
+  aCloseTabButton->setFixedSize(16, 16);
+  aCloseTabButton->setIcon(QIcon(":pictures/wnd_close.png"));
+  aCloseTabButton->setFlat(true);
+  aTabBar->setTabButton(aConsoleTabId,
+                        QTabBar::RightSide,
+                        aCloseTabButton);
+
+  connect(aCloseTabButton, SIGNAL(clicked()),
+          myDesktop, SLOT(dockPythonConsole()));
+}
+
+void XGUI_MainMenu::removeConsole()
+{
+  const int kLastTab = myMenuTabs->count() - 1;
+  myMenuTabs->removeTab(kLastTab);
+}
+
 XGUI_Command* XGUI_MainMenu::feature(const QString& theId) const
 {
-  QList<QDockWidget*>::const_iterator aIt;
-  for (aIt = myMenuTabs.constBegin(); aIt != myMenuTabs.constEnd(); ++aIt) {
-    XGUI_Workbench* aWbn = static_cast<XGUI_Workbench*>((*aIt)->widget());
-    XGUI_Command* aCmd = aWbn->feature(theId);
-    if (aCmd)
-      return aCmd;
+  XGUI_Command* result;
+  result = myGeneralPage->feature(theId);
+  if (!result) {
+    for (int aTabIdx = 0; aTabIdx < myMenuTabs->count(); ++aTabIdx) {
+      XGUI_Workbench* aWbn = static_cast<XGUI_Workbench*>(myMenuTabs->widget(aTabIdx));
+      result = aWbn->feature(theId);
+      if (result) break;
+    }
   }
-  return 0;
+  return result;
 }
 
 QList<XGUI_Command*> XGUI_MainMenu::features() const
 {
-  QList<XGUI_Command*> aList;
-  QList<QDockWidget*>::const_iterator aIt;
-  for (aIt = myMenuTabs.constBegin(); aIt != myMenuTabs.constEnd(); ++aIt) {
-    XGUI_Workbench* aWbn = static_cast<XGUI_Workbench*>((*aIt)->widget());
+  QList<XGUI_Command*> aList = myGeneralPage->features();
+  for (int aTabIdx = 0; aTabIdx < myMenuTabs->count(); ++aTabIdx) {
+    XGUI_Workbench* aWbn = static_cast<XGUI_Workbench*>(myMenuTabs->widget(aTabIdx));
     aList.append(aWbn->features());
   }
   return aList;
@@ -97,11 +118,33 @@ QList<XGUI_Command*> XGUI_MainMenu::features() const
 QList<XGUI_Workbench*> XGUI_MainMenu::workbenches() const
 {
   QList<XGUI_Workbench*> aList;
-  aList.append(myGeneralPage);
-  foreach(QDockWidget* aDoc, myMenuTabs) {
-    XGUI_Workbench* aWb = dynamic_cast<XGUI_Workbench*>(aDoc->widget());
-    if (aWb)
+  for (int aTabIdx = 0; aTabIdx < myMenuTabs->count(); ++aTabIdx) {
+    XGUI_Workbench* aWb = dynamic_cast<XGUI_Workbench*>(myMenuTabs->widget(aTabIdx));
+    if (aWb) {
       aList.append(aWb);
+    }
   }
   return aList;
-}
\ No newline at end of file
+}
+
+int XGUI_MainMenu::menuItemSize() const
+{
+  //TODO(sbh, vsv): get this value from the preferences
+  static const ItemSize DEFAULT_ITEM_SIZE = Medium;
+  return (int) DEFAULT_ITEM_SIZE;
+}
+
+int XGUI_MainMenu::menuHeight() const
+{
+  // Default group has no tabs above --> one extra row
+  int rows = menuItemRowsCount() + 1;
+  const int kMarginsSpacings = 4;
+  return rows * menuItemSize() + kMarginsSpacings;
+}
+
+int XGUI_MainMenu::menuItemRowsCount() const
+{
+  //TODO(sbh, vsv): get this value from the preferences
+  static const int DEFAULT_ITEM_ROWS_COUNT = 3;
+  return DEFAULT_ITEM_ROWS_COUNT;
+}
index 945ddcb8d9f890b6d90811986f280805c69dfb01..3be908792422bc615f555073b0c96bc855d37718 100644 (file)
@@ -5,6 +5,7 @@
 #include <QObject>
 #include <QList>
 #include <QMap>
+#include <QWidget>
 
 class XGUI_Command;
 class XGUI_MainWindow;
@@ -17,14 +18,22 @@ class QAction;
 class QDockWidget;
 class QEvent;
 
-
 /**\class XGUI_MainMenu
  * \ingroup GUI
  * \brief Class for creation of main menu (set of workbenches)
  */
-class XGUI_EXPORT XGUI_MainMenu: public QObject
+class XGUI_EXPORT XGUI_MainMenu: public QWidget
 {
-Q_OBJECT
+  Q_OBJECT
+
+  //! Size of menu item
+  //TODO(sbh, vsv): Move to the settings
+  enum ItemSize {
+    Small = 20,
+    Medium = 25,
+    Large = 30
+  };
+
 public:
   XGUI_MainMenu(XGUI_MainWindow *parent);
   virtual ~XGUI_MainMenu();
@@ -36,10 +45,10 @@ public:
   XGUI_Workbench* findWorkbench(const QString& theId)  const;
 
   //! Returns General page (predefined workbench)
-  XGUI_Workbench* generalPage() const { return myGeneralPage; }
+  XGUI_MenuGroupPanel* generalPage() const { return myGeneralPage; }
 
   //! Rerturns last created workbench in dock widget container
-  QDockWidget* getLastDockWindow() const { return myMenuTabs.last(); }
+  //QDockWidget* getLastDockWindow() const;
 
   //! Returns already created command by its ID
   XGUI_Command* feature(const QString& theId) const;
@@ -51,10 +60,19 @@ public:
 
   virtual bool eventFilter(QObject *theWatched, QEvent *theEvent);
 
+  //! Displays given console as a tab in the workbench
+  void insertConsole(QWidget*);
+  //! Removes already created tab with python console
+  void removeConsole();
+
+  int menuItemSize() const;
+  int menuItemRowsCount() const;
+  int menuHeight() const;
+
 private:
   XGUI_MainWindow* myDesktop;
-  QList<QDockWidget*> myMenuTabs;
-  XGUI_Workbench* myGeneralPage;
+  QTabWidget* myMenuTabs;
+  XGUI_MenuGroupPanel* myGeneralPage;
 
   QMap<XGUI_Command*, bool> myCommandState;
 };
index 1400fc0ccc7f4c502b092cbdae6bc5b93cd4532b..b989488c694c9c4b8f2959f7c54852bd8f4c1104 100644 (file)
 
 XGUI_MainWindow::XGUI_MainWindow(QWidget* parent)
     : QMainWindow(parent), 
-    myPythonConsole(0)
+    myPythonConsole(0),
+    myIsConsoleDocked(false)
 {
   setWindowTitle(tr("New Geom"));
-  myMenuBar = new XGUI_MainMenu(this);
-
+  createMainMenu();
   QMdiArea* aMdiArea = new QMdiArea(this);
   aMdiArea->setContextMenuPolicy(Qt::ActionsContextMenu);
   setCentralWidget(aMdiArea);
@@ -67,15 +67,8 @@ QMdiArea* XGUI_MainWindow::mdiArea() const
 void XGUI_MainWindow::showPythonConsole()
 {
   if (!myPythonConsole) {
-
-    QDockWidget* aDoc = new QDockWidget(this);
-    aDoc->setFeatures(QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar);
-    aDoc->setMinimumHeight(0);
-    aDoc->setWindowTitle("Console");
-    myPythonConsole = new PyConsole_EnhConsole( aDoc, new PyConsole_EnhInterp());
-    aDoc->setWidget(myPythonConsole);
-    addDockWidget(Qt::TopDockWidgetArea, aDoc);
-    tabifyDockWidget(myMenuBar->getLastDockWindow(), aDoc);
+    myPythonConsole = new PyConsole_EnhConsole(this, new PyConsole_EnhInterp());
+    undockPythonConsole();
   }
   myPythonConsole->parentWidget()->show();
 }
@@ -87,6 +80,44 @@ void XGUI_MainWindow::hidePythonConsole()
     myPythonConsole->parentWidget()->hide();
 }
 
+//******************************************************
+void XGUI_MainWindow::dockPythonConsole()
+{
+  if (!myPythonConsole)
+    return;
+  myMenuBar->removeConsole();
+  QDockWidget* aDock = new QDockWidget(this);
+  aDock->setFeatures(QDockWidget::AllDockWidgetFeatures |
+                     QDockWidget::DockWidgetVerticalTitleBar);
+  aDock->setAllowedAreas(Qt::LeftDockWidgetArea  |
+                         Qt::RightDockWidgetArea |
+                         Qt::BottomDockWidgetArea);
+  aDock->setMinimumHeight(0);
+  aDock->setWindowTitle("Console");
+  aDock->setWidget(myPythonConsole);
+  addDockWidget(Qt::BottomDockWidgetArea, aDock);
+  // Undock python console if widget is closed...
+  CloseEventWatcher* aWatcher =  new CloseEventWatcher(aDock);
+  connect(aWatcher, SIGNAL(widgetClosed()),
+          this,     SLOT(undockPythonConsole()));
+  aDock->installEventFilter(aWatcher);
+}
+
+void XGUI_MainWindow::undockPythonConsole()
+{
+  if (!myPythonConsole)
+    return;
+  QDockWidget* aDock = qobject_cast<QDockWidget*>(myPythonConsole->parentWidget());
+  //When the application starts console will be displayed as
+  //a wokbench tab, so there is no dock yet
+  if(aDock) {
+    aDock->hide();
+    aDock->setWidget(NULL);
+    aDock->deleteLater();
+  }
+  myMenuBar->insertConsole(myPythonConsole);
+}
+
 //******************************************************
 void XGUI_MainWindow::createSubWindow()
 {
@@ -205,3 +236,30 @@ void XGUI_MainWindow::closeEvent(QCloseEvent * event)
   emit exitKeySequence();
   event->ignore();
 }
+
+void XGUI_MainWindow::createMainMenu()
+{
+  myMenuBar = new XGUI_MainMenu(this);
+  QDockWidget* aMenuDock = new QDockWidget(this);
+  aMenuDock->setWidget(myMenuBar);
+  aMenuDock->setAllowedAreas(Qt::TopDockWidgetArea);
+  aMenuDock->setFeatures(QDockWidget::DockWidgetVerticalTitleBar);
+  aMenuDock->setWindowTitle(tr("General"));
+  addDockWidget(Qt::TopDockWidgetArea, aMenuDock);
+}
+
+CloseEventWatcher::CloseEventWatcher(QObject* theParent)
+    : QObject(theParent)
+{}
+
+bool CloseEventWatcher::eventFilter(QObject *obj, QEvent *event) {
+  if (event->type() == QEvent::Close) {
+    emit widgetClosed();
+    event->ignore();
+    return true;
+  } else {
+    // standard event processing
+    return QObject::eventFilter(obj, event);
+  }
+}
+
index 010f9e309530b3cb12289015b259a85908bfdcee..2126834aad458c51900c72926f786ca14619ad54 100644 (file)
@@ -44,6 +44,8 @@ public:
 public slots:
   void showPythonConsole();
   void hidePythonConsole();
+  void dockPythonConsole();
+  void undockPythonConsole();
 
   void createSubWindow();
   
@@ -59,12 +61,29 @@ signals:
 
 protected:
   void closeEvent(QCloseEvent* event);
+  void createMainMenu();
 
 private:
   XGUI_MainMenu* myMenuBar;
   XGUI_Viewer* myViewer;
 
   PyConsole_EnhConsole* myPythonConsole;
+  //! Python console can be a dock widget if true, else as the tab.
+  bool myIsConsoleDocked;
+};
+
+class XGUI_EXPORT CloseEventWatcher: public QObject {
+  Q_OBJECT
+
+ public:
+  CloseEventWatcher(QObject* theParent);
+
+ signals:
+  void widgetClosed();
+
+ protected:
+  bool eventFilter(QObject *obj, QEvent *);
+
 };
 
 #endif
index 8d5d24b2146206e706922eff835521861c478797..f268c369122f0d70094eb6546747a7b1d506d71c 100644 (file)
 #include <iostream>
 
 XGUI_MenuGroupPanel::XGUI_MenuGroupPanel(QWidget *parent)
-    : QWidget(parent), myNewRow(0), myNewCol(0), myMaxRow(1)
+    : QFrame(parent), myNewRow(0), myNewCol(0), myMaxRow(1)
 {
   myLayout = new QGridLayout(this);
   myLayout->setSpacing(0);
   myLayout->setMargin(0);
   myLayout->setContentsMargins(0, 0, 0, 0);
+  setFrameShape(QFrame::NoFrame);
 }
 
+
+
 void XGUI_MenuGroupPanel::addCommand(XGUI_Command* theAction)
 {
   myActions.append(theAction);
@@ -68,9 +71,9 @@ XGUI_Command* XGUI_MenuGroupPanel::addFeature(const QString& theId, const QStrin
 {
   XGUI_Command* aCommand = new XGUI_Command(theId, theIcon, theTitle, this, isCheckable);
   aCommand->setToolTip(theTip);
-  if (!theKeys.isEmpty())
+  if (!theKeys.isEmpty()) {
     aCommand->setShortcut(theKeys);
-
+  }
   addCommand(aCommand);
   return aCommand;
 }
index b43ef75c6e7175e3561c7294da3ee111c6791841..07f51ed1eac140a981fbe492772bdea59233f3d0 100644 (file)
@@ -2,20 +2,22 @@
 #define XGUI_MenuGroupPanel_H
 
 #include "XGUI.h"
-#include <QWidget>
+#include <QFrame>
 #include <QMap>
 
 class XGUI_Command;
 class QGridLayout;
 
+
 /**\class XGUI_MenuGroupPanel
  * \ingroup GUI
  * \brief Represents a one group in a page of main menu (workbench)
  */
-class XGUI_EXPORT XGUI_MenuGroupPanel: public QWidget
+class XGUI_EXPORT XGUI_MenuGroupPanel: public QFrame
 {
-Q_OBJECT
-public:
+  Q_OBJECT
+
+ public:
   explicit XGUI_MenuGroupPanel(QWidget *parent = 0);
 
   //! Adding a new feature (Command) in the group
index 8577da961fe51ba063fb32468a4b73f9c105c30c..db0ab95fd7765e0d98f4b981f9b9aa9eec03e189 100644 (file)
@@ -168,10 +168,8 @@ void XGUI_Workshop::initMenu()
     salomeConnector()->addEditMenuSeparator();
     return;
   }
-  XGUI_Workbench* aPage = myMainWindow->menuObject()->generalPage();
-
   // File commands group
-  XGUI_MenuGroupPanel* aGroup = aPage->addGroup("Default");
+  XGUI_MenuGroupPanel* aGroup = myMainWindow->menuObject()->generalPage();
 
   XGUI_Command* aCommand;
 
@@ -208,11 +206,11 @@ void XGUI_Workshop::initMenu()
                                 QIcon(":pictures/close.png"), QKeySequence::Close);
   aCommand->connectTo(this, SLOT(onExit()));
   //FIXME: SBH's test action. Can be used for some GUI tests.
-  //#ifdef _DEBUG
-  //  aCommand = aGroup->addFeature("TEST_CMD", "Test!", "Private debug button",
-  //                                QIcon(":pictures/close.png"));
-  //  aCommand->connectTo(myActionsMgr, SLOT(update()));
-  //#endif
+//  #ifdef _DEBUG
+//    aCommand = aGroup->addFeature("TEST_CMD", "Test!", "Private debug button",
+//                                  QIcon(":pictures/close.png"), QKeySequence(), true);
+//    aCommand->connectTo(myMainWindow, SLOT(dockPythonConsole()));
+//  #endif
 }
 
 //******************************************************
@@ -775,10 +773,8 @@ QList<QAction*> XGUI_Workshop::getModuleCommands() const
   } else {
     XGUI_MainMenu* aMenuBar = myMainWindow->menuObject();
     foreach (XGUI_Workbench* aWb, aMenuBar->workbenches()) {
-      if (aWb != aMenuBar->generalPage()) {
-        foreach(XGUI_Command* aCmd, aWb->features())
-          aCommands.append(aCmd);
-      }
+      foreach(XGUI_Command* aCmd, aWb->features())
+        aCommands.append(aCmd);
     }
   }
   return aCommands;