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
Related
I'm using WPF, and I have a RichTextBox in my user interface, which I convert to a PDF file. I take the RichTextBox.Document FlowDocument from the RichTextBox and translate it to a PdfSharp.Pdf.PdfPage.
This has been working pretty good (after finding some help for wordwrap on SO), but I found that I need to scale the PDF, so after I get the font from the FlowDoc, I multiply it by a scale factor, in my case 0.88.
This appeared to work great, but on closer inspection, I found that a few lines were terminating early.
// these lines use font info from the FlowDoc. To simplify, I've
// hard-coded the font size.
// this works fine:
var thisRunXFont = new XFont(thisRun.FontFamily.Source, 14, xRunFontStyle);
// this causes problems:
var thisRunXFont = new XFont(thisRun.FontFamily.Source, 12.32, xRunFontStyle);
Has anyone else seen this kind of trouble? I do go on to use MeasureString() to get the enclosing paragraph -- but forcing the rectangle to be wider does not change the behavior.
PPM1
Textfile
I tried create a C code, that can create a ppm, like on the picture 1 from a textfile like on picture 3. When somemone can help, it where great. I am a new Programmer, i tried do do that Code for 6h. I tried to scan in the data from the textfile and put it in a array and try to make withe that a ppm, but my code is unusable:/.
The path forward is to split the task into smaller sub-tasks, solve and test each one of them separately, and only after they all work, combine them into a single program.
Because the OP has not posted any code, I will not post any directly useful code either. If OP is truly blocked due to not getting any forward progress even after trying, this should actually be of practical use. If OP is just looking for someone to do their homework, this should annoy them immensely. Both work for me. :)
First sub-task is to read the input in an array. There are several examples on the web, and related questions here. You'll want to put this in a separate function, so merging into the complete project later on is easier. Since you are a beginner programmer, you could go for a function like
int read_numbers(double data[], int max);
so that the caller declares the maximum number of data points, and the function returns the number of data points read; or negative if an error occurs. Your main() for testing that function should be trivial, say
#define MAX_NUMBERS 500
int main(void)
{
double x[MAX_NUMBERS];
int i, n;
n = read_numbers(x, MAX_NUMBERS, stdin);
if (n <= 0) {
fprintf(stderr, "Error reading numbers from standard input.\n");
return EXIT_FAILURE;
}
printf("Read %d numbers:\n", n);
for (i = 0; i < n; i++)
printf("%.6f\n", x[i]);
return EXIT_SUCCESS;
}
The second sub-task is to generate a PPM image. PPM is actually a group of closely related image formats, also called Netpbm formats. The example image is a bitmap image -- black and white only; no colors, no shades of gray --, so the PBM format (or variant of PPM) is suitable for this.
I suspect it is easiest to attack this sub-task by using a two-dimensional array, sized for the largest image you can generate (i.e. unsigned char bitmap[HEIGHT_MAX][WIDTH_MAX];), but note that you can also just use a part of it. (You could also generate the image on the fly, without any array, but that is much more error prone, and not as universally applicable as using an array to store the image is.)
You'll probably need to decide the width of the bitmap based on the maximum data value, and the height of the bitmap based on the number of data points.
For testing, just fill the array with some simple patterns, or maybe just a diagonal line from top left corner to bottom right corner.
Then, consider writing a function that sets a rectangular area to a given value (0 or 1). Based on the image, you'll also need a function that draws vertical dotted lines, changing (exclusive-OR'ing) the state of each bit. For example,
#define WIDTH_MAX 1024
#define HEIGHT_MAX 768
unsigned char bitmap[HEIGHT_MAX][WIDTH_MAX];
int width = 0;
int height = 0;
void write_pbm(FILE *out); /* Or perhaps (const char *filename)? */
void fill_rect(int x, int y, int w, int h, unsigned char v);
void vline_xor(int x, int y, int h);
At this point, you should have realized that the write_pbm() function, the one that saves the PBM image, should be written and tested first. Then, you can use the fill_rect() function to not just draw filled rectangles, but also to initialize the image -- the portion of the array you are going to use -- to a background color (0 or 1). All of the three functions above you can, and should, do in separate sub-steps, so that at any point you can rely on that the code you've written earlier is correct and tested. That way, you only need to look at bugs in the code you have written since the last successful testing! It might sound like a slow way to progress, but it actually turns out to be the fastest way to get code working. You very quickly start to love the confidence the testing gives you, and the fact that you only need to focus and worry about one thing at a time.
The third sub-task is to find out a way to draw the rectangles and vertical dotted lines, for various inputs.
(I cheated a bit, above, and included the fill_rect() and vline_xor() functions in the previous sub-task, because I could tell those are needed to draw the example picture.)
The vertical dotted lines are easiest to draw afterwards, using a function that draws a vertical line, leaving every other pixel untouched, but exclusive-ors every other pixel. (Hint: for (y = y0; y < y0 + height; y += 2) bitmap[y][x] ^= 1;)
That leaves the filled rectangles. Their height is obviously constant, and they have a bit of vertical space in between, and they start at the left edge; so, the only thing, is to calculate how wide each rectangle needs to be. (And, how wide the entire bitmap should be, and how tall, as previously mentioned; the largest data value, and the number of data values, dictates those.)
Rather than writing one C source file, and adding to it every step, I recommend you write a separate program for each of the sub-steps. That is, after every time you get a sub-part working, you save that as a separate file, and keep it for reference -- a back-up, if you will. If you lose your way completely, or decide on another path for solving some problem, you only need to revert back to your last reference version, rather than start from scratch.
That kind of work-flow is known to be reliable, efficient, and scalable: it does not matter how large the project is, the above approach works. Of course, there are tools to help us do this in an easy, structured manner (with comments on each commit -- completed unit of code, if you will); and git is a popular, free, but very powerful one. Just do a web search for git for beginners if you are interested in it.
If you bothered to read all through the above wall of text, and grasped the work flow it describes, you won't have much trouble learning how to use tools like git to help you with the workflow. You'll also love how much typing tools like make (and the Makefiles containing the make recipes) help, and how easy it is to make and maintain projects that not only work, but also look professional. Yet, don't try to grasp all of it at once: take it one small step at a time, and verify you have a solid footing, before going onwards. That way, when you stumble, you won't hurt yourself; just learn.
Have fun!
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.
We're porting an application from Tru64 to SLES11 and the part that I'm working on right now is a GUI written with TeleUSE.
The problem that I'm encountering is that one of my XmBulletinBoardDialogs has only half the size on LINUX compared to Tru64. I've tried to change the height in the pcd file and the generated c code looks alright but has no effect:
XtSetArg(args[n], XmNheight, 800); n++;
Any appearance changes that I've tried had no effect also..
Are there known problems or changes in functionality between the platforms or should I search for constraints from parent windows (then how would they look like?)? I'm new to TeleUSE so any hint on a probable source for the problem would help.
The size of the window was set by the input string "\n\n\n\n TEXT \n\n\n"
The problem was that apparently the parsing of the string is working differently with the function "XmStringCreateLtoR". I had to add spaces between the \n's for the line breaks to have an effect
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.