Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add placeholder for uiEntry and uiEditableCombobox #224

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

matyalatte
Copy link
Contributor

@matyalatte matyalatte commented Sep 16, 2023

Related to #218
This PR will add placeholders for uiEntry and uiEditableCombobox.
For Windows, you can also use uiWindows*Placeholder functions for other edit controls and combobox controls.

Added functions
- uiEntryPlaceholder, uiEntrySetPlaceholder
- uiEditableComboboxPlaceholder, uiEditableComboboxSetPlaceholder
- uiWindowsEntryPlaceholder, uiWindowsSetEntryPlaceholder
- uiWindowsComboboxPlaceholder, uiWindowsSetComboboxPlaceholder
@matyalatte
Copy link
Contributor Author

Here is a custom version of the controlgallery.
controlgallery.zip

You can see the placeholders on the example app.
And you can see the placeholder's text on the cosole.
entries
editablecombo
read-only
stdout

@cody271
Copy link
Contributor

cody271 commented Sep 16, 2023

Here is a custom version of the controlgallery.
controlgallery.zip

Please try to keep all contributions inside version control. Passing around source files like that is not recommended!

@cody271
Copy link
Contributor

cody271 commented Sep 16, 2023

We should add placeholders to controlgallery, but keep it simple:

diff --git a/examples/controlgallery/main.c b/examples/controlgallery/main.c
index 6415e4ff..e6cc9a48 100644
--- a/examples/controlgallery/main.c
+++ b/examples/controlgallery/main.c
@@ -54,14 +54,18 @@ static uiControl *makeBasicControlsPage(void)
 	uiFormSetPadded(entryForm, 1);
 	uiGroupSetChild(group, uiControl(entryForm));
 
+	uiEntry* entry = uiNewEntry();
+	uiEntrySetPlaceholder(entry, "Type here");
 	uiFormAppend(entryForm,
 		"Entry",
-		uiControl(uiNewEntry()),
+		uiControl(entry),
 		0);
+
 	uiFormAppend(entryForm,
 		"Password Entry",
 		uiControl(uiNewPasswordEntry()),
 		0);
+
 	uiFormAppend(entryForm,
 		"Search Entry",
 		uiControl(uiNewSearchEntry()),
@@ -147,6 +151,7 @@ static uiControl *makeNumbersPage()
 	uiEditableComboboxAppend(ecbox, "Editable Item 1");
 	uiEditableComboboxAppend(ecbox, "Editable Item 2");
 	uiEditableComboboxAppend(ecbox, "Editable Item 3");
+	uiEditableComboboxSetPlaceholder(ecbox, "Select an item");
 	uiBoxAppend(vbox, uiControl(ecbox), 0);
 
 	rb = uiNewRadioButtons();
@@ -264,6 +269,7 @@ static uiControl *makeDataChoosersPage(void)
 
 	button = uiNewButton("  Open File  ");
 	entry = uiNewEntry();
+	uiEntrySetPlaceholder(entry, "Select a file");
 	uiEntrySetReadOnly(entry, 1);
 	uiButtonOnClicked(button, onOpenFileClicked, entry);
 	uiGridAppend(grid, uiControl(button),

@cody271
Copy link
Contributor

cody271 commented Sep 16, 2023

stdout

These sorts of checks should be added to the test suite, instead of the examples.

@matyalatte
Copy link
Contributor Author

matyalatte commented Sep 16, 2023

Please try to keep all contributions inside version control.

It's just for testing setter and getter methods on the GUI. so I thought it shouldn't be added to the PR.

We should add placeholders to controlgallery, but keep it simple:

ok. I'll add another commit for it.

ui_windows.h Outdated Show resolved Hide resolved
ui.h Outdated
* @param text Placeholder text.\n
* A valid, `NUL` terminated UTF-8 string.\n
* Data is copied internally. Ownership is not transferred.
* @warning Read-only entries can't not display the placeholder on Windows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this limitation can be fixed, I will try the Windows implementation next.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have confirmed that it is a limitation of Win32 API that EM_SETCUEBANNER doesn't support read only entries or multi-line entries!

@cody271
Copy link
Contributor

cody271 commented Sep 18, 2023

Might as well add multi-line entry support now?
As the Unix/Darwin part is simple to implement. Underlying Windows implementation here is broken anyway.

Make a new issue specific to Windows (to keep track of it), then we can move on for now. It can be fixed in a later PR..

Copy link
Contributor

@cody271 cody271 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: functions private, not fucntions private.

Copy link
Contributor

@szanni szanni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have so far only checked uiEntry and added a few more test cases - one of which crashes hard on all platforms.

From an API perspective it is the question of what the default value of uiEntryPlaceholder should be. An empty string or NULL?
And do we want to support the setting of NULL or do we unset via an empty string?

I haven't checked but the crash on all three platforms suggests they return some type of NULL value initially. The test I added expects an empty string, as that is what uiEntryText returns by default.
I am not entirely opposed to NULL values either. The docs would need to be changed to reflect that though.

I would love to also have a qa test for the interaction of read only and placeholder text.
And I would wouldn't mind having two different PRs for uiEntry and uiCombobox as this is a lot of code - I do understand they have a fair amount of overlap though on win32.

ui.h Outdated
* @param text Placeholder text.\n
* A valid, `NUL` terminated UTF-8 string.\n
* Data is copied internally. Ownership is not transferred.
* @warning Read-only entries can't not display the placeholder on Windows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @warning Read-only entries can't not display the placeholder on Windows
* @warning Read only entries do not display the placeholder text on Windows.

Spelling and consistent punctuation.

And I confirmed as well that EM_SETCUEBANNER does not play nice with ES_READONLY.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read-only -> Read only

I can see some comments that use "read-only" in the repo. (e.g. windows/multilineentry.cpp)
But should I use "Read only" in the document?

can't -> do

I thought I fixed it already but I seemed to revert it somehow...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed at 3302ef9

@@ -123,6 +140,7 @@ int entryRunUnitTests(void)
entryUnitTests(entryTextDefault),
entryUnitTests(entrySetText),
entryUnitTests(entrySetTextNoCallback),
entryUnitTests(entrySetPlaceholder),
entryUnitTests(entryReadOnlyDefault),
entryUnitTests(entrySetReadOnly),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
entryUnitTests(entrySetReadOnly),
entryUnitTests(entrySetReadOnly),
entryUnitTests(entryReadOnlySetPlaceholder),
entryUnitTests(entryPlaceholderSetReadOnly),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And add the following two tests to line 87:

// win32: Make sure the placeholder gets set in read only mode, even though not visually displayed.
static void entryReadOnlySetPlaceholder(void **state)
{
	uiEntry **e = uiEntryPtrFromState(state);
	const char *text = "Text";
	char *rv;

	uiEntrySetReadOnly(*e, 1);
	uiEntrySetPlaceholder(*e, text);
	assert_int_equal(uiEntryReadOnly(*e), 1);
	rv = uiEntryPlaceholder(*e);
	assert_string_equal(rv, text);
	uiFreeText(rv);
}

// win32: Make sure the placeholder is retained and read only mode settable with a placeholder set.
static void entryPlaceholderSetReadOnly(void **state)
{
	uiEntry **e = uiEntryPtrFromState(state);
	const char *text = "Text";
	char *rv;

	uiEntrySetPlaceholder(*e, text);

	uiEntrySetReadOnly(*e, 1);
	assert_int_equal(uiEntryReadOnly(*e), 1);
	rv = uiEntryPlaceholder(*e);
	assert_string_equal(rv, text);
	uiFreeText(rv);

	uiEntrySetReadOnly(*e, 0);
	assert_int_equal(uiEntryReadOnly(*e), 0);
	rv = uiEntryPlaceholder(*e);
	assert_string_equal(rv, text);
	uiFreeText(rv);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed I don't need to edit windows/entry.cpp to pass these tests.
I mean, EM_SETCUEBANNER works internally with ES_READONLY.
I made another branch to test them but it passed the CI worklfow.

@@ -51,6 +51,23 @@ static void entrySetTextNoCallback(void **state)
uiEntrySetText(*e, "Text 2");
}

static void entrySetPlaceholder(void **state)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static void entrySetPlaceholder(void **state)
static void entryPlaceholderDefault(void **state)
{
uiEntry **e = uiEntryPtrFromState(state);
const char *text = "";
char *rv;
rv = uiEntryPlaceholder(*e);
assert_string_equal(rv, text);
uiFreeText(rv);
}
static void entrySetPlaceholder(void **state)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This currently crashes on all platforms and needs fixing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed at ac3ce07

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the other functions are prefixed with uipriv. Do we wan't to specify any rules around this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other functions just predate the policy change. Original discussion here:

andlabs/libui#308

  • prefix all non-public names that aren't static with uipriv

@cody271 cody271 linked an issue Sep 22, 2023 that may be closed by this pull request
@matyalatte
Copy link
Contributor Author

Might as well add multi-line entry support now?

It requires WM_* events to catch focus events and to change the text color.
So, I think we should work on the event handling features first.
like uiEntryOnFocused, uiEntrySetTextColor, etc.

Make a new issue specific to Windows (to keep track of it), then we can move on for now. It can be fixed in a later PR.

Ok, I'll make another issue like "Read only entries do not display placeholders on Windows" after this PR is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Enhancement] Placeholders for Text Entries
3 participants