How to go about implementing a custom TextView in GTK3? - gtk3

I would like to write a very simple text editor with a custom widget for drawing the text. I use GTK3. So far, I've come up with something like this:
Window -> Vertical Box -> Scrolled Window -> Drawing Area
The scrolled window fits the main window, as it is inside a vertical box. Depending on the size of the drawing area, the scrolled window shows the scroll bar. So far so good.
Now, there are several things I don't understand:
When the text doesn't fit the drawing area, how do I go about resizing the drawing area?
What is the best way of approaching the resizing when the text changes? One way I can think of is to simply handle key presses and count lines, but that doesn't seem right and probably won't work when lines wrap.
What events do I have to handle (and possibly propagate) for this to work?
I've tried searching the GTK docs, but they are very unhelpful in this regard. gtk3-demo doesn't really help, too. I know that there is https://developer.gnome.org/gtk3/stable/ch01s05.html, which describes the custom drawing a bit, but doesn't solve what I'm trying to do.
Update:
I figured out a lot by reading gedit, gtksourceview and gtk sources, which I wanted to avoid, but there seems to be no way around it.

Related

Available height to position UI elements assuming keyboard always shows

I am encountering a problem that I'm not sure how to solve. If you look at the screenshot below, you'll see that the UI is laid out so that it neatly fits into the space between the safe area layout guide's top anchor and the top of the keyboard.
The keyboard will ALWAYS be shown in this view controller. But I need a way of knowing what the height of the keyboard is so that I can do some math to figure out how to tall to make the UITextView (the red box).
I tried the approach of registering for notifications on when the keyboard will show, but that is too late.
I need a way of knowing the height of the keyboard before the view renders so that I can configure the height of each of the elements in the UI.
Is there a way to do this?
Thank you!
One option would be to capture the dimensions of the Keyboard when it IS presented then pass those dimensions into this view.
However, you will also want to make sure that you are handling cases such as the split keyboard on an iPad and things of that nature.
For that you might choose to look at the documentation on using the keyboardLayoutGuide and use it with some constraints.
https://developer.apple.com/documentation/uikit/keyboards_and_input/adjusting_your_layout_with_keyboard_layout_guide

How can I make a NSTextfield with left or right indicator for validation?

I need to make a custom NSTextField with an indicator like this:
https://i.stack.imgur.com/LAhfA.png
On the right side, you could see an indicator icon.
What code I need to make this?
Thanks for all.
EDIT
The text never could be overlap the icon. The icon is not always displayed, but it can be shown when it is being written and when the text is correct, this text must also occupy the position of the icon.
A text field control is a view where the drawing is all done with an NSTextFieldCell. What you'd need to do is subclass NSTextFieldCell, and customize the drawing. Look at NSCell's API and you'll see there's a drawWithFrame:inView: method which is what does all of the drawing for the entire field. Various other methods of NSCell are used in this process.
Unfortunately some of how the drawing is done is a bit private and not eeeasily fiddled with, but the main thing is drawWithFrame:inView: will draw the background and then call drawInteriorWithFrame:inView: to draw the text. Off the top of my head, I can't remember if NSTextFieldCell uses titleRectForBounds: to determine what the text's bounds are, but I'm pretty sure it is. So you could override that to return a narrower rectangle, leaving room to either draw the validation icon with the cell itself, or use a subview.
Additionally, you'll need to adjust the bounds in which the NSTextView field editor draws and edits the text, otherwise when you view the field while it is not first responder it will look fine, but when you edit the field's text it will overlap the icon. For that you may need to adjust the frame given to editWithFrame:inView:editor:delegate:event:.
It's always a bit finicky to tweak text fields because it takes a while to find all the methods and code paths involved, but that's the gist of what you need to do.

Turning scrollbar, ListView into timeline slider

I've been seeing this UI technique quite often at Dribbble, mostly demonstrated on iPhone as timeline, and I am really wondering if it's possible to do so on Android. The idea is to exploit scrollbar, make it activate each row it is passing.
Consider these schematics of a list of contact.
The first one is the list (photos on the left side, names on the right) split roughly in the middle with scroll track.
The scrollbar cannot expand and has to be smaller than the smallest row. I believe it is possible to produce this kind of arrangement by combining two listviews and make them roll together.
The second one shows the screen when scrolled and when the scrollbar moves to the second row. After it stops, the second row will expand its height. All hidden elements there like address, phone, etc will show up. Also, the moment the scrollbar leaves the first row / hits the second, the first row will toggle off. It will shrink and remove all elements except name.
I have been thinking about this scenario and one key question in this technique is whether the scrollbar has the ability to activate the row it hits. The only tool I know in regard to scrolling is onScrollListener but I wonder if it's sufficient. Does anyone have any insight into such scenario ?
Thank you in advance.
I've been seen something similar to this in lots of applications. Some of them are just using ListView with design tricks to look like that, others with custom views or something else. The idea which I have in my about this implementation is using two Fragments: left and right which are placed in one FragmentActivity. Left Fragment will be your image holder, where for example you will have a ListView or some other view depending on your choice which will communicate with the Right Fragment and when LeftFragment's ListView stop scrolling, fire an event to RightFragment's ListView to scroll to position 5 for example and expand that item. Not really sure if it's the best option and if it will work properly as you want, but that's the first idea which I can think of to do some implementation like this.
Hope this help you find the right answer.

How to highlight text in epub like ibooks app

I need to highlight text in epub book,when user selects the text,i can get the text,what the user has selected,but i need to highlight,the text permanently what user selected,thanks,any help will ne appreciated.
There's nothing built in to iOS that will do this. Some broad techniques that might work:
If you're showing the book in a web view, you might be able to wrap that area in a span and style it to create a highlight.
If you're using Core Text, you could draw the highlight in directly, either before or after drawing the text. (Your choice will decide how the highlight affects non-black text.)
You could add a transparent view over the text that draws in the highlight.
As for adding highlight-related items to the selection menu, see this Stack Overflow post. You probably won't be able to get icons in the menu like Apple does, though; that seems to be a private API. You could probably override the whole menu system if you want something closer to Apple's look, but that'll be quite a bit of work.

Easy way to scroll overflow text on a button?

Does anyone have any examples or resources where i might find information on scrolling text which is too long to display in a button control? I'm thinking something along these lines.
Display as much text will fit within the current rect with a '...' at the end to signify overflow.
Pause for say 1 second then slowly scroll the text to the right edge displaying the right part of the string.
Display as much text will fit within the current rect with a '...' at the beginning to signify overflow.
Start the whole thing over in reverse.
Is there an easy way to do this using the "core" or built in "animation" frameworks on a certain mobile device?
[edit]
Iwanted to add some more details as i think people are more focused on wether or not what i'm trying to accomplish is appropriate. The button is for the answers on a trivia game. It does not perform any speciffic UI function but is for displaying the answer. Apple themselves is doing this in their iQuiz trivia game on the iPod Nano and i think its a pretty elegant solution to answers that are longer than the width of my button.
In case its the '...' that is the difficult part of this. Lets say i removed this requirement. Could i have the label for the button be full sized but clipped to the client rect of the button and use some animation methods to scroll it within the clipping rect? This would give me almost the same effect minus the ellipses.
Here's an idea: instead of ellipses (...), use a gradient on each side, so the extra text fades away into the background color. Then you could do this with three CALayers: one for the text and two for fade effect.
The fade masks would just be rectangles with a gradient that goes from transparent to the background color. They should be positioned above the text layer. The text would be drawn on the text layer, and then you just animate it sliding back and forth in the manner you describe. You can create a CGPath object describing the path and add it to a CAKeyframeAnimation object which you add to the text layer.
As for whether you think this is "easy" depends on how well you know Core Animation, but I think once you learn the API you'll find this isn't too bad and would be worth the trouble.
Without wishing to be obtuse, maybe you should rethink your problem. A button should have a clear and predictable function. It's not a place to store and display text. Perhaps you could have a description show on screen with a nice standard button below?
Update with source code example:
Here is some ready to use source code example (actually a full zipped Xcode project with image and nib files and some source code), not for the iPhone, not using Core Animation, just using a couple of simple NSImages and a NSImageView. It is just a cheap hack, it does not implement the full functionality you requested (sorry, but I don't feel like writing your source code for you :-P), horrible code layout (hey, I just hacked this together within a couple of minutes, so you can't expect any better ;-)) and it's just a demonstration how this can be done. It can be done with Core Animation, too, but this approach is simpler. Composing the button animation into a NSImageView is not as nice as subclassing a NSView and directly paint to its context, but it's much simpler (I just wanted to hack together the simplest solution possible). It will also not scroll back once it scrolled all the way to the right. Therefor you just need another method to scroll back and start another NSTimer that fires 2 seconds after you drew the dots to the left.
Just open the project in Xcode and hit run, that's all there is to do. Then have a look at the source code. It's really not that complicated (however, you may have to reformat it first, the layout sucks).
Update because of comment to my answer:
If you don't use Apple UI elements at all, I fail to see the problem. In that case your button is not even a button, it's just a clickable View (NSView if you use Cocoa). You can just sub-class NSView as MyAnswerView and overwrite the paint method to paint into the view whatever you wish. Multiline text, scrolling text, 3D text animated, it's completely up to your imagination.
Here's an example, showing how someone subclassed NSView to create a complete custom control that does not exist by default. The control looks like this:
See the funny thing in the upper left corner? That is a control. Here's how it works:
I hate to say that, as it is no answer to your question, but "Don't do that!". Apple has guidelines how to implement a user interface. While you are free to ignore them, Apple users are used to have UIs following these guidelines and not following them will create applications that Apple users find ugly and little appealing.
Here are Apple's Human Interface Guidelines
Let me quote from there
Push Button Contents and Labeling
A push button always contains text, it
does not contain an image. If you need
to display an icon or other image on a
button, use instead a bevel button,
described in “Bevel Buttons.”
The label on a push button should be a
verb or verb phrase that describes the
action it performs—Save, Close, Print,
Delete, Change Password, and so on. If
a push button acts on a single
setting, label the button as
specifically as possible; “Choose
Picture…,” for example, is more
helpful than “Choose…” Because buttons
initiate an immediate action, it
shouldn’t be necessary to use “now”
(Scan Now, for example) in the label.
Push button labels should have
title-style capitalization, as
described in “Capitalization of
Interface Element Labels and Text.” If
the push button immediately opens
another window, dialog, or application
to perform its action, you can use an
ellipsis in the label. For example,
Mail preferences displays a push
button that includes an ellipsis
because it opens .Mac system
preferences, as shown in Figure 15-8.
Buttons should contain a single verb or a verb phrase, not answers to trivia game! If you have between 2 and 5 answers, you should use Radio Buttons to have the user select the answer and an OK button to have the user accept the answer. For more than 5 answers, you should consider a Pop-up Selector instead according to guidelines, though I guess that would be rather ugly in this case.
You could consider using a table with just one column, one row per answer and each cell being multiline if the answer is very long and needs to break. So the user selects a table row by clicking on it, which highlights the table cell and then clicks on an OK button to finish. Alternatively, you can directly continue, as soon as the user selects any table cell (but that way you take the user any chance to correct an accidental click). On the other hand, tables with multiline cells are rather rare on MacOS X. The iPhone uses some, but usually with very little text (at most two lines).
Pretty sure you can't do that using the standard API, certainly not with UILineBreakMode. In addition, the style guide says that an ellipsis indicates that the button when pressed will ask you for more information -for example Open File... will ask for the name of a file. Your proposed use of ellipsis violates this guideline.
You'd need some custom logic to implement the behaviour you describe, but I don't think it's the way to go anyway.
This is not a very good UI practice, but if you still want to do it, your best bet is to do so via a clickable div styled to look like a button.
Set the width of the div to an explicit value, and its overflow to hidden, then use a script executing on an interval to adjust the scrollLeft property of this div.