mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-03 21:46:20 +00:00
Add right-click to ui::Entry to show edit popup menu (cut/copy/paste)
This commit is contained in:
parent
3704cb0ae4
commit
7d89167e00
@ -144,7 +144,7 @@ protected:
|
||||
menu->addChild(item);
|
||||
|
||||
const gfx::Rect& bounds = m_selectFile.getBounds();
|
||||
menu->showPopup(bounds.x, bounds.y+bounds.h);
|
||||
menu->showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
|
||||
}
|
||||
|
||||
void onUseCurrentSprite()
|
||||
|
@ -292,7 +292,7 @@ void MainWindow::clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons
|
||||
if (buttons & kButtonRight) {
|
||||
Menu* popup_menu = AppMenus::instance()->getDocumentTabPopupMenu();
|
||||
if (popup_menu != NULL) {
|
||||
popup_menu->showPopup(jmouse_x(0), jmouse_y(0));
|
||||
popup_menu->showPopup(ui::get_mouse_position());
|
||||
}
|
||||
}
|
||||
// Middle-button: close the sprite
|
||||
|
@ -88,9 +88,9 @@ void Notifications::onClick(ui::Event& ev)
|
||||
invalidate();
|
||||
|
||||
gfx::Rect bounds = getBounds();
|
||||
m_popup.showPopup(
|
||||
bounds.x - m_popup.getPreferredSize().w,
|
||||
bounds.y + bounds.h);
|
||||
m_popup.showPopup(gfx::Point(
|
||||
bounds.x - m_popup.getPreferredSize().w,
|
||||
bounds.y + bounds.h));
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -670,10 +670,8 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||
if (mouseMsg->right()) {
|
||||
if (m_clk_frame == m_hot_frame) {
|
||||
Menu* popup_menu = AppMenus::instance()->getFramePopupMenu();
|
||||
if (popup_menu != NULL) {
|
||||
gfx::Point mousePos = mouseMsg->position();
|
||||
popup_menu->showPopup(mousePos.x, mousePos.y);
|
||||
}
|
||||
if (popup_menu)
|
||||
popup_menu->showPopup(mouseMsg->position());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -683,10 +681,8 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||
if (mouseMsg->right()) {
|
||||
if (m_clk_layer == m_hot_layer) {
|
||||
Menu* popup_menu = AppMenus::instance()->getLayerPopupMenu();
|
||||
if (popup_menu != NULL) {
|
||||
gfx::Point mousePos = mouseMsg->position();
|
||||
popup_menu->showPopup(mousePos.x, mousePos.y);
|
||||
}
|
||||
if (popup_menu != NULL)
|
||||
popup_menu->showPopup(mouseMsg->position());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -721,10 +717,8 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||
AppMenus::instance()->getCelMovementPopupMenu():
|
||||
AppMenus::instance()->getCelPopupMenu();
|
||||
|
||||
if (popup_menu != NULL) {
|
||||
gfx::Point mousePos = mouseMsg->position();
|
||||
popup_menu->showPopup(mousePos.x, mousePos.y);
|
||||
}
|
||||
if (popup_menu)
|
||||
popup_menu->showPopup(mouseMsg->position());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
118
src/ui/entry.cpp
118
src/ui/entry.cpp
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013 David Capello
|
||||
// Copyright (C) 2001-2014 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -14,21 +14,33 @@
|
||||
#include "she/font.h"
|
||||
#include "ui/clipboard.h"
|
||||
#include "ui/manager.h"
|
||||
#include "ui/menu.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/preferred_size_event.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/theme.h"
|
||||
#include "ui/widget.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
|
||||
namespace ui {
|
||||
|
||||
Entry::Entry(size_t maxsize, const char *format, ...)
|
||||
: Widget(kEntryWidget)
|
||||
, m_timer(500, this)
|
||||
, m_maxsize(maxsize)
|
||||
, m_caret(0)
|
||||
, m_scroll(0)
|
||||
, m_select(0)
|
||||
, m_hidden(false)
|
||||
, m_state(false)
|
||||
, m_readonly(false)
|
||||
, m_password(false)
|
||||
, m_recent_focused(false)
|
||||
, m_lock_selection(false)
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
@ -44,18 +56,8 @@ Entry::Entry(size_t maxsize, const char *format, ...)
|
||||
buf[0] = 0;
|
||||
}
|
||||
|
||||
m_maxsize = maxsize;
|
||||
m_caret = 0;
|
||||
m_scroll = 0;
|
||||
m_select = 0;
|
||||
m_hidden = false;
|
||||
m_state = false;
|
||||
m_password = false;
|
||||
m_readonly = false;
|
||||
m_recent_focused = false;
|
||||
|
||||
/* TODO support for text alignment and multi-line */
|
||||
/* widget->align = JI_LEFT | JI_MIDDLE; */
|
||||
// TODO support for text alignment and multi-line
|
||||
// widget->align = JI_LEFT | JI_MIDDLE;
|
||||
setText(buf);
|
||||
|
||||
setFocusStop(true);
|
||||
@ -194,8 +196,13 @@ bool Entry::onProcessMessage(Message* msg)
|
||||
m_state = true;
|
||||
invalidate();
|
||||
|
||||
selectText(0, -1);
|
||||
m_recent_focused = true;
|
||||
if (m_lock_selection) {
|
||||
m_lock_selection = false;
|
||||
}
|
||||
else {
|
||||
selectAllText();
|
||||
m_recent_focused = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFocusLeaveMessage:
|
||||
@ -203,14 +210,16 @@ bool Entry::onProcessMessage(Message* msg)
|
||||
|
||||
m_timer.stop();
|
||||
|
||||
deselectText();
|
||||
if (!m_lock_selection)
|
||||
deselectText();
|
||||
|
||||
m_recent_focused = false;
|
||||
break;
|
||||
|
||||
case kKeyDownMessage:
|
||||
if (hasFocus() && !isReadOnly()) {
|
||||
// Command to execute
|
||||
EntryCmd::Type cmd = EntryCmd::NoOp;
|
||||
EntryCmd cmd = EntryCmd::NoOp;
|
||||
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
|
||||
KeyScancode scancode = keymsg->scancode();
|
||||
|
||||
@ -333,24 +342,27 @@ bool Entry::onProcessMessage(Message* msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Move caret
|
||||
if (move) {
|
||||
c = getCaretFromMouse(static_cast<MouseMessage*>(msg));
|
||||
c = getCaretFromMouse(static_cast<MouseMessage*>(msg));
|
||||
|
||||
if (m_caret != c) {
|
||||
m_caret = c;
|
||||
is_dirty = true;
|
||||
invalidate();
|
||||
if (static_cast<MouseMessage*>(msg)->left() ||
|
||||
(move && !isPosInSelection(c))) {
|
||||
// Move caret
|
||||
if (move) {
|
||||
if (m_caret != c) {
|
||||
m_caret = c;
|
||||
is_dirty = true;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move selection
|
||||
if (m_recent_focused) {
|
||||
m_recent_focused = false;
|
||||
m_select = m_caret;
|
||||
// Move selection
|
||||
if (m_recent_focused) {
|
||||
m_recent_focused = false;
|
||||
m_select = m_caret;
|
||||
}
|
||||
else if (msg->type() == kMouseDownMessage)
|
||||
m_select = m_caret;
|
||||
}
|
||||
else if (msg->type() == kMouseDownMessage)
|
||||
m_select = m_caret;
|
||||
|
||||
// Show the caret
|
||||
if (is_dirty) {
|
||||
@ -363,8 +375,18 @@ bool Entry::onProcessMessage(Message* msg)
|
||||
break;
|
||||
|
||||
case kMouseUpMessage:
|
||||
if (hasCapture())
|
||||
if (hasCapture()) {
|
||||
releaseMouse();
|
||||
|
||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||
if (mouseMsg->right()) {
|
||||
// This flag is disabled in kFocusEnterMessage message handler.
|
||||
m_lock_selection = true;
|
||||
|
||||
showEditPopupMenu(mouseMsg->position());
|
||||
requestFocus();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case kDoubleClickMessage:
|
||||
@ -376,7 +398,7 @@ bool Entry::onProcessMessage(Message* msg)
|
||||
|
||||
case kMouseEnterMessage:
|
||||
case kMouseLeaveMessage:
|
||||
/* TODO theme stuff */
|
||||
// TODO theme stuff
|
||||
if (isEnabled())
|
||||
invalidate();
|
||||
break;
|
||||
@ -461,7 +483,7 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
|
||||
return caret;
|
||||
}
|
||||
|
||||
void Entry::executeCmd(EntryCmd::Type cmd, int unicodeChar, bool shift_pressed)
|
||||
void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
|
||||
{
|
||||
std::wstring text = base::from_utf8(getText());
|
||||
int c, selbeg, selend;
|
||||
@ -693,4 +715,30 @@ int Entry::getAvailableTextLength()
|
||||
return getClientChildrenBounds().w / getFont()->charWidth('w');
|
||||
}
|
||||
|
||||
bool Entry::isPosInSelection(int pos)
|
||||
{
|
||||
return (pos >= MIN(m_caret, m_select) && pos <= MAX(m_caret, m_select));
|
||||
}
|
||||
|
||||
void Entry::showEditPopupMenu(const gfx::Point& pt)
|
||||
{
|
||||
Menu menu;
|
||||
MenuItem cut("Cut");
|
||||
MenuItem copy("Copy");
|
||||
MenuItem paste("Paste");
|
||||
menu.addChild(&cut);
|
||||
menu.addChild(©);
|
||||
menu.addChild(&paste);
|
||||
cut.Click.connect(std::bind(&Entry::executeCmd, this, EntryCmd::Cut, 0, false));
|
||||
copy.Click.connect(std::bind(&Entry::executeCmd, this, EntryCmd::Copy, 0, false));
|
||||
paste.Click.connect(std::bind(&Entry::executeCmd, this, EntryCmd::Paste, 0, false));
|
||||
|
||||
if (isReadOnly()) {
|
||||
cut.setEnabled(false);
|
||||
paste.setEnabled(false);
|
||||
}
|
||||
|
||||
menu.showPopup(pt);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -56,40 +56,41 @@ namespace ui {
|
||||
virtual void onEntryChange();
|
||||
|
||||
private:
|
||||
struct EntryCmd {
|
||||
enum Type {
|
||||
NoOp,
|
||||
InsertChar,
|
||||
ForwardChar,
|
||||
ForwardWord,
|
||||
BackwardChar,
|
||||
BackwardWord,
|
||||
BeginningOfLine,
|
||||
EndOfLine,
|
||||
DeleteForward,
|
||||
DeleteBackward,
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
};
|
||||
enum class EntryCmd {
|
||||
NoOp,
|
||||
InsertChar,
|
||||
ForwardChar,
|
||||
ForwardWord,
|
||||
BackwardChar,
|
||||
BackwardWord,
|
||||
BeginningOfLine,
|
||||
EndOfLine,
|
||||
DeleteForward,
|
||||
DeleteBackward,
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
};
|
||||
|
||||
int getCaretFromMouse(MouseMessage* mousemsg);
|
||||
void executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed);
|
||||
void executeCmd(EntryCmd cmd, int ascii, bool shift_pressed);
|
||||
void forwardWord();
|
||||
void backwardWord();
|
||||
int getAvailableTextLength();
|
||||
bool isPosInSelection(int pos);
|
||||
void showEditPopupMenu(const gfx::Point& pt);
|
||||
|
||||
Timer m_timer;
|
||||
size_t m_maxsize;
|
||||
int m_caret;
|
||||
int m_scroll;
|
||||
int m_select;
|
||||
Timer m_timer;
|
||||
bool m_hidden : 1;
|
||||
bool m_state : 1; // show or not the text caret
|
||||
bool m_readonly : 1;
|
||||
bool m_password : 1;
|
||||
bool m_recent_focused : 1;
|
||||
bool m_hidden;
|
||||
bool m_state; // show or not the text caret
|
||||
bool m_readonly;
|
||||
bool m_password;
|
||||
bool m_recent_focused;
|
||||
bool m_lock_selection;
|
||||
std::string m_suffix;
|
||||
};
|
||||
|
||||
|
@ -266,7 +266,7 @@ bool MenuItem::hasSubmenu() const
|
||||
return (m_submenu && !m_submenu->getChildren().empty());
|
||||
}
|
||||
|
||||
void Menu::showPopup(int x, int y)
|
||||
void Menu::showPopup(const gfx::Point& pos)
|
||||
{
|
||||
// New window and new menu-box
|
||||
Window* window = new Window(Window::WithoutTitleBar);
|
||||
@ -285,8 +285,9 @@ void Menu::showPopup(int x, int y)
|
||||
window->remapWindow();
|
||||
|
||||
// Menubox position
|
||||
window->positionWindow(MID(0, x, ui::display_w()-window->getBounds().w),
|
||||
MID(0, y, ui::display_h()-window->getBounds().h));
|
||||
window->positionWindow(
|
||||
MID(0, pos.x, ui::display_w() - window->getBounds().w),
|
||||
MID(0, pos.y, ui::display_h() - window->getBounds().h));
|
||||
|
||||
// Set the focus to the new menubox
|
||||
Manager::getDefault()->setFocus(menubox);
|
||||
|
@ -26,7 +26,7 @@ namespace ui {
|
||||
Menu();
|
||||
~Menu();
|
||||
|
||||
void showPopup(int x, int y);
|
||||
void showPopup(const gfx::Point& pos);
|
||||
|
||||
// Returns the MenuItem that has as submenu this menu.
|
||||
MenuItem* getOwnerMenuItem() {
|
||||
|
Loading…
Reference in New Issue
Block a user