summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-11-05 13:35:39 -0500
committerPietro Gagliardi <[email protected]>2014-11-05 13:35:39 -0500
commitb632fef3b13dc082acbbbd8aaf6898c663da1c0b (patch)
treedb74e1e02e91e555b50e9ad6efd2eaafafae907f
parentcd96f8ee2e0a4ae3370a57357f9bcde4e2a8c36f (diff)
Implemented TextField.ReadOnly() on Mac OS X. Began standardizing window class name access on Windows.
-rw-r--r--basicctrls_darwin.m12
-rw-r--r--common_windows.c4
-rw-r--r--objc_darwin.h2
-rw-r--r--textfield_darwin.go10
-rw-r--r--uitask_windows.c11
-rw-r--r--winapi_windows.h7
6 files changed, 35 insertions, 11 deletions
diff --git a/basicctrls_darwin.m b/basicctrls_darwin.m
index 873882e..b91862e 100644
--- a/basicctrls_darwin.m
+++ b/basicctrls_darwin.m
@@ -136,6 +136,7 @@ id newTextField(void)
NSTextField *t;
t = [[NSTextField alloc] initWithFrame:NSZeroRect];
+ [t setSelectable:YES]; // otherwise the setting is masked by the editable default of YES
return finishNewTextField((id) t, YES);
}
@@ -144,6 +145,7 @@ id newPasswordField(void)
NSSecureTextField *t;
t = [[NSSecureTextField alloc] initWithFrame:NSZeroRect];
+ [t setSelectable:YES]; // otherwise the setting is masked by the editable default of YES
return finishNewTextField((id) t, YES);
}
@@ -184,6 +186,16 @@ void textfieldCloseInvalidPopover(id popover)
// don't release; close does that already
}
+BOOL textfieldEditable(id textfield)
+{
+ return [toNSTextField(textfield) isEditable];
+}
+
+void textfieldSetEditable(id textfield, BOOL editable)
+{
+ [toNSTextField(textfield) setEditable:editable];
+}
+
id newLabel(void)
{
NSTextField *l;
diff --git a/common_windows.c b/common_windows.c
index 207b691..9e67a0c 100644
--- a/common_windows.c
+++ b/common_windows.c
@@ -100,7 +100,7 @@ void paintControlBackground(HWND hwnd, HDC dc)
HWND parent;
RECT r;
POINT p, pOrig;
- WCHAR classname[128] = L""; // more than enough to avoid collisions
+ WCHAR classname[maxClassName + 1] = L"";
parent = hwnd;
for (;;) {
@@ -110,7 +110,7 @@ void paintControlBackground(HWND hwnd, HDC dc)
// wine sends these messages early, yay...
if (parent == msgwin)
return;
- if (GetClassNameW(parent, classname, 128) == 0)
+ if (GetClassNameW(parent, classname, maxClassName) == 0)
xpanic("error getting name of focused window class in paintControlBackground()", GetLastError());
// skip groupboxes; they're (supposed to be) transparent
if (_wcsicmp(classname, L"button") != 0)
diff --git a/objc_darwin.h b/objc_darwin.h
index 7ed69d1..e8b7752 100644
--- a/objc_darwin.h
+++ b/objc_darwin.h
@@ -75,6 +75,8 @@ extern const char *textfieldText(id);
extern void textfieldSetText(id, char *);
extern id textfieldOpenInvalidPopover(id, char *);
extern void textfieldCloseInvalidPopover(id);
+extern BOOL textfieldEditable(id);
+extern void textfieldSetEditable(id, BOOL);
extern id newLabel(void);
extern id newGroup(id);
extern const char *groupText(id);
diff --git a/textfield_darwin.go b/textfield_darwin.go
index bf63073..c61a1b9 100644
--- a/textfield_darwin.go
+++ b/textfield_darwin.go
@@ -62,6 +62,16 @@ func (t *textfield) Invalid(reason string) {
t.invalid = C.textfieldOpenInvalidPopover(t.id, creason)
}
+// note that the property here is editable, which is the opposite of read-only
+
+func (t *textfield) ReadOnly() bool {
+ return !fromBOOL(C.textfieldEditable(t.id))
+}
+
+func (t *textfield) SetReadOnly(readonly bool) {
+ C.textfieldSetEditable(t.id, toBOOL(!readonly))
+}
+
//export textfieldChanged
func textfieldChanged(data unsafe.Pointer) {
t := (*textfield)(data)
diff --git a/uitask_windows.c b/uitask_windows.c
index dec6ed2..49937c9 100644
--- a/uitask_windows.c
+++ b/uitask_windows.c
@@ -3,10 +3,6 @@
#include "winapi_windows.h"
#include "_cgo_export.h"
-// note that this includes the terminating '\0'
-// this also assumes WC_TABCONTROL is longer than areaWindowClass
-#define NCLASSNAME (sizeof WC_TABCONTROL / sizeof WC_TABCONTROL[0])
-
void uimsgloop_area(HWND active, HWND focus, MSG *msg)
{
MSG copy;
@@ -63,7 +59,7 @@ void uimsgloop(void)
MSG msg;
int res;
HWND active, focus;
- WCHAR classchk[NCLASSNAME];
+ WCHAR classchk[maxClassName + 1];
BOOL dodlgmessage;
for (;;) {
@@ -82,12 +78,9 @@ void uimsgloop(void)
// bit of logic involved here:
// we don't want dialog messages passed into Areas, so we don't call IsDialogMessageW() there
// as for Tabs, we can't have both WS_TABSTOP and WS_EX_CONTROLPARENT set at the same time, so we hotswap the two styles to get the behavior we want
- // theoretically we could use the class atom to avoid a wcscmp()
- // however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything)
- // we could also theoretically just send msgAreaDefocuses directly, but what DefWindowProc() does to a WM_APP message is undocumented
focus = GetFocus();
if (focus != NULL) {
- if (GetClassNameW(focus, classchk, NCLASSNAME) == 0)
+ if (GetClassNameW(focus, classchk, maxClassName) == 0)
xpanic("error getting name of focused window class for Area check", GetLastError());
if (_wcsicmp(classchk, areaWindowClass) == 0) {
uimsgloop_area(active, focus, &msg);
diff --git a/winapi_windows.h b/winapi_windows.h
index 9642397..db3b49e 100644
--- a/winapi_windows.h
+++ b/winapi_windows.h
@@ -41,6 +41,13 @@ enum {
msgOpenFileDone,
};
+// there are a number of places where we need to know what window class an arbitrary handle has
+// theoretically we could use the class atom to avoid a _wcsicmp()
+// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything)
+// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character)
+// TODO localize this to a helper function
+#define maxClassName 260
+
// uitask_windows.c
extern void uimsgloop(void);
extern void issue(void *);