ThinkC Redrawing a window when updateEvt happens

Relating to ThinkC Development

eric

Administrator
Staff member
Sep 2, 2021
941
1,542
93
MN
scsi.blue
I'm having trouble understanding how to handle update events. I'm going to walk through what I've tried and what happened, maybe someone can fill in where I've gone wrong or what I'm missing.

For reference this is what the window looks like to start, a simple window with a list with two items, a button, a roundrect around the button, a rect, and some text:
1660314394540.png


First - if you dont handle updateEvt and your window is drawn over and then comes back - everything that was drawn over will be missing
1660314046233.png


Ok, so lets handle the updateEvt
C:
case updateEvt:
    BeginUpdate((WindowPtr)e->message);
    DrawControls((WIndowPtr)e->message);
    EndUpdate((WindowPtr)e->message);
1660314245487.png

Ok, a bit better - the button and list are there, but the text in the list is chopped off, the rect around the button is gone, the DrawString "here" is gone, and my bar next to the button is gone.

The books and docs seem to stop here - not giving me pointers on HOW to update the rest. Any guidance appreciated!
 

jcs

Tinkerer
Oct 30, 2021
30
66
18
Chicago
jcs.org
You have to do the DrawString again in the update because all DrawString does is draw pixels on the viewport, it's not adding something like a label that retains the string. Maybe put the DrawString in an update routine and call it during updateEvt, and if you want it at init time just call that function too.

For the list, you have to call LUpdate because it's not a normal control that is handled by DrawControls. Same for a TextEdit object that would require TEUpdate.
 
  • Like
Reactions: eric

eric

Administrator
Staff member
Sep 2, 2021
941
1,542
93
MN
scsi.blue
Ahh, when searching through thinkc reference 1.0 LUpdate wasnt shown, but if I got into the List Manager section I see it. Ok that works for updating the list.

C:
WindowPtr window;
switch(e->what)
{
    case updateEvt:
        window = (WindowPtr)e->message;
        BeginUpdate(window);
        DrawControls(window);
        LUpdate(window->visRgn, gList); // ya a global for now :P
        // Todo, redraw other parts of window manually
        EndUpdate(window);
        break;
}

For keeping track of WHERE to draw the other things, for the button it looks like i can get the `button->controlRect` and then calculate the Round Rect for the default button. For the text/manual rect - I'll have to either store or have some constants to know where to draw them, or offset them from the controlRect of the other controls.
 

eric

Administrator
Staff member
Sep 2, 2021
941
1,542
93
MN
scsi.blue
C:
/* ReDraw the RoundRect around the button to show it as default */
void DrawDefaultButtonRect()
{
    Rect bounds;
    bounds = (*gButton)->contrlRect;
    PenSize(3,3);
    bounds.top = bounds.top - 4;
    bounds.bottom = bounds.bottom + 4;
    bounds.left = bounds.left - 4;
    bounds.right = bounds.right + 4;
    FrameRoundRect(&bounds, 16, 16);
}

Redrawing the button - suppose i could pass it in as a param to the method too, but this works for now.