how to (programmatically) scroll to a specific line in gtktextview/gtksourceview - c

I am creating a text editor as a way of getting more familiar with C and gtk+. I am using gtk+-2.0 & gtksourceview-2.0, and gtk_scrolled_window . As a first attempt at creating a goto function browser I thought I would just simply create an array of functions found in the document and a corresponding array of lines on which they occur. I have that much done. I was surprised to find that there is no goto line capability that I can easily find in devhelp. It sounds like gtk_text_view_scroll_to_mark () is what I want (after creating a mark), but all the *scroll_to functions require a within_margin, which to be honest I don't really understand.:
From devhelp:
The effective screen for purposes of this function is reduced by a margin of size within_margin.
What does that mean?
Am I even close? How can I create this scroll to line number functionality?
Thanks.
UPDATE: The following three functions were used to scroll to a line in the buffer:
gtk_text_iter_set_line (&start, lineNums[9]);
gtk_text_buffer_add_mark (tbuffer, scroll2mark, &start);
gtk_text_view_scroll_to_mark (text_view, scroll2mark, 0.0, TRUE, 0.0, 0.17);
The last parameter of gtk_text_view_scroll_to_mark was used to get the target line number to line up with the very top line in the buffer. I imagine this parameter will not work on all screen sizes, but I have not tested it.
The gtk_text_view_scroll_mark_onscreen function got me close to the line number, but it was just a couple of lines off the bottom of the text area.

The within_margin parameter controls the area of the screen in which the scrolled-to text should appear or more precisely it sets the amount of space at the border of the screen in which the text should not appear.
This exists so that when you set use_align to false (i.e. you don't want the text to appear at a specific position on the screen), you can still make sure that the text doesn't appear directly at the top of bottom of the screen (which might be bad for readability purposes).
If you don't care at all about the position at which the text will appear, you can use g_text_view_scroll_mark_on_screen which only takes the text view and a mark and no further arguments. This will always scroll the minimum amount to make the text appear on screen.

Related

If a line of text is separated into multiple text leaves in the accessibility tree, is it still accessible well?

Below is a picture of my current accessibility tree. You can see that the 4 text leaves in it are separated, but it still forms only one line of content. Is this still accessible well ("well" meaning screen readers can detect that they form one complete sentence), or should all of the text leaves be combined into one leaf?
If they should be combined, how can you concatenate variables into the text in React, while keeping it as one single leaf? This is my current code: <p>{cloudiness}% ({cloudinessDescription})</p>
How they are read aloud depends on the screen reader being used. VoiceOver reads it as one phrase, but that doesn't mean others will. Having it split up wouldn't be a nice experience, but it doesn't mean it's not accessible.
If you really want to make sure it's read as one phrase but don't like the noise of the template literal inside the JSX (I agree), why not define the string somewhere else until you are able to test on multiple screen readers?
const cloudinessSummary = `${cloudiness}% (${cloudinessDescription})`;
return <p>{cloudinessSummary}</p>;

How to count the width of text sprite?

I need to wrap text nicely. E.g. "WWWW WWWW" takes more space than "1111 1111".
I have a design to make a for loop and add words one by one and see if text is too long to fit the row.
How to count properly the text.textWidth() without drawing text to the screen 1st?
System.Wait() seems to be required to make textwidth value refresh, is there any workaround for this? I don't want to add sleep into for loop, it would take ages.
len(text.text) to count the text, use len(str(text.text)) if combinated number and text
checkout full documentation here

SVG unit system is different than expected

In the screenshot of the DOM you can see that the text ending in the numbers 623 is given a x value of 160. However, when I inspect the text, something something which is rendered before the numbers it has a length of 126.08px (see the second screenshot). This means that my text, which I translated 160px to the right, is not actually 160px to the right. From this article, I understand that unless a viewport is provided one user unit should equal one screen unit, but this is obviously not the case here. Why is this? Thanks! I'm using React if that is necessary.
You're setting "text-anchor' to "end' which will end up shifting the text to the left. Set it to 'start' (or possibly skip it altogether) and you should see the behavior you expect.

Window positioning in ncurses

I'm attempting to write a simple chat application in C using ncurses, both of which I am new to with a background in PHP. (Yes, I know. Thanks. I'll take that advice to heart. Please put down the guns.)
What I've attempted to do is create two windows, one for input and one for channel text, like so:
int termwidth = getmaxy(stdscr);
int termheight = getmaxx(stdscr);
WINDOW *channel = newwin(termwidth, termheight - 1, 0, 0);
scrollok(channel, TRUE);
WINDOW *input = newwin(termwidth, 1, termheight + 1, 0);
scrollok(input, TRUE);
and then set cursor position to input:
wmove(input, 0, 0);
in order to put typed input in the second window, which should occupy a single column at the bottom of the terminal, while output appears in the first window which fills the rest of the terminal's space.
Output appears to fill the top window (channel) properly, with the input cursor flashing in the proper place, but changing its size does not yield predictable results and typed input doesn't appear to be going into the input window at all.
The complete source is available here: http://pastebin.com/X8apHUgh
To sum up, I am asking why input is behaving unexpectedly, and why drawing the "channel" window is yielding strange results.
Oh, [expletive/deleted]! I'm an imbecile. It turns out my problem was twofold:
I had inadvertently mixed my X and Y assignments, and
I had also reversed the width and height parameters in the functions.
This meant that positioning worked properly, until I made certain assumptions for basic positioning math.
I should add that this is partly because I was conceiving terminal positioning in terms of X/Y position, where rows/cols is the paradigm in place. They are only partly equivalent.
slow clap for self

Programmatically determining max fit in textbox (WP7)

I'm currently writing an eBook reader for Windows Phone Seven, and I'm trying to style it like the Kindle reader. In order to do so, I need to split my books up into pages, and this is going to get a lot more complex when variable font sizes are added.
To do this at the moment, I just add a word at a time into the textblock until it becomes higher than its container. As you can imagine though, with a document of over 120,000 words, this takes an unacceptable period of time.
Is there a way I can find out when the text would exceed the bounds (logically dividing it into pages), without having to actually render it? That way I'd be able to run it in a background thread so the user can keep reading in the meantime.
So far, the only idea that has occurred to me is to find out how the textblock decides its bounds (in the measure call?), but I have no idea how to find that code, because reflector didn't show anything.
Thanks in advance!
From what I can see the Kindle app appears to use a similar algorithm to the one you suggest. Note that:
it generally shows the % position through the book - it doesn't show total number of pages.
if you change the font size, then the first word on the page remains the same (so that's where the % comes from) - so the Kindle app just does one page worth of repagination assuming the first word of the page stays the same.
if you change the font size and then scroll back to the first page, then actually there is a discontinuity - they pull content forwards again in order to fill the first page.
Based on this, I would suggest you do not index the whole book. Instead just concentrate on the current page based on a "position" of some kind (e.g. character count - displayed as a percentage). If you have to do something on a background thread, then just look at the next page (and maybe the prev page) in order that scrolling can be more responsive.
Further to optimise your experience, there are a couple of changes you could make to your current algorithm that you could try:
try a different starting point and search increment for your algorithm - no need to start at one word and to then only add one word at a time.
assuming most of your books are ASCII, try caching the width of the common characters, and then work out the width of textblocks yourself.
Beyond that, I'd also quite like to try using <Run> blocks within your TextBlock - it may be possible to get the relative position of each Run within the TextBlock - although I've not managed to do this yet.
I do something similar to adjust font size for individual textboxes (to ensure they all fit). Basically, I create a TextBlock in code, set all my properties and check the ActualWidth and ActualHeight properties. Here is some pseudo code to help with your problem:
public static String PageText(TextBlock txtPage, String BookText)
{
TextBlock t = new TextBlock();
t.FontFamily = txtPage.FontFamily;
t.FontStyle = txtPage.FontStyle;
t.FontWeight = txtPage.FontWeight;
t.FontSize = txtPage.FontSize;
t.Text = BookText;
Size Actual = new Size();
Actual.Width = t.ActualWidth;
Actual.Height = t.ActualHeight;
if(Actual.Height <= txtPage.ActualHeight)
return BookText;
Double hRatio = txtPage.ActualHeight / Actual.Height;
return s.Substring((int)((s.Length - 1) * hRatio));
}
The above is untested code, but hopefully can get you started. Basically it sees if the text can fit in the box, if so you're good to go. If not, it finds out what percentage of the text can fit and returns it. This does not take word breaks into account, and may not be a perfect match, but should get you close.
You could alter this code to return the length rather than the actual substring and use that as your page size. Creating the textblock in code (with no display) actually performs pretty well (I do it in some table views with no noticeable lag). I wouldn't send all 120,000 words to this function, but a reasonable subset of some sort.
Once you have the ideal length you can use a RegEx to split the book into pages. There are examples on this site of RegEx that break on word boundaries after a specific length.
Another option, is to calculate page size ahead of time for each potential fontsize (and hardcode it with a switch statement). This could easily get crazy if you are allowing any font and any size combinations, and would be awful if you allowed mixed fonts/sizes, but would perform very well. Most likely you have a particular range of readable sizes, and just a few fonts. Creating a test app to calculate the text length of a page for each of these combinations wouldn't be that hard and would probably make your life easier - even if it doesn't "feel" right as a programmer :)
I didn't find any reference to this example from Microsoft called: "Principles of Pagination".
It has some interesting sample code running in Windows Phone.
http://msdn.microsoft.com/en-us/magazine/hh205757.aspx
You can also look this article about Page Transitions in Windows Phone and this other about the final touches in the E-Book project.
The code is downloadable: http://archive.msdn.microsoft.com/mag201111UIFrontiers/Release/ProjectReleases.aspx?ReleaseId=5776
You can query the FormattedText class that is used AFAIK inside textBlock. since this is the class being used to format text in preparation for Rendering, this is the most lower-level class available, and should be fast.

Resources