Reputation: 6015
I would like to program a WYSIWYG editor for HTML. I'm looking for a high level approach, which I will eventually be implementing in C++.
My initial approach is to create a hierarchy of classes which extend a common base class (node). So object "body" would contain object "p" which would contain object "b" which would contain some text.
class node {
node *parent;
vector<node> children;
string name;
map<string,string> attributes;
string text;
virtual void render(const rect &rect, const point &offset) = 0;
virtual void onEvent(const event &e);
}
The main engine would call something like body.render(screen, point(0, 0)), which would recursively render its children.
The cursor would be represented by a pointer into the object hierarchy, and each node would have its own internal cursor state, and would respond to keyboard events when it is the selected node.
For example, if the user hits the left-arrow, and the "p" node is selected, the "p" node's reaction to the keypress might be to change the current node to the parent of "p".
Abstractly, it seems like this could work, the closest thing I can find to what I'm looking for is Sigil, which at first glance seems pretty intimidating to study (main.cpp is 70k).
Before I go down this road, I was wondering if anyone had a simpler approach, or can see any pitfalls with this method.
Upvotes: 2
Views: 1875
Reputation: 225054
A simpler approach, if you can do this, is to embed a web browser in your application and set contentEditable="true"
on <body>
. If you're on Windows, you can use the built-in one, or you can embed an engine like Gecko or WebKit.
Upvotes: 2
Reputation: 6615
You can look at doing color picking.
Basically you render everything twice. Once is what is displayed to the user.
The other is a bunch of bounding boxes done in unique random colours that you can turn back into pointers via a hashtable lookup or whatever. This allows you to quickly locate what is under a mouse cursor without having to recursively look up every object. You might want to miss the currently selecvted object from the color picking that way you can click twice to get the object below you current one (if you want to keep going for lower you will need to mess around with zorder depth somehow. Maybe don't render anything in the selected elements bounding box region that is over the zorder of your currently selected object).
Finally once you have selected the specific element you can enter a sub editing mode. For example turning a block of text into an editable text box with a blinking cursor, drawing borders/handles around your element to allow you to resize/manipulate it and showing a list of properties.
Realistically if your looking at making a HTML WYSIWYG editor, that will also require a HTML rendering engine. Unless you plan to make your own from scratch (which is a massive undertaking by itself), or only plan on implementing a very limited subset of HTML (which would still be fairly time-consuming). Most HTML renderer engines will include some kind of support for tapping into things like object picking. It might be worth grabbing webkit and seeing what it supports. Maybe look at the Chromium source code (Chrome includes an inbuilt webpage inspector that isn't too far off being an editor (it allows object picking and runtime editing of properties but the editing isn't totally WYSIWYG since its done in an external window, but that might be enough for what you want.
You might even do better to look at writing you editor (or parts of it) as some kind of JavaScript/Grease Monkey extension that you can load over the page being edited. You could write your whole editor in HTML or just add some support handle wrapper script that communicates to your native program.
Upvotes: 2