wxErlang question 6 - Image display

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

wxErlang question 6 - Image display

Joe Armstrong-2
Images

wxWidgets is breaking the principle of least astonishment

I've been making a load of widgets and adding them to a Vbox
which arranges them in a vertical stack.

To make a button

    Button = wxButton:new(Panel, Id, [{label,"My New Button"}]),
    wxSizer:add(Vbox, Button, ...)

To make a text editor

    Button = wxTextCtrl:new(Panel, Id, ...),
    wxSizer:add(Vbox, Editor, ...)

To make a combo box

     Combo = wxComboBox:new(Panel, Id, ..),
     wxSizer:add(Vbox, Combo, ...)

and so on.

At this point I began thinking "I'm beginng to understand this stuff" but ...

I thought I'd add an image, so I tried this:

    Image = wxImage:new("image.jpg", []),
    wxSizer:add(Vbox, Image, ...)

But oh dear - this doesn't work.

I Googled a bit - and it appears I have to mess with paint events and
graphics contexts and so on.

But why? - why break the principle of least atonishment.

Is it possible to dispay an Image in a Panel *without* handling graphics context
and paint events?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: wxErlang question 6 - Image display

zxq9-2
On 2017年07月08日 土曜日 15:14:05 Joe Armstrong wrote:
> Images
>
> wxWidgets is breaking the principle of least astonishment

Indeed. Most of all with regard to semantics. "Window", "frame", "image", "bitmap" and so on all mean slightly different things than we expect. The semantic hurdles were my greatest annoyance with WX, and still are.

>     Image = wxImage:new("image.jpg", []),
>     wxSizer:add(Vbox, Image, ...)
>
> But oh dear - this doesn't work.
>
> I Googled a bit - and it appears I have to mess with paint events and
> graphics contexts and so on.
>
> But why? - why break the principle of least atonishment.
>
> Is it possible to dispay an Image in a Panel *without* handling graphics context
> and paint events?

I remember encountering this problem... and I placed the solution into a library (which I've been doing gradually with quite a few things to make them more Erlangish). Looking it up, I see that I had been using wxBitmap to display jpegs and pngs.

The relevant code:

https://github.com/zxq9/zxWidgets/blob/master/src/zxw.erl#L101-L114

That function is a shortcut for displaying a PNG image button, but I believe the basic bits worked for displaying an image inside a sizer also.

Until now I've only dabbled with abstracting away a few annoyances into my little widget wrapper lib. Within about a month or so I'll be back working on it quite deliberately. I'll let you know how it goes. My goal is to prevent myself from having to constantly write pages of extremely long functions just to get a few generic things on the screen (like grids of input fields, basic data displays where we know basically an X-columns wide set of information like [{Label, Data}] but don't want it to look like a Calc spreadsheet, etc.).

-Craig
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: wxErlang question 6 - Image display

Joe Armstrong-2
In reply to this post by Joe Armstrong-2
To answer my own question - this works but the code has a nasty smell
Is this really how do do things? must I setup a paint handler and
do it this way? Is there a better way??

-module(image_png).

-export([start/0]).

-include_lib("wx/include/wx.hrl").

start() ->
    W = wx:new(),
    Frame = wxFrame:new(W, -1, "PNG image"),
    Panel = wxPanel:new(Frame, [{size,{400,600}}]),
    Vbox = wxBoxSizer:new(?wxVERTICAL),
    wxSizer:add(Vbox, Panel, [{proportion, 1}, {flag, ?wxEXPAND}]),
    Image = wxBitmap:new("frame1.png", [{type, ?wxBITMAP_TYPE_PNG}]),
    F = fun(I, _) -> redraw(Image,I) end,
    wxPanel:connect(Panel, paint, [{callback,F}]),
    wxFrame:show(Frame).

redraw(Image, #wx{obj=Panel}) ->
    DC = wxPaintDC:new(Panel),
    wxDC:drawBitmap(DC,Image,{0,0}).

/Joe

On Sat, Jul 8, 2017 at 3:14 PM, Joe Armstrong <[hidden email]> wrote:

> Images
>
> wxWidgets is breaking the principle of least astonishment
>
> I've been making a load of widgets and adding them to a Vbox
> which arranges them in a vertical stack.
>
> To make a button
>
>     Button = wxButton:new(Panel, Id, [{label,"My New Button"}]),
>     wxSizer:add(Vbox, Button, ...)
>
> To make a text editor
>
>     Button = wxTextCtrl:new(Panel, Id, ...),
>     wxSizer:add(Vbox, Editor, ...)
>
> To make a combo box
>
>      Combo = wxComboBox:new(Panel, Id, ..),
>      wxSizer:add(Vbox, Combo, ...)
>
> and so on.
>
> At this point I began thinking "I'm beginng to understand this stuff" but ...
>
> I thought I'd add an image, so I tried this:
>
>     Image = wxImage:new("image.jpg", []),
>     wxSizer:add(Vbox, Image, ...)
>
> But oh dear - this doesn't work.
>
> I Googled a bit - and it appears I have to mess with paint events and
> graphics contexts and so on.
>
> But why? - why break the principle of least atonishment.
>
> Is it possible to dispay an Image in a Panel *without* handling graphics context
> and paint events?
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: wxErlang question 6 - Image display

Joe Armstrong-2
In reply to this post by zxq9-2
On Tue, Jul 11, 2017 at 3:17 AM, zxq9 <[hidden email]> wrote:

> On 2017年07月08日 土曜日 15:14:05 Joe Armstrong wrote:
>> Images
>>
>> wxWidgets is breaking the principle of least astonishment
>
> Indeed. Most of all with regard to semantics. "Window", "frame", "image", "bitmap" and so on all mean slightly different things than we expect. The semantic hurdles were my greatest annoyance with WX, and still are.
>
>>     Image = wxImage:new("image.jpg", []),
>>     wxSizer:add(Vbox, Image, ...)
>>
>> But oh dear - this doesn't work.
>>
>> I Googled a bit - and it appears I have to mess with paint events and
>> graphics contexts and so on.
>>
>> But why? - why break the principle of least atonishment.
>>
>> Is it possible to dispay an Image in a Panel *without* handling graphics context
>> and paint events?
>
> I remember encountering this problem... and I placed the solution into a library (which I've been doing gradually with quite a few things to make them more Erlangish). Looking it up, I see that I had been using wxBitmap to display jpegs and pngs.
>
> The relevant code:
>
> https://github.com/zxq9/zxWidgets/blob/master/src/zxw.erl#L101-L114
>
> That function is a shortcut for displaying a PNG image button, but I believe the basic bits worked for displaying an image inside a sizer also.

I tried to put the bit map in a sizer without any joy - it might be possible

>
> Until now I've only dabbled with abstracting away a few annoyances into my little widget wrapper lib. Within about a month or so I'll be back working on it quite deliberately. I'll let you know how it goes. My goal is to prevent myself from having to constantly write pages of extremely long functions just to get a few generic things on the screen (like grids of input fields, basic data displays where we know basically an X-columns wide set of information like [{Label, Data}] but don't want it to look like a Calc spreadsheet, etc.

Brilliant - I'm convinced this is the right way to go.

I recently ran into a problem - I wanted a text editor with a given
width and height and border
If you put this in a Vbox and set wxEXPAND and if the origional size
of the editor is bigger than the frame window then the padding is
ignored.

The work around is to make the initial width rather small in the
knowledge the the vbox entries will
ignored when it is expanded - so the border argument to the sizer
depends heavily upon context.

Instead of saying   wxSpacer:add(X,Y,[{border,10}, ..])

I want a *functional* interface

     Panel1 = add_padding(Panel)

that *always* works

Hopefully we can discover a smallish set of combinators that hides the
horrendous mess
of callbacks.

<aside>
I'm beginning to understand why people use interface builders - they
drag and drop
controls onto a canvas and code which makes the GUI is created.

If you read the generated code it is horrible - but it does insert all
the undocumented
kludges that makes the thing work (perhaps).

I had always thought that the very existence of a interface builder was
'proof' (If I needed one) that there were deep problems with the
underlying libraries.
Instead of solving these underlying problems, they have just been
pushed under the carpet.
The mess is hidden - not cleaned up.

Now we seem to have two worlds - native GUI programming is a mess - programming
GUIs in SVG or in Javascript by manipulating the DOM is pretty easy.
</aside>


Cheers

/Joe




/Joe




>
> -Craig
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions