aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cocoa/PlatCocoa.mm75
-rw-r--r--doc/ScintillaDoc.html54
-rw-r--r--doc/ScintillaHistory.html3
-rw-r--r--gtk/PlatGTK.cxx40
-rw-r--r--include/Platform.h15
-rw-r--r--include/Scintilla.h1
-rw-r--r--include/Scintilla.iface1
-rw-r--r--qt/ScintillaEditBase/PlatQt.cpp38
-rw-r--r--src/ScintillaBase.cxx33
-rw-r--r--src/ScintillaBase.h5
-rw-r--r--win32/PlatWin.cxx32
11 files changed, 236 insertions, 61 deletions
diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm
index 6633f98ff..3dfaa13e2 100644
--- a/cocoa/PlatCocoa.mm
+++ b/cocoa/PlatCocoa.mm
@@ -1274,7 +1274,9 @@ static NSImage *ImageFromXPM(XPM *pxpm) {
namespace {
-// unnamed namespace hides IListBox interface
+// Unnamed namespace hides local IListBox interface.
+// IListBox is used to cross languages to send events from Objective C++
+// AutoCompletionDelegate and AutoCompletionDataSource to C++ ListBoxImpl.
class IListBox {
public:
@@ -1282,18 +1284,43 @@ public:
virtual NSImage *ImageForRow(NSInteger row) = 0;
virtual NSString *TextForRow(NSInteger row) = 0;
virtual void DoubleClick() = 0;
+ virtual void SelectionChange() = 0;
};
-} // unnamed namespace
+}
+
+//----------------- AutoCompletionDelegate ---------------------------------------------------------
+
+// AutoCompletionDelegate is an Objective C++ class so it can implement
+// NSTableViewDelegate and receive tableViewSelectionDidChange events.
+
+@interface AutoCompletionDelegate : NSObject <NSTableViewDelegate> {
+ IListBox *box;
+}
+
+@property IListBox *box;
+
+@end
+
+@implementation AutoCompletionDelegate
+
+@synthesize box;
+
+- (void) tableViewSelectionDidChange: (NSNotification *) notification {
+#pragma unused(notification)
+ if (box) {
+ box->SelectionChange();
+ }
+}
+
+@end
//----------------- AutoCompletionDataSource -------------------------------------------------------
-@interface AutoCompletionDataSource :
- NSObject
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
- <NSTableViewDataSource>
-#endif
-{
+// AutoCompletionDataSource provides data to display in the list box.
+// It is also the target of the NSTableView so it receives double clicks.
+
+@interface AutoCompletionDataSource : NSObject <NSTableViewDataSource> {
IListBox *box;
}
@@ -1400,10 +1427,10 @@ private:
NSTableColumn *colIcon;
NSTableColumn *colText;
AutoCompletionDataSource *ds;
+ AutoCompletionDelegate *acd;
LinesData ld;
- CallBackAction doubleClickAction;
- void *doubleClickActionData;
+ IListBoxDelegate *delegate;
public:
ListBoxImpl() :
@@ -1420,8 +1447,8 @@ public:
colIcon(nil),
colText(nil),
ds(nil),
- doubleClickAction(nullptr),
- doubleClickActionData(nullptr) {
+ acd(nil),
+ delegate(nullptr) {
images = [[NSMutableDictionary alloc] init];
}
~ListBoxImpl() override {
@@ -1445,9 +1472,8 @@ public:
void RegisterImage(int type, const char *xpm_data) override;
void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override;
void ClearRegisteredImages() override;
- void SetDoubleClickAction(CallBackAction action, void *data) override {
- doubleClickAction = action;
- doubleClickActionData = data;
+ void SetDelegate(IListBoxDelegate *lbDelegate) override {
+ delegate = lbDelegate;
}
void SetList(const char *list, char separator, char typesep) override;
@@ -1459,6 +1485,7 @@ public:
NSImage *ImageForRow(NSInteger row) override;
NSString *TextForRow(NSInteger row) override;
void DoubleClick() override;
+ void SelectionChange() override;
};
void ListBoxImpl::Create(Window & /*parent*/, int /*ctrlID*/, Scintilla::Point pt,
@@ -1494,6 +1521,9 @@ void ListBoxImpl::Create(Window & /*parent*/, int /*ctrlID*/, Scintilla::Point p
ds = [[AutoCompletionDataSource alloc] init];
ds.box = this;
table.dataSource = ds; // Weak reference
+ acd = [[AutoCompletionDelegate alloc] init];
+ [acd setBox: this];
+ table.delegate = acd;
scroller.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[winLB.contentView addSubview: scroller];
@@ -1568,6 +1598,7 @@ void ListBoxImpl::ReleaseViews() {
scroller = nil;
colIcon = nil;
colText = nil;
+ acd = nil;
ds = nil;
}
@@ -1694,8 +1725,16 @@ NSString *ListBoxImpl::TextForRow(NSInteger row) {
}
void ListBoxImpl::DoubleClick() {
- if (doubleClickAction) {
- doubleClickAction(doubleClickActionData);
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::doubleClick);
+ delegate->ListNotify(&event);
+ }
+}
+
+void ListBoxImpl::SelectionChange() {
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::selectionChange);
+ delegate->ListNotify(&event);
}
}
@@ -1703,6 +1742,8 @@ void ListBoxImpl::DoubleClick() {
//----------------- ListBox ------------------------------------------------------------------------
+// ListBox is implemented by the ListBoxImpl class.
+
ListBox::ListBox() {
}
diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html
index 805c39bf8..e43f2466c 100644
--- a/doc/ScintillaDoc.html
+++ b/doc/ScintillaDoc.html
@@ -7011,7 +7011,7 @@ struct SCNotification {
/* SCN_MARGINRIGHTCLICK, SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, */
/* SCN_CALLTIPCLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
/* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
- /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+ /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_AUTOCSELECTIONCHANGE */
int ch;
/* SCN_CHARADDED, SCN_KEY, SCN_AUTOCCOMPLETE, SCN_AUTOCSELECTION, */
@@ -7022,7 +7022,8 @@ struct SCNotification {
int modificationType; /* SCN_MODIFIED */
const char *text;
- /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
+ /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED, */
+ /* SCN_AUTOCSELECTIONCHANGE */
Sci_Position length; /* SCN_MODIFIED */
Sci_Position linesAdded; /* SCN_MODIFIED */
@@ -7033,7 +7034,7 @@ struct SCNotification {
int foldLevelNow; /* SCN_MODIFIED */
int foldLevelPrev; /* SCN_MODIFIED */
int margin; /* SCN_MARGINCLICK, SCN_MARGINRIGHTCLICK */
- int listType; /* SCN_USERLISTSELECTION */
+ int listType; /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTIONCHANGE */
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
@@ -7078,6 +7079,7 @@ struct SCNotification {
<a class="message" href="#SCN_FOCUSOUT">SCN_FOCUSOUT</a><br />
<a class="message" href="#SCN_AUTOCCOMPLETED">SCN_AUTOCCOMPLETED</a><br />
<a class="message" href="#SCN_MARGINRIGHTCLICK">SCN_MARGINRIGHTCLICK</a><br />
+ <a class="message" href="#SCN_AUTOCSELECTIONCHANGE">SCN_AUTOCSELECTIONCHANGE</a><br />
</code>
<p>The following <code>SCI_*</code> messages are associated with these notifications:</p>
@@ -7946,10 +7948,6 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
The user deleted a character while autocompletion list was active.
There is no other information in SCNotification.</p>
- <p><b id="SCN_FOCUSIN">SCN_FOCUSIN</b><br />
- <b id="SCN_FOCUSOUT">SCN_FOCUSOUT</b><br />
- <code>SCN_FOCUSIN</code> (2028) is fired when Scintilla receives focus and
- <code>SCN_FOCUSOUT</code> (2029) when it loses focus.</p>
<p><b id="SCN_AUTOCCOMPLETED">SCN_AUTOCCOMPLETED<br />
</b>This notification is generated after an autocompletion has inserted its
@@ -7958,6 +7956,48 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<a class="jump" href="#SCN_AUTOCSELECTION">SCN_AUTOCSELECTION</a></code>
notification.</p>
+ <p><b id="SCN_AUTOCSELECTIONCHANGE">SCN_AUTOCSELECTIONCHANGE<br />
+ </b>This notification is sent when items are highlighted in an autocompletion or user list.
+ The
+ <code>SCNotification</code> fields used are:</p>
+
+ <table class="standard" summary="User list notification">
+ <tbody>
+ <tr>
+ <th align="left">Field</th>
+
+ <th align="left">Usage</th>
+ </tr>
+ </tbody>
+
+ <tbody valign="top">
+ <tr>
+ <td align="left"><code>listType</code></td>
+
+ <td align="left">This is set to the <code>listType</code> parameter from the <a
+ class="message" href="#SCI_USERLISTSHOW"><code>SCI_USERLISTSHOW</code></a> message
+ or 0 for an autocompletion.</td>
+ </tr>
+
+ <tr>
+ <td align="left"><code>text</code></td>
+
+ <td align="left">The text of the selection.</td>
+ </tr>
+
+ <tr>
+ <td align="left"><code>position</code></td>
+
+ <td align="left">The position the list was displayed at.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p><b id="SCN_FOCUSIN">SCN_FOCUSIN</b><br />
+ <b id="SCN_FOCUSOUT">SCN_FOCUSOUT</b><br />
+ <code>SCN_FOCUSIN</code> (2028) is fired when Scintilla receives focus and
+ <code>SCN_FOCUSOUT</code> (2029) when it loses focus.</p>
+
<h2 id="Images">Images</h2>
<p>Two formats are supported for images used in margin markers and autocompletion lists, RGBA and XPM.</p>
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index dae985a07..4f0ebf066 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -536,6 +536,9 @@
Support dropped for GTK+ versions before 2.24.
</li>
<li>
+ An SCN_AUTOCSELECTIONCHANGE notification is sent when items are highlighted in an autocompletion or user list.
+ </li>
+ <li>
SciTE allows user.shortcuts to be defined with symbolic Scintilla messages like
'Ctrl+L|SCI_LINEDELETE|'.
</li>
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index 432fc9ea0..5252e890c 100644
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -1196,8 +1196,7 @@ class ListBoxX : public ListBox {
GtkCssProvider *cssProvider;
#endif
public:
- CallBackAction doubleClickAction;
- void *doubleClickActionData;
+ IListBoxDelegate *delegate;
ListBoxX() : widCached(0), frame(0), list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
renderer(0),
@@ -1206,7 +1205,7 @@ public:
#if GTK_CHECK_VERSION(3,0,0)
cssProvider(NULL),
#endif
- doubleClickAction(NULL), doubleClickActionData(NULL) {
+ delegate(nullptr) {
}
~ListBoxX() override {
if (pixhash) {
@@ -1243,10 +1242,7 @@ public:
void RegisterImage(int type, const char *xpm_data) override;
void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override;
void ClearRegisteredImages() override;
- void SetDoubleClickAction(CallBackAction action, void *data) override {
- doubleClickAction = action;
- doubleClickActionData = data;
- }
+ void SetDelegate(IListBoxDelegate *lbDelegate) override;
void SetList(const char *listText, char separator, char typesep) override;
};
@@ -1337,8 +1333,9 @@ static void small_scroller_init(SmallScroller *){}
static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
try {
ListBoxX* lb = static_cast<ListBoxX*>(p);
- if (ev->type == GDK_2BUTTON_PRESS && lb->doubleClickAction != NULL) {
- lb->doubleClickAction(lb->doubleClickActionData);
+ if (ev->type == GDK_2BUTTON_PRESS && lb->delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::doubleClick);
+ lb->delegate->ListNotify(&event);
return TRUE;
}
@@ -1348,6 +1345,20 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
return FALSE;
}
+static gboolean ButtonRelease(GtkWidget *, GdkEventButton* ev, gpointer p) {
+ try {
+ ListBoxX* lb = static_cast<ListBoxX*>(p);
+ if (ev->type != GDK_2BUTTON_PRESS && lb->delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::selectionChange);
+ lb->delegate->ListNotify(&event);
+ return TRUE;
+ }
+ } catch (...) {
+ // No pointer back to Scintilla to save status
+ }
+ return FALSE;
+}
+
/* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
@@ -1472,6 +1483,8 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, int) {
gtk_widget_show(widget);
g_signal_connect(G_OBJECT(widget), "button_press_event",
G_CALLBACK(ButtonPress), this);
+ g_signal_connect(G_OBJECT(widget), "button_release_event",
+ G_CALLBACK(ButtonRelease), this);
GtkWidget *top = gtk_widget_get_toplevel(static_cast<GtkWidget *>(parent.GetID()));
gtk_window_set_transient_for(GTK_WINDOW(static_cast<GtkWidget *>(wid)),
@@ -1747,6 +1760,11 @@ void ListBoxX::Select(int n) {
} else {
gtk_tree_selection_unselect_all(selection);
}
+
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::selectionChange);
+ delegate->ListNotify(&event);
+ }
}
int ListBoxX::GetSelection() {
@@ -1843,6 +1861,10 @@ void ListBoxX::ClearRegisteredImages() {
images.Clear();
}
+void ListBoxX::SetDelegate(IListBoxDelegate *lbDelegate) {
+ delegate = lbDelegate;
+}
+
void ListBoxX::SetList(const char *listText, char separator, char typesep) {
Clear();
int count = strlen(listText) + 1;
diff --git a/include/Platform.h b/include/Platform.h
index 570ba738b..3a6818192 100644
--- a/include/Platform.h
+++ b/include/Platform.h
@@ -397,6 +397,19 @@ private:
* Listbox management.
*/
+// ScintillaBase implements IListBoxDelegate to receive ListBoxEvents from a ListBox
+
+struct ListBoxEvent {
+ enum class EventType { selectionChange, doubleClick } event;
+ ListBoxEvent(EventType event_) : event(event_) {
+ }
+};
+
+class IListBoxDelegate {
+public:
+ virtual void ListNotify(ListBoxEvent *plbe)=0;
+};
+
class ListBox : public Window {
public:
ListBox();
@@ -420,7 +433,7 @@ public:
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0;
- virtual void SetDoubleClickAction(CallBackAction, void *)=0;
+ virtual void SetDelegate(IListBoxDelegate *lbDelegate)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;
};
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 58643a8d9..6f18af9a9 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -1102,6 +1102,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_FOCUSOUT 2029
#define SCN_AUTOCCOMPLETED 2030
#define SCN_MARGINRIGHTCLICK 2031
+#define SCN_AUTOCSELECTIONCHANGE 2032
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index f35206990..135be3b4e 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -4855,6 +4855,7 @@ evt void FocusIn=2028(void)
evt void FocusOut=2029(void)
evt void AutoCCompleted=2030(string text, int position, int ch, CompletionMethods listCompletionMethod)
evt void MarginRightClick=2031(int modifiers, int position, int margin)
+evt void AutoCSelectionChange=2032(int listType, string text, int position)
# There are no provisional APIs currently, but some arguments to SCI_SETTECHNOLOGY are provisional.
diff --git a/qt/ScintillaEditBase/PlatQt.cpp b/qt/ScintillaEditBase/PlatQt.cpp
index c8db3f864..4c7eba127 100644
--- a/qt/ScintillaEditBase/PlatQt.cpp
+++ b/qt/ScintillaEditBase/PlatQt.cpp
@@ -772,7 +772,7 @@ public:
const unsigned char *pixelsImage) override;
virtual void RegisterQPixmapImage(int type, const QPixmap& pm);
void ClearRegisteredImages() override;
- void SetDoubleClickAction(CallBackAction action, void *data) override;
+ void SetDelegate(IListBoxDelegate *lbDelegate) override;
void SetList(const char *list, char separator, char typesep) override;
private:
bool unicodeMode;
@@ -785,15 +785,16 @@ public:
explicit ListWidget(QWidget *parent);
virtual ~ListWidget();
- void setDoubleClickAction(CallBackAction action, void *data);
+ void setDelegate(IListBoxDelegate *lbDelegate);
+ void selectionChanged();
protected:
+ void mouseReleaseEvent(QMouseEvent * event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
QStyleOptionViewItem viewOptions() const override;
private:
- CallBackAction doubleClickAction;
- void *doubleClickActionData;
+ IListBoxDelegate *delegate;
};
@@ -946,6 +947,7 @@ void ListBoxImpl::Select(int n)
}
}
list->setCurrentRow(n);
+ list->selectionChanged();
}
int ListBoxImpl::GetSelection()
@@ -1014,10 +1016,10 @@ void ListBoxImpl::ClearRegisteredImages()
list->setIconSize(QSize(0, 0));
}
-void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data)
+void ListBoxImpl::SetDelegate(IListBoxDelegate *lbDelegate)
{
ListWidget *list = static_cast<ListWidget *>(wid);
- list->setDoubleClickAction(action, data);
+ list->setDelegate(lbDelegate);
}
void ListBoxImpl::SetList(const char *list, char separator, char typesep)
@@ -1059,24 +1061,36 @@ ListBox *ListBox::Allocate()
}
ListWidget::ListWidget(QWidget *parent)
-: QListWidget(parent), doubleClickAction(0), doubleClickActionData(0)
+: QListWidget(parent), delegate(0)
{}
ListWidget::~ListWidget() {}
-void ListWidget::setDoubleClickAction(CallBackAction action, void *data)
+void ListWidget::setDelegate(IListBoxDelegate *lbDelegate)
{
- doubleClickAction = action;
- doubleClickActionData = data;
+ delegate = lbDelegate;
+}
+
+void ListWidget::selectionChanged() {
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::selectionChange);
+ delegate->ListNotify(&event);
+ }
}
void ListWidget::mouseDoubleClickEvent(QMouseEvent * /* event */)
{
- if (doubleClickAction != 0) {
- doubleClickAction(doubleClickActionData);
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::doubleClick);
+ delegate->ListNotify(&event);
}
}
+void ListWidget::mouseReleaseEvent(QMouseEvent * /* event */)
+{
+ selectionChanged();
+}
+
QStyleOptionViewItem ListWidget::viewOptions() const
{
QStyleOptionViewItem result = QListWidget::viewOptions();
diff --git a/src/ScintillaBase.cxx b/src/ScintillaBase.cxx
index 3979354eb..2da142462 100644
--- a/src/ScintillaBase.cxx
+++ b/src/ScintillaBase.cxx
@@ -202,9 +202,15 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
return Editor::KeyCommand(iMessage);
}
-void ScintillaBase::AutoCompleteDoubleClick(void *p) {
- ScintillaBase *sci = static_cast<ScintillaBase *>(p);
- sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
+void ScintillaBase::ListNotify(ListBoxEvent *plbe) {
+ switch (plbe->event) {
+ case ListBoxEvent::EventType::selectionChange:
+ AutoCompleteSelection();
+ break;
+ case ListBoxEvent::EventType::doubleClick:
+ AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
+ break;
+ }
}
void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, int removeLen, const char *text, int textLen) {
@@ -293,7 +299,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
ac.lb->SetAverageCharWidth(aveCharWidth);
- ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
+ ac.lb->SetDelegate(this);
ac.SetList(list ? list : "");
@@ -340,6 +346,25 @@ void ScintillaBase::AutoCompleteMoveToCurrentWord() {
ac.Select(wordCurrent.c_str());
}
+void ScintillaBase::AutoCompleteSelection() {
+ int item = ac.GetSelection();
+ std::string selected;
+ if (item != -1) {
+ selected = ac.GetValue(item);
+ }
+
+ SCNotification scn = {};
+ scn.nmhdr.code = SCN_AUTOCSELECTIONCHANGE;
+ scn.message = 0;
+ scn.wParam = listType;
+ scn.listType = listType;
+ Sci::Position firstPos = ac.posStart - ac.startLen;
+ scn.position = firstPos;
+ scn.lParam = firstPos;
+ scn.text = selected.c_str();
+ NotifyParent(scn);
+}
+
void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
if (ac.IsFillUpChar(ch)) {
AutoCompleteCompleted(ch, SC_AC_FILLUP);
diff --git a/src/ScintillaBase.h b/src/ScintillaBase.h
index cd8a1f5a1..9b8f08ae3 100644
--- a/src/ScintillaBase.h
+++ b/src/ScintillaBase.h
@@ -18,7 +18,7 @@ class LexState;
/**
*/
-class ScintillaBase : public Editor {
+class ScintillaBase : public Editor, IListBoxDelegate {
protected:
/** Enumeration of commands and child windows. */
enum {
@@ -76,7 +76,8 @@ protected:
void AutoCompleteCharacterDeleted();
void AutoCompleteCompleted(char ch, unsigned int completionMethod);
void AutoCompleteMoveToCurrentWord();
- static void AutoCompleteDoubleClick(void *p);
+ void AutoCompleteSelection();
+ void ListNotify(ListBoxEvent *plbe) override;
void CallTipClick();
void CallTipShow(Point pt, const char *defn);
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 7a0385a27..72513b071 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -2042,8 +2042,7 @@ class ListBoxX : public ListBox {
unsigned int aveCharWidth;
Window *parent;
int ctrlID;
- CallBackAction doubleClickAction;
- void *doubleClickActionData;
+ IListBoxDelegate *delegate;
const char *widestItem;
unsigned int maxCharWidth;
int resizeHit;
@@ -2063,6 +2062,7 @@ class ListBoxX : public ListBox {
POINT MaxTrackSize() const;
void SetRedraw(bool on);
void OnDoubleClick();
+ void OnSelChange();
void ResizeToCursor();
void StartResize(WPARAM);
LRESULT NcHitTest(WPARAM, LPARAM) const;
@@ -2077,7 +2077,8 @@ class ListBoxX : public ListBox {
public:
ListBoxX() : lineHeight(10), fontCopy(0), technology(0), lb(0), unicodeMode(false),
desiredVisibleRows(9), maxItemCharacters(0), aveCharWidth(8),
- parent(NULL), ctrlID(0), doubleClickAction(NULL), doubleClickActionData(NULL),
+ parent(NULL), ctrlID(0),
+ delegate(nullptr),
widestItem(NULL), maxCharWidth(1), resizeHit(0), wheelDelta(0) {
}
~ListBoxX() override {
@@ -2103,10 +2104,7 @@ public:
void RegisterImage(int type, const char *xpm_data) override;
void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) override;
void ClearRegisteredImages() override;
- void SetDoubleClickAction(CallBackAction action, void *data) override {
- doubleClickAction = action;
- doubleClickActionData = data;
- }
+ virtual void SetDelegate(IListBoxDelegate *lbDelegate) override;
void SetList(const char *list, char separator, char typesep) override;
void Draw(DRAWITEMSTRUCT *pDrawItem);
LRESULT WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
@@ -2247,6 +2245,7 @@ void ListBoxX::Select(int n) {
SetRedraw(false);
CentreItem(n);
::SendMessage(lb, LB_SETCURSEL, n, 0);
+ OnSelChange();
SetRedraw(true);
}
@@ -2377,6 +2376,10 @@ void ListBoxX::AppendListItem(const char *text, const char *numword) {
}
}
+void ListBoxX::SetDelegate(IListBoxDelegate *lbDelegate) {
+ delegate = lbDelegate;
+}
+
void ListBoxX::SetList(const char *list, char separator, char typesep) {
// Turn off redraw while populating the list - this has a significant effect, even if
// the listbox is not visible.
@@ -2606,9 +2609,16 @@ LRESULT ListBoxX::NcHitTest(WPARAM wParam, LPARAM lParam) const {
}
void ListBoxX::OnDoubleClick() {
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::doubleClick);
+ delegate->ListNotify(&event);
+ }
+}
- if (doubleClickAction != NULL) {
- doubleClickAction(doubleClickActionData);
+void ListBoxX::OnSelChange() {
+ if (delegate) {
+ ListBoxEvent event(ListBoxEvent::EventType::selectionChange);
+ delegate->ListNotify(&event);
}
}
@@ -2683,6 +2693,10 @@ LRESULT PASCAL ListBoxX::ControlWndProc(HWND hWnd, UINT iMessage, WPARAM wParam,
int item = LOWORD(lResult);
if (HIWORD(lResult) == 0 && item >= 0) {
::SendMessage(hWnd, LB_SETCURSEL, item, 0);
+ ListBoxX *lbx = static_cast<ListBoxX *>(PointerFromWindow(::GetParent(hWnd)));
+ if (lbx) {
+ lbx->OnSelChange();
+ }
}
}
return 0;