|
OK, I'll take that as a no
But anyways, I pretty think I know what to do with the Panel to make it look like the RichTextBox:
- 3D borders.
- Window -colored background.
- When user hovers over the Panel, change cursor.
- When user clicks the Panel, create a custom cursor by using the |, using a timer to display and hide it.
- When user begins to write, have a handler that handles KeyPress (KeyDown maybe?) which draws (?) the text. Have the whole typed text in a string and have an array with all the lines in it.
Is it something like that? You sure you can't just send me the extended Panel Class/Control/Component (?)? Maybe just a little sneakpeak? If not, can I have your MSN or Skype or anything really so I can instant message you when I'm in trouble?
Theo
|
|
|
|
|
You're pretty close, except for the details:
- I didn't want to look it exactly like an RTB, however that is not a primary concern;
- I draw my own cursor, I don't use a Windows cursor; I want it to be located and sized exactly up to the pixel, all my cursors have to be in sync, and the cursor resizes when I resize my fonts;
- I need KeyDown, KeyPress and KeyUp events for functional reasons;
- each line of text becomes a little object holding a string, and some administrative information;
- I keep textlines in a List obviously, not an array.
And you are free to post questions, I am watching several forums including this one. So there is a good chance you will get my reply.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
modified on Wednesday, July 15, 2009 6:22 AM
|
|
|
|
|
You don't got some kind of instant messager? I'd be much easier for me.
Ehhh, I'm kinda stuck at the Caret thingy... How do I convert text locations to Points?
Code:
namespace Storm.TextBox.Document
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
public class Caret : Control
{
#region Members
private Timer caretTimer = new Timer();
private int Interval = 50;
private string caretString = "|";
private Font caretFont = new Font(new Font("Courier New", 9.25f), FontStyle.Bold);
private Color caretColor = SystemColors.ControlText;
private bool caretDisplay = true;
private Point caretPos = new Point(-1, -1);
private Size caretSize;
#endregion
#region Properties
public Font CaretFont
{
get { return caretFont; }
set { caretFont = value; }
}
public string DisplayString
{
get { return caretString; }
set { caretString = value; }
}
public int CaretInterval
{
get { return Interval; }
set { Interval = value; }
}
#endregion
#region Methods
private void onTick(object sender, EventArgs e)
{
caretDisplay = !caretDisplay;
Invalidate();
}
private void DrawCaret(Graphics g)
{
if (caretDisplay == true)
{
Rectangle r = new Rectangle(caretPos, caretSize);
ControlPaint.DrawStringDisabled(g, caretString, caretFont, caretColor, r, TextFormatFlags.Default);
}
}
private void onPaint(object sender, PaintEventArgs e)
{
DrawCaret(e.Graphics);
}
#endregion
public Caret()
{
Paint += new PaintEventHandler(onPaint);
caretTimer.Enabled = true;
caretTimer.Tick += new EventHandler(onTick);
caretTimer.Start();
}
}
}
|
|
|
|
|
No, I don't do chat, twitter, and the like.
IIRC monospaced fonts such as Courier New always have integral character widths; so what I probably do is int charwidth=(int)(0.5+Graphics.MeasureString(someLongString).Width/someLongString.Length); once, then use that charwidth to map column numbers to/from pixel numbers.
If the above were incorrect, changing the fontsize slightly would be sufficient to make it hold true.
BTW: for proportional fonts things are much more complex, since then you have to really convert each and every position on its own merits.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm... someLongString being the... what?
> charwidth to map column numbers to/from pixel numbers.
I don't get that, sorry :s
|
|
|
|
|
just a long string with arbitrary content; although it probably does not matter much since all characters are assumed to have equal width, so a short string should give the same result in theory.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, that is weird, it says MeasureString takes 4 arguments. What should I put in the others?
Could you also explain this: charwidth to map column numbers to/from pixel numbers. ?
|
|
|
|
|
Yes, I only gave pseudo-code to convey the idea.
For the details read the documentation, that is what it is for. I will not hold your hand all the way.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, okay I figured it out
I was thinking, since I'm making the Document class..
Wouldn't it be smarter to have a Dictionary<int, string=""> than a List<string>? Since I'm creating a method "UpdateLine" that takes (int lineNum, string newLine)? The reason I'm asking is because I'm not sure if it's the most efficient way.
Really, I now it's kinda disturbing that I ask so much, but I am totally new to making this custom-Caret-Cursor-textpoint-to-pixel-thingy, I know nothing about it. I simply always used the default Windows controls or inheritted them in my own. Please bear with me
The thing about the map column thing... should I simply just, when the Document is updated, add the charWidth to the current caret point (of course substract when the user hit backspace) ? That is what seems most logical to me.
|
|
|
|
|
Hi,
having a method UpdateLine(int lineNum, string newLine) seems appropriate.
you don't need a Dictionary for that, most collections support indexing, so you could have a List<string> textLines and then perform textLines[ineNum]=newLine; as if it were an array, except I guess for adding lines beyond the current end of the list, then you would need textLines.Add(newLine);
I suggest you read up on indexers[^].
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, this is great, I think I'm on the right track now. I got it to display the Cursor X and Y when the TextEditor recieves focus, so I suppose I should convert those values into row and columns in the text, right? And if the the row and column values are invalid, jump to the last available row and column?
I think I get everything, however, how would I convert X and Y values into row and columns? You got a formula for that I should I try myself?
Thanks for everything so far!
|
|
|
|
|
Hi,
with monospaced fonts, the formula are ver simple:
xPixel=(textColumnNumber-horizontalScrollCount)*textCharacterWidth;
yPixel=(textLineNumber-verticalScrollCount)*textLineHeight;
which is assuming all characters have same width and height, and all scrolling is by integral lines and characters. Which I prefer anyway.
The above are text position to screen position (as for displaying stuff); invert them for editing (mouse to text).
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hmm, like this?
colNum = (Cursor.Position.X + this.stormParent.HorizontalScroll.Value) / charWidth;<br />
rowNum = (Cursor.Position.Y + this.stormParent.VerticalScroll.Value) / charHeight;
Because that simply gives me the same values except in minus. (261 290 becomes -261 -290 for example)
I feel sooooo stupid :s
|
|
|
|
|
Vestras wrote: like this?
obviously not. Put those gray cells to work!
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Ahh I finally figured out what the thing was! Yours is linenumber, mine isn't.
But ehh... don't I need to know the col and row to figure out the line number? >__<
Hmm... and wouldn't the textLineHeight be the same as charHeight?
|
|
|
|
|
Vestras wrote: wouldn't the textLineHeight be the same as charHeight?
maybe, maybe not.
when you do Graphics.DrawString("abc",...) the font is in charge of the character spacing.
when you paint individual text lines (or parts thereof as you are going to perform syntax coloring), you are in charge of the vertical line distance, it does not directly relate to the font height (whatever that is) as long as it is large enough.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK, I can't figure it out... my gray brain cells are dead
Can't you, please, post the correct formula? I tried everything (obviously not, but I tried what my brain could make up)
Gosh...
|
|
|
|
|
Sorry I won't.
This is what you shall do:
1. take pencil and paper
2. copy one formula exactly as it is (you are allowed shorter names, as long as they are clear)
3. locate the position of the unknown variable
4. copy the previous formula but now either add/subtract/multiply/divide by something on both sides (hence keeping the equality), so that the side where the unknown is becomes simpler
5. repeat step 4 until you've got it.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
OK I'll start from the beginning again...
Is this true?
xPixel = (textColumnNumber - horizontalScrollCount) * textCharacterWidth;
yPixel = (textLineNumber - verticalScrollCount) * textLineHeight;
______/\______ ___________/\__________
Unknown Vars Unknown Var(S)?
|
|
|
|
|
You choose a font size, hence you get a charwidth and a charheight; you choose a textLineHeight equal to or slightly larger than the charheight.
On (mouse) input you know xPixel and yPixel and want to know textLineNumber and textColumnNumber
on (display) output you know textLineNumber and textColumnNumber and want to know xPixel and yPixel.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Luc, can't you please, please help me? The closest I could come was this, and it's still pathetic:
colNum = (Cursor.Position.X - this.stormParent.HorizontalScroll.Value) / charWidth - charWidth;
lineNum = (Cursor.Position.Y - this.stormParent.VerticalScroll.Value) / (int)this.Font.Size - (int)this.Font.Size;
I tried for nearly 9 hours :s
|
|
|
|
|
Hi,
I gave you
xPixel=(textColumnNumber-horizontalScrollCount)*textCharacterWidth;
and you now want textColumnNumber=a*xPixel+b right?
The only problem is determining the coefficients a and b. Take the recipe I gave earlier, make the factors and terms on the textColumnNumber disappear by adding/subtracting/multiplying/dividing both sides of thee equation appropriately.
The first thing to go is "*textCharacterWidth" because that is what you perform last in the original equation;
then the remaining "-horizontalScrollCount"
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Is it something like this? It's the closest I can get. (And this time I even got help, lol, I suck at math)
colNum = (Cursor.Position.X / charWidth) + this.stormParent.HorizontalScroll.Value;
|
|
|
|
|
Congratulations are in order.
When a formula is correct, you can read it and see it makes sense, in this case, using horizontal character positions as a unit of measure, it says:
the column you're at equals your cursor position (in pixels) divided by the width of a character (in pixels, we divide to get rid of those pixels), plus whatever number of characters that have been scrolled away.
So now you have two ways to come up with a formula:
- start from an existing one and invert it, by moving annoying terms and factors to the other side (undoing multiplication by a division, addition by a subtraction);
- or write down a logical statement, as in the above example.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Yay, I did something correct!
However, it still seems a little off, for example what should have given me char 1, line 1, give sme char 18, line 24. This is what I have:
colNum = (Cursor.Position.X / charWidth) + this.stormParent.VerticalScroll.Value;
lineNum = (Cursor.Position.Y / (int)this.stormParent.Font.Size) + this.stormParent.HorizontalScroll.Value;
As I said, math isn't my strongest side xD I'm more at app design and such.
|
|
|
|
|