From 18098b4c7042e7ce2f965964bb8977b4f17b9842 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 12 Apr 2013 16:49:43 -0500 Subject: [PATCH] Add initial taskbar drag and drop support This partially resolves Bug 1103 Save horizontal space around TDE Menu button when text is in use and Kicker is greater than one line in height --- kcontrol/taskbar/kcmtaskbarui.ui | 30 ++++++++--- kicker/kicker/buttons/kbutton.cpp | 23 +++++++++ kicker/kicker/buttons/kbutton.h | 12 +++++ kicker/kicker/core/container_button.cpp | 13 +++-- kicker/libkicker/panelbutton.cpp | 10 ++++ kicker/libkicker/panelbutton.h | 11 ++++ kicker/taskbar/taskbar.cpp | 69 +++++++++++++++++++++++++ kicker/taskbar/taskbar.h | 2 + kicker/taskbar/taskbar.kcfg | 5 ++ kicker/taskbar/taskbarcontainer.cpp | 41 +++++++++++++++ kicker/taskbar/taskbarcontainer.h | 5 ++ kicker/taskbar/taskcontainer.cpp | 32 +++++++++++- kicker/taskbar/taskcontainer.h | 7 ++- 13 files changed, 244 insertions(+), 16 deletions(-) diff --git a/kcontrol/taskbar/kcmtaskbarui.ui b/kcontrol/taskbar/kcmtaskbarui.ui index 3803c1b15..1f34c32e4 100644 --- a/kcontrol/taskbar/kcmtaskbarui.ui +++ b/kcontrol/taskbar/kcmtaskbarui.ui @@ -130,6 +130,20 @@ By default this option is selected. By default, this option is selected and all windows are shown. + + + kcfg_AllowDragAndDropReArrange + + + &Allow taskbar items to be rearranged using drag and drop + + + true + + + Turning this option on will allow tasks on the taskbar to be manually rearranged using drag and drop. + + kcfg_ShowWindowListBtn @@ -144,7 +158,7 @@ By default, this option is selected and all windows are shown. Selecting this option causes the taskbar to display a button that, when clicked, shows a list of all windows in a popup menu. - + kcfg_GroupTasks @@ -164,7 +178,7 @@ You can set the taskbar to <strong>Never</strong> group windows, to By default the taskbar groups windows when it is full. - + groupTasksLabel @@ -175,7 +189,7 @@ By default the taskbar groups windows when it is full. kcfg_ShowTaskStates - + kcfg_ShowTaskStates @@ -191,7 +205,7 @@ By default the taskbar groups windows when it is full. The taskbar can show and/or hide tasks based on their current process state. Select <em>Any</em> to show all tasks regardless of current state. - + showTaskStatesLabel @@ -247,12 +261,12 @@ By default this option is selected. By default, this option is selected and all windows are shown. - + appearance - + textLabel1 @@ -263,7 +277,7 @@ By default, this option is selected and all windows are shown. appearance - + kcfg_UseCustomColors @@ -277,7 +291,7 @@ By default, this option is selected and all windows are shown. true - + layout9 diff --git a/kicker/kicker/buttons/kbutton.cpp b/kicker/kicker/buttons/kbutton.cpp index 2f84badb0..88b664059 100644 --- a/kicker/kicker/buttons/kbutton.cpp +++ b/kicker/kicker/buttons/kbutton.cpp @@ -56,6 +56,9 @@ KButton::KButton( TQWidget* parent ) setButtonText(KickerSettings::kMenuText()); setFont(KickerSettings::buttonFont()); setTextColor(KickerSettings::buttonTextColor()); + setMaximumHeight(30); + setMaximumWidth(widthForHeight(30)); + setCenterButtonInContainer(false); } } @@ -64,6 +67,26 @@ KButton::~KButton() MenuManager::the()->unregisterKButton(this); } +int KButton::widthForHeight(int height) const +{ + if (KickerSettings::showKMenuText()) { + return PanelPopupButton::widthForHeight(30); + } + else { + return PanelPopupButton::widthForHeight(height); + } +} + +int KButton::heightForWidth(int width) const +{ + if (KickerSettings::showKMenuText()) { + return 30; + } + else { + return PanelPopupButton::heightForWidth(width); + } +} + void KButton::properties() { TDEApplication::startServiceByDesktopName("kmenuedit", TQStringList(), diff --git a/kicker/kicker/buttons/kbutton.h b/kicker/kicker/buttons/kbutton.h index a051e9d57..896bf56c2 100644 --- a/kicker/kicker/buttons/kbutton.h +++ b/kicker/kicker/buttons/kbutton.h @@ -41,6 +41,18 @@ public: virtual void properties(); + /** + * Reimplement this to give Kicker a hint for the width of the button + * given a certain height. + */ + virtual int widthForHeight(int height) const; + + /** + * Reimplement this to give Kicker a hint for the height of the button + * given a certain width. + */ + virtual int heightForWidth(int width) const; + protected: virtual TQString tileName() { return "KMenu"; } virtual void initPopup(); diff --git a/kicker/kicker/core/container_button.cpp b/kicker/kicker/core/container_button.cpp index 178d83bae..fa3814bfb 100644 --- a/kicker/kicker/core/container_button.cpp +++ b/kicker/kicker/core/container_button.cpp @@ -145,12 +145,17 @@ void ButtonContainer::embedButton(PanelButton* b) { if (!b) return; - delete _layout; - _layout = new TQVBoxLayout(this); - _button = b; + if (_layout) delete _layout; + _button = b; _button->installEventFilter(this); - _layout->add(_button); + + if (b->centerButtonInContainer()) { + TQVBoxLayout* vbox = new TQVBoxLayout(this); + vbox->addWidget(_button); + _layout = vbox; + } + connect(_button, TQT_SIGNAL(requestSave()), TQT_SIGNAL(requestSave())); connect(_button, TQT_SIGNAL(hideme(bool)), TQT_SLOT(hideRequested(bool))); connect(_button, TQT_SIGNAL(removeme()), TQT_SLOT(removeRequested())); diff --git a/kicker/libkicker/panelbutton.cpp b/kicker/libkicker/panelbutton.cpp index 9f05d1f90..0bd13ac7b 100644 --- a/kicker/libkicker/panelbutton.cpp +++ b/kicker/libkicker/panelbutton.cpp @@ -70,6 +70,7 @@ PanelButton::PanelButton( TQWidget* parent, const char* name, bool forceStandard m_highlight(false), m_changeCursorOverItem(forceStandardCursor?false:true), m_hasAcceptedDrag(false), + m_centerInContainer(true), m_arrowDirection(KPanelExtension::Bottom), m_popupDirection(KPanelApplet::Up), m_iconAlignment(AlignCenter), @@ -938,6 +939,10 @@ bool PanelButton::calculateIconSize() return false; } +void PanelButton::setCenterButtonInContainer(bool center) { + m_centerInContainer = center; +} + void PanelButton::updateKickerTip(KickerTip::Data& data) { data.message = TQStyleSheet::escape(title()); @@ -946,6 +951,11 @@ void PanelButton::updateKickerTip(KickerTip::Data& data) data.direction = popupDirection(); } +bool PanelButton::centerButtonInContainer() +{ + return m_centerInContainer; +} + // // PanelPopupButton class // diff --git a/kicker/libkicker/panelbutton.h b/kicker/libkicker/panelbutton.h index b67bc2b9a..80b26f377 100644 --- a/kicker/libkicker/panelbutton.h +++ b/kicker/libkicker/panelbutton.h @@ -205,6 +205,11 @@ public: */ void updateKickerTip(KickerTip::Data& data); + /** + * @return true if the button should be centered in its parent container, false if not + */ + bool centerButtonInContainer(); + signals: /** * Emitted when the button's icon is changed. @@ -347,6 +352,11 @@ protected: */ bool calculateIconSize(); + /** + * @param center true if the button should be centered in its parent container, false if not + */ + void setCenterButtonInContainer(bool center); + bool m_valid; TQPixmap m_icon; @@ -382,6 +392,7 @@ private: bool m_highlight; bool m_changeCursorOverItem; bool m_hasAcceptedDrag; + bool m_centerInContainer; TQColor m_textColor; TQColor m_tileColor; TQString m_buttonText; diff --git a/kicker/taskbar/taskbar.cpp b/kicker/taskbar/taskbar.cpp index 1e27050f3..40cc04fe1 100644 --- a/kicker/taskbar/taskbar.cpp +++ b/kicker/taskbar/taskbar.cpp @@ -1295,3 +1295,72 @@ void TaskBar::sortContainersByDesktop(TaskContainer::List& list) } } +int TaskBar::taskMoveHandler(const TQPoint &pos, Task::List taskList) { + TaskContainer* movingContainer = NULL; + TaskContainer* destContainer = NULL; + bool movingRight = true; + + TaskContainer::Iterator it = containers.begin(); + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + if (c->taskList() == taskList) { + movingContainer = c; + break; + } + } + + if (movingContainer) { + // Find the best place for the container to go... + it = containers.begin(); + for (; it != containers.end(); ++it) + { + TaskContainer* c = *it; + TQPoint containerPos = c->pos(); + TQSize containerSize = c->size(); + TQRect containerRect(containerPos.x(), containerPos.y(), containerSize.width(), containerSize.height()); + if (containerRect.contains(pos)) { + destContainer = c; + // Figure out if the mobile container is moving towards the end of the container list (i.e. right or down) + for (; it != containers.end(); ++it) + { + if (movingContainer == (*it)) { + movingRight = false; + } + } + break; + } + } + + if (destContainer == movingContainer) { + return false; + } + + removeChild(movingContainer); + containers.remove(movingContainer); + + if (destContainer) { + it = containers.find(destContainer); + if ((it != containers.end()) && (movingRight)) { + it++; + } + if (it != containers.end()) { + containers.insert(it, movingContainer); + } + else { + containers.append(movingContainer); + } + } + else { + containers.append(movingContainer); + } + + addChild(movingContainer); + reLayoutEventually(); + emit containerCountChanged(); + + return true; + } + + return false; +} \ No newline at end of file diff --git a/kicker/taskbar/taskbar.h b/kicker/taskbar/taskbar.h index afb59c365..f12ee895d 100644 --- a/kicker/taskbar/taskbar.h +++ b/kicker/taskbar/taskbar.h @@ -65,6 +65,8 @@ public: KTextShadowEngine *textShadowEngine(); + int taskMoveHandler(const TQPoint &pos, Task::List taskList); + public slots: void configure(); void setBackground(); diff --git a/kicker/taskbar/taskbar.kcfg b/kicker/taskbar/taskbar.kcfg index b87c32eaf..320b8a2d6 100644 --- a/kicker/taskbar/taskbar.kcfg +++ b/kicker/taskbar/taskbar.kcfg @@ -11,6 +11,11 @@ Turning this option off will cause the taskbar to ignore the global taskbar configuration, instead using a specific configuration for that particular taskbar. + + true + + Turning this option on will allow tasks on the taskbar to be manually rearranged using drag and drop. + true diff --git a/kicker/taskbar/taskbarcontainer.cpp b/kicker/taskbar/taskbarcontainer.cpp index 5a75f7c15..030a565dc 100644 --- a/kicker/taskbar/taskbarcontainer.cpp +++ b/kicker/taskbar/taskbarcontainer.cpp @@ -74,6 +74,8 @@ TaskBarContainer::TaskBarContainer( bool enableFrame, TQString configFileOverrid settingsObject = new TaskBarSettings(TDESharedConfig::openConfig(configFile)); globalSettingsObject = new TaskBarSettings(TDESharedConfig::openConfig(GLOBAL_TASKBAR_CONFIG_FILE_NAME)); + setAcceptDrops(true); // Always enabled to activate task during drag&drop. + setBackgroundOrigin( AncestorOrigin ); uint margin; @@ -327,3 +329,42 @@ void TaskBarContainer::setBackground() { taskBar->setBackground(); } + +void TaskBarContainer::dragEnterEvent( TQDragEnterEvent* e ) +{ + // ignore all drags other than tasks + if (!TaskDrag::canDecode(e)) + { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + e->accept(); + } + } +} + +void TaskBarContainer::dragLeaveEvent( TQDragLeaveEvent* e ) +{ + TQFrame::dragLeaveEvent( e ); +} + +void TaskBarContainer::dropEvent( TQDropEvent* e ) +{ + // ignore all drags other than tasks + if (!TaskDrag::canDecode(e)) + { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + if (taskBar->taskMoveHandler(taskBar->mapFrom(this, e->pos()), TaskDrag::decode(e))) { + e->accept(); + } + } + } +} \ No newline at end of file diff --git a/kicker/taskbar/taskbarcontainer.h b/kicker/taskbar/taskbarcontainer.h index fb5f26dd1..7fc13241f 100644 --- a/kicker/taskbar/taskbarcontainer.h +++ b/kicker/taskbar/taskbarcontainer.h @@ -52,6 +52,11 @@ public: TQSize sizeHint( KPanelExtension::Position, TQSize maxSize ) const; void setBackground(); +protected: + void dragEnterEvent(TQDragEnterEvent*); + void dragLeaveEvent(TQDragLeaveEvent*); + void dropEvent(TQDropEvent*); + k_dcop: void configChanged(); diff --git a/kicker/taskbar/taskcontainer.cpp b/kicker/taskbar/taskcontainer.cpp index d63166bb8..484a85659 100644 --- a/kicker/taskbar/taskcontainer.cpp +++ b/kicker/taskbar/taskcontainer.cpp @@ -1393,12 +1393,19 @@ void TaskContainer::publishIconGeometry( TQPoint global ) void TaskContainer::dragEnterEvent( TQDragEnterEvent* e ) { - // ignore task drags and applet drags - if (TaskDrag::canDecode(e) || PanelDrag::canDecode(e)) + // ignore applet drags + if (PanelDrag::canDecode(e)) { return; } + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + e->accept(); + } + } + // if a dragitem is held for over a taskbutton for two seconds, // activate corresponding window if (m_filteredTasks.isEmpty()) @@ -1415,6 +1422,27 @@ void TaskContainer::dragEnterEvent( TQDragEnterEvent* e ) TQToolButton::dragEnterEvent( e ); } +void TaskContainer::dropEvent( TQDropEvent* e ) +{ + // Ignore all drops except tasks + if (!TaskDrag::canDecode(e)) { + return; + } + + if (TaskDrag::canDecode(e) && READ_MERGED_TASBKAR_SETTING(allowDragAndDropReArrange)) + { + if (!READ_MERGED_TASBKAR_SETTING(sortByApp)) { + if (taskBar->taskMoveHandler(TQWidget::mapTo(taskBar, e->pos()), TaskDrag::decode(e))) { + e->accept(); + } + } + } + + dragSwitchTimer.stop(); + + TQToolButton::dropEvent( e ); +} + void TaskContainer::dragLeaveEvent( TQDragLeaveEvent* e ) { dragSwitchTimer.stop(); diff --git a/kicker/taskbar/taskcontainer.h b/kicker/taskbar/taskcontainer.h index b7016477e..857cd6c45 100644 --- a/kicker/taskbar/taskcontainer.h +++ b/kicker/taskbar/taskcontainer.h @@ -87,9 +87,11 @@ public: void updateKickerTip(KickerTip::Data&); void finish(); - + void setBackground(); - + + Task::List taskList() const { return tasks; } + public slots: void updateNow(); @@ -105,6 +107,7 @@ protected: void mouseMoveEvent(TQMouseEvent*); void dragEnterEvent(TQDragEnterEvent*); void dragLeaveEvent(TQDragLeaveEvent*); + void dropEvent(TQDropEvent*); void enterEvent(TQEvent*); void leaveEvent(TQEvent*); bool startDrag(const TQPoint& pos);