texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Texmacs-dev] Re: Compiling TexMacs on OSX


From: Abdelrazak Younes
Subject: [Texmacs-dev] Re: Compiling TexMacs on OSX
Date: Tue, 17 Jun 2008 16:51:58 +0200
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Henri Lesourd wrote:
Abdelrazak Younes wrote:

Henri Lesourd wrote:

It looks like one of the root causes of why you feel
it's difficult to support multiple toolkits is that
you are trying to design *too much fine-grained* APIs.


Hum well, the API you are describing below is *very fine-grained* :-), more details below.

It captures the essence of what widgets are, namely,
rectangular areas of the screen which can be recursively
embedded inside one each other.

As soon as you know that these aspects of widgets are
universal, of course you provide detailed control over
that.

There are a lot of different kind of widget. It's even possible possible to have non-rectangular widget :-) By keeping the control of such things as widget placement and size you are limiting yourself to widget with windows. For example Qt provides dock widgets and drawer on Mac. You ought to let Qt manage these widget, there is no other way around.

The fact remains that I agree with you that supporting
multiplatform software is hard. But there are ways
to turn this easier by means of designing the APIs
carefully, especially: thru your API, you should
*not* try to give control on details which, as a
matter of fact, are platform-dependent.


Much of the API I see below is platform-dependent IMO.

You would need to point me exactly why, because
it seems to me that my API contains no detail
related to any particular platform or environment.

See above. IIUC your architecture, you are limiting the frontend capabilities to the one you are defining. In essence, you are forcing the frontend API to a common denominator while I think the core typesetting engine is the one which should define a clear and limited API. The frontend will just provide a canvas where the core can draw onto. A virtual interface to the painting operations will of course be needed.


But perhaps we have different definitions
for "platform-independent", in such a case
we should agree on a definition of this word
first.

By platform-dependant I meant the "Texmacs platform" because that what you are creating ;-)

You seem to miss my point: those indirections caused by your encapsulation is not worth it.

Yes it is worth, because the code written on top of the
first low-level API (the "hardware abstraction layer" if
you want) is completely reuseable, you don't maintain a
different version of this code for each platform.

And what I am saying that the toolkit designer (Qt in our example) have done a lot of thinking about the API. Of course, the code that you are creating using the object defined with your API components will be usable by all frontends but, in most cases, programming directly using Qt component will mean much less code to begin with. I mean, unless you are a GUI toolkit expert yourself and you think you can do better... In this case you should simply say that you are implementing a simple GUI toolkit limited to dialogs and buttons on top of Qt :-) That's how we do it in LyX, the only thing that the core knows about is the text canvas that we call the Work Area. the core doesn't know anymore about menubars, toolbars and dialogs. We are not 100% clean yet but coming close.


Maybe you think that you'll be able to factorize some code between frontend because a dialog is a dialog and a button is a button.

No: I think that I will be able to factorize lots of code
because the API for a dialog and the API for a button have
a lots of common points, e.g., dialog and buttons are rectangular
areas of the screen,

Wrong! These are predefined ideas, things can be much more complex than buttons and dialogs.

they can be moved, they can send you back
a "submit" event with the appropriate meaning in each one of
the cases, etc.

In the end, it turns out that when you want to wrap Qt
buttons behind my API, 80% of the code is pure wrapping,
e.g. something like that:

button::move(widgel *w,int x,int y) {
 ((QWidget*)w->wdg)->move(x,y);
}

, and the rest is wrapping the specific Qt events (e.g.,
the "clicked" event) behind one of the few handlers for
the generic events (e.g. "submit").


And THAT'S ALL ! Thus once the API is defined, wrapping
a new Qt component behind it is a matter of less than
one hour.

As a said, if your goal is to have limited support for GUI components, that's fine. Qt provides signal and slots for the typical needs for user interaction with button, by handling this kind of events you are not simplifying things.



Still, there remain hard cases, especially for
features you absolutely need, but are not well
standardized across toolkits, and thus are platform
dependent. A chief example of such features is
how to encapsulate the main loop of the underlying
GUI toolkit in a portable way.


And that's exactly why you should try to avoid it. We had a lot of problem managing the event loop in LyX; I cleaned up that so that the core doesn't know about the event loop, literally.

It has to be somewhere, anyway, and there are well-known
techniques to abstract such a thing (i.e., by means of
a queue).

Well, we have a virtual interface for the event handler (QApplication). So we just intanciate that class and call QApplication::exec() from main(), that's all. But even that kind of stuff should be transferred to the frontend, I'll do that later for LyX.


The only problem is that it's never sure that the GUI
will provide us with the control we need on the main
loop (specifically: the ability to stop the loop from
outside, or either to run the loop for only one event,
or either to run the loop till it becomes idle).

I don't get it, why do you want to keep control of the loop?


In any case, this thing has to be implemented somewhere,
all the more because the pure X11 TeXmacs loop was
performing some important polling (e.g., listening
to the incoming socket).

You can use a timer do that kind of polling, no need to mess with the event loop.


And NO, it is not an option to turn this polling loop
to a Qt event handler, that's exactly what has to be
avoided, because then you need to use *their* implementation
of sockets, timers, etc., which would raise other problems.

What problems? Again, are you in the business of a typesetting application or in the toolkit business? You are not forced to use Qt's solution for socket (we don't either) but there's nothing that forbids that. Regarding the event loop and timers, I don't understand what is the benefit of not using them.


No: the reality is that designing a portable API (i.e., what
you call the "virtual interface") is *hard*. But if you do
it well, i.e., if you capture the real nature of what a widget
is, then you can succeed.


And your locking yourself in your portable API.

As soon as I know I will not need to change it in
the future, it's OK.

YES, it means that I define in the first
place what a "widget" is, and that in the
future, I stick to that definition. But as
a matter of fact, in computer science, defining
what you want to implement is *necessary*.

Well, if the thing is already defined what is the need to redefine it? ;-)

This is what I called glue code, at application level, we are not (IMHO) in the toolkit API business.

For me, a toolkit API should provide you with
the basics, namely:

1. being able to move and redim, to hide and
  unhide widgets ;

You can put in place a communication protocol for that kind of stuff. No need to encapsulate the GUI API. In LyX we just use what we call a function request which is an object that is understood by the core and the frontend. But you could also really split the application in two process and use socket or pipe based communication between the two if you truly want to be Qt independent.


That's exactly what my API provides, and what I claim
is that you don't, and will never need more in the
future.

Well, if you replace 'you don't' by 'I don't', I would agree :-)


You can disagree with me, but then it means that your
goal is not the same as mine, which is to provide a
simple, limited API for encapsulating all the usual
widgets.
Exactly :-)

void widglib_finish();


Sorry but this looks to me like a lot of work for basically not much gain.

Are you sure we speak about the same thing ? You need
routines to start the main loop and routines to stop
it, how could you do without ?

As I said above:

int main(int argc,char **argv) {
   MyApplication app(argc, argv);
   return app.exec();
}

MyApplication would of course derives from QApplication in my world. But I know that isn't the answer you were expecting.


A typical C program creating a window with only a
button looks like this:

int main(int argc,char **argv) {
}


Although it's perhaps possible to make shorter,
it seems to me that the API provides you with
a *very* easy way to implement interactive
applications.


Well, in a C world maybe. Having the core lib in C is maybe desirable (that's not my personal taste) but the GUI should be implemented in C++ IMHO, especially if you make use of C++ toolkit.



But you seem to be pretty convinced of your case so I won't insist :-)

It's just that it seems to me difficult to do
simpler, and that this API is easy to implement,
and easy to use as well.

What else could I want ?, this is really the question.

Maybe the question is "what else could other developers want?"

OK, I hope I clarified my point of view. At this point I think we of course all agree that it is the one that do the work that decide.

Good luck in any case :-)

Abdel.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]