mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 18:21:42 -05:00
Dragging text from FlatLabel is supported.
Started drag-n-drop support for chat photo updating.
This commit is contained in:
parent
ab59ef8498
commit
329285a8a6
6 changed files with 118 additions and 4 deletions
|
@ -457,6 +457,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
"lng_profile_shared_links_header" = "Shared links overview";
|
||||
"lng_profile_copy_phone" = "Copy phone number";
|
||||
"lng_profile_copy_fullname" = "Copy name";
|
||||
"lng_profile_drop_area_title" = "Drop your image here";
|
||||
"lng_profile_drop_area_subtitle" = "to set it as a group photo";
|
||||
|
||||
"lng_channel_add_admins" = "New administrator";
|
||||
"lng_channel_add_members" = "Add members";
|
||||
|
|
|
@ -76,6 +76,16 @@ profileSecondaryButton: BoxButton(profilePrimaryButton) {
|
|||
textBgOver: #f2f7fa;
|
||||
}
|
||||
|
||||
profileDropAreaBg: profileBg;
|
||||
profileDropAreaFg: #3fb0e4;
|
||||
profileDropAreaPadding: margins(30px, 20px, 30px, 20px);
|
||||
profileDropAreaTitleFont: font(24px);
|
||||
profileDropAreaTitleTop: 36px;
|
||||
profileDropAreaSubtitleFont: font(16px);
|
||||
profileDropAreaSubtitleTop: 72px;
|
||||
profileDropAreaBorderFg: profileDropAreaFg;
|
||||
profileDropAreaBorderWidth: 3px;
|
||||
|
||||
profileDividerFg: black;
|
||||
profileDividerLeft: icon {
|
||||
{ "profile_divider_left", profileDividerFg },
|
||||
|
|
|
@ -123,6 +123,50 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class DropArea : public TWidget {
|
||||
public:
|
||||
DropArea(QWidget *parent) : TWidget(parent) {
|
||||
}
|
||||
|
||||
void showAnimated() {
|
||||
show();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override {
|
||||
Painter p(this);
|
||||
p.fillRect(e->rect(), st::profileDropAreaBg);
|
||||
|
||||
if (width() < st::profileDropAreaPadding.left() + st::profileDropAreaPadding.right()) return;
|
||||
if (height() < st::profileDropAreaPadding.top() + st::profileDropAreaPadding.bottom()) return;
|
||||
|
||||
auto border = st::profileDropAreaBorderWidth;
|
||||
auto &borderFg = st::profileDropAreaBorderFg;
|
||||
auto inner = rect().marginsRemoved(st::profileDropAreaPadding);
|
||||
p.fillRect(inner.x(), inner.y(), inner.width(), border, borderFg);
|
||||
p.fillRect(inner.x(), inner.y() + inner.height() - border, inner.width(), border, borderFg);
|
||||
p.fillRect(inner.x(), inner.y() + border, border, inner.height() - 2 * border, borderFg);
|
||||
p.fillRect(inner.x() + inner.width() - border, inner.y() + border, border, inner.height() - 2 * border, borderFg);
|
||||
|
||||
auto title = lang(lng_profile_drop_area_title);
|
||||
int titleWidth = st::profileDropAreaTitleFont->width(title);
|
||||
int titleLeft = inner.x() + (inner.width() - titleWidth) / 2;
|
||||
int titleTop = inner.y() + st::profileDropAreaTitleTop + st::profileDropAreaTitleFont->ascent;
|
||||
p.setFont(st::profileDropAreaTitleFont);
|
||||
p.setPen(st::profileDropAreaFg);
|
||||
p.drawText(titleLeft, titleTop, title);
|
||||
|
||||
auto subtitle = lang(lng_profile_drop_area_subtitle);
|
||||
int subtitleWidth = st::profileDropAreaSubtitleFont->width(subtitle);
|
||||
int subtitleLeft = inner.x() + (inner.width() - subtitleWidth) / 2;
|
||||
int subtitleTop = inner.y() + st::profileDropAreaSubtitleTop + st::profileDropAreaSubtitleFont->ascent;
|
||||
p.setFont(st::profileDropAreaSubtitleFont);
|
||||
p.setPen(st::profileDropAreaFg);
|
||||
p.drawText(subtitleLeft, subtitleTop, subtitle);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
|
||||
, _peer(peer)
|
||||
, _peerUser(peer->asUser())
|
||||
|
@ -132,6 +176,7 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
|
|||
, _photoButton(this, peer)
|
||||
, _name(this, QString(), st::profileNameLabel) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setAcceptDrops(true);
|
||||
|
||||
_name.setSelectable(true);
|
||||
_name.setContextCopyText(lang(lng_profile_copy_fullname));
|
||||
|
@ -204,6 +249,23 @@ void CoverWidget::paintEvent(QPaintEvent *e) {
|
|||
paintDivider(p);
|
||||
}
|
||||
|
||||
void CoverWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||
_dropArea = new DropArea(this);
|
||||
_dropArea->setGeometry(0, 0, width(), _dividerTop);
|
||||
_dropArea->showAnimated();
|
||||
e->accept();
|
||||
}
|
||||
|
||||
void CoverWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||
delete _dropArea;
|
||||
_dropArea = nullptr;
|
||||
}
|
||||
|
||||
void CoverWidget::dropEvent(QDropEvent *e) {
|
||||
delete _dropArea;
|
||||
_dropArea = nullptr;
|
||||
}
|
||||
|
||||
void CoverWidget::paintDivider(Painter &p) {
|
||||
st::profileDividerLeft.paint(p, QPoint(st::lineWidth, _dividerTop), width());
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Profile {
|
|||
|
||||
class BackButton;
|
||||
class PhotoButton;
|
||||
class DropArea;
|
||||
|
||||
class CoverWidget final : public TWidget, public Notify::Observer {
|
||||
Q_OBJECT
|
||||
|
@ -58,6 +59,9 @@ private slots:
|
|||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void dragEnterEvent(QDragEnterEvent *e) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
||||
void dropEvent(QDropEvent *e) override;
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
|
@ -85,8 +89,8 @@ private:
|
|||
ChannelData *_peerChannel;
|
||||
ChannelData *_peerMegagroup;
|
||||
|
||||
// Cover content
|
||||
ChildWidget<PhotoButton> _photoButton;
|
||||
ChildWidget<DropArea> _dropArea = { nullptr };
|
||||
|
||||
FlatLabel _name;
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton bu
|
|||
if (_dragWasInactive) App::wnd()->inactivePress(false);
|
||||
|
||||
if (ClickHandler::getPressed()) {
|
||||
_dragStartPosition = mapFromGlobal(_lastMousePos);
|
||||
_dragAction = PrepareDrag;
|
||||
}
|
||||
if (!_selectable || _dragAction != NoDrag) {
|
||||
|
@ -147,6 +148,7 @@ Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton bu
|
|||
}
|
||||
}
|
||||
if (uponSelected) {
|
||||
_dragStartPosition = mapFromGlobal(_lastMousePos);
|
||||
_dragAction = PrepareDrag; // start text drag
|
||||
} else if (!_dragWasInactive) {
|
||||
if (state.afterSymbol) ++_dragSymbol;
|
||||
|
@ -391,6 +393,33 @@ void FlatLabel::onContextMenuDestroy(QObject *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatLabel::onExecuteDrag() {
|
||||
if (_dragAction != Dragging) return;
|
||||
|
||||
auto state = getTextState(_dragStartPosition);
|
||||
bool uponSelected = state.uponSymbol && _selection.from <= state.symbol;
|
||||
if (uponSelected) {
|
||||
if (_dragSymbol < _selection.from || _dragSymbol >= _selection.to) {
|
||||
uponSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
ClickHandlerPtr pressedHandler = ClickHandler::getPressed();
|
||||
QString selectedText;
|
||||
if (uponSelected) {
|
||||
selectedText = _text.originalText(_selection, ExpandLinksAll);
|
||||
} else if (pressedHandler) {
|
||||
selectedText = pressedHandler->dragText();
|
||||
}
|
||||
if (!selectedText.isEmpty()) {
|
||||
auto mimeData = new QMimeData();
|
||||
mimeData->setText(selectedText);
|
||||
auto drag = new QDrag(App::wnd());
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec(Qt::CopyAction);
|
||||
}
|
||||
}
|
||||
|
||||
void FlatLabel::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
|
||||
update();
|
||||
}
|
||||
|
@ -400,10 +429,15 @@ void FlatLabel::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool a
|
|||
}
|
||||
|
||||
Text::StateResult FlatLabel::dragActionUpdate() {
|
||||
QPoint m(mapFromGlobal(_lastMousePos));
|
||||
LOG(("DRAG ACTION UPDATE: %1 %2").arg(m.x()).arg(m.y()));
|
||||
auto m = mapFromGlobal(_lastMousePos);
|
||||
auto state = getTextState(m);
|
||||
updateHover(state);
|
||||
|
||||
if (_dragAction == PrepareDrag && (m - _dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_dragAction = Dragging;
|
||||
QTimer::singleShot(1, this, SLOT(onExecuteDrag()));
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ private slots:
|
|||
void onTouchSelect();
|
||||
void onContextMenuDestroy(QObject *obj);
|
||||
|
||||
void onExecuteDrag();
|
||||
|
||||
private:
|
||||
Text::StateResult dragActionUpdate();
|
||||
Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button);
|
||||
|
@ -100,10 +102,10 @@ private:
|
|||
NoDrag = 0x00,
|
||||
PrepareDrag = 0x01,
|
||||
Dragging = 0x02,
|
||||
PrepareSelect = 0x03,
|
||||
Selecting = 0x04,
|
||||
};
|
||||
DragAction _dragAction = NoDrag;
|
||||
QPoint _dragStartPosition;
|
||||
uint16 _dragSymbol = 0;
|
||||
bool _dragWasInactive = false;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue