Annotation of 43BSD/contrib/X/xdemo/menus.clu, revision 1.1

1.1     ! root        1: 
        !             2: left_Arrow = "\000\000\002\000\006\000\016\000\036\000\076\000" ||
        !             3:             "\176\000\376\000\376\001\376\003\376\007\176\000" ||
        !             4:             "\156\000\306\000\302\000\200\001\200\001\000\000"
        !             5: left_Mask  = "\003\000\007\000\017\000\037\000\077\000\177\000" ||
        !             6:             "\377\000\377\001\377\003\377\007\377\017\377\017" ||
        !             7:             "\377\000\357\001\347\001\303\003\300\003\200\001"
        !             8: 
        !             9: la_Width   = 12
        !            10: la_Height  = 18
        !            11: la_X      = 1
        !            12: la_Y       = 1
        !            13: 
        !            14: vLine_Width   = 1
        !            15: vBottom_Space = 2
        !            16: vTop_Space    = 2
        !            17: vLeft_Space   = 1   %% avg_width chars
        !            18: vRight_Space  = 1
        !            19: 
        !            20: 
        !            21: menu_bar = cluster is
        !            22:        init,
        !            23:        reset,
        !            24:        insert,
        !            25:        append,
        !            26:        remove,
        !            27:        select,
        !            28:        get_cursor, get_fore, get_back, get_forepix, get_backpix, get_plane
        !            29: 
        !            30:     title = record [ Menu:   menu,
        !            31:                     Window: x_window ]
        !            32:     at = array[title]
        !            33: 
        !            34:     rep = record[
        !            35:              Window:   x_window,
        !            36:              White_W:  x_window,
        !            37:              MBW:      x_window,
        !            38:              Cursor:   x_cursor,
        !            39:              Font:     x_font,
        !            40:              Fore:     x_pixmap,
        !            41:              Back:     x_pixmap,
        !            42:              ForePix:  int,
        !            43:              BackPix:  int,
        !            44:              Plane:    int,
        !            45:              Titles:   at,
        !            46:              Ch_Width: int,
        !            47:              Height:   int,
        !            48:              Width:    int
        !            49:                 ]
        !            50: 
        !            51:     vExtra_Width  = 4 * vLine_Width
        !            52:     vExtra_Height = 4 * vLine_Width
        !            53:     vWhite_Border  = 1
        !            54:     vWExtra_Width  = vExtra_Width  + (2 * vWhite_Border)
        !            55:     vWExtra_Height = vExtra_Height + (2 * vWhite_Border)
        !            56:     vLeft_Offset  = vLine_Width
        !            57:     vTop_Offset   = vLine_Width
        !            58:     vHighLight_Offset = vLine_Width
        !            59:     vHighLight_Height = vExtra_Height - vTop_Offset  - vHighLight_Offset
        !            60:     vHighLight_Width  = vExtra_Width  - vLeft_Offset - vHighLight_Offset
        !            61: 
        !            62:     Init = proc (W: x_window, Font: x_font, BackPix, Plane, MousePix: int)
        !            63:             returns (cvt) signals (error(string))
        !            64:        ForePix: int := i_xor(BackPix, Plane)
        !            65:        Cursor: x_cursor := x_cursor$SCons(la_Width, la_Height,
        !            66:                                          left_Arrow, left_Mask,
        !            67:                                          MousePix, BackPix,
        !            68:                                          la_X, la_Y, GXcopy)
        !            69:        Avg_Width: int,
        !            70:        Height: int,
        !            71:        Ch1: char,
        !            72:        ChLast: char,
        !            73:        BaseLine: int,
        !            74:        FixedWidth: bool := x_font$Query(Font)
        !            75:           resignal Error
        !            76:        Height := Height + vTop_Space + vBottom_Space
        !            77:        Back: x_pixmap := x_pixmap$Tile(BackPix)
        !            78:        Fore: x_pixmap := x_pixmap$Tile(ForePix)
        !            79:        White_W: x_window := x_window$Create(
        !            80:                                 0,
        !            81:                                 0,
        !            82:                                 vWExtra_Width,
        !            83:                                 Height + vWExtra_Height,
        !            84:                                 Back,
        !            85:                                 x_display$Root(),
        !            86:                                 0,
        !            87:                                 Back)
        !            88:        White_W.Input := buttonReleased % + enterWindow
        !            89:        White_W.Cursor := Cursor
        !            90:        MBW: x_window := x_window$Create(
        !            91:                             1,
        !            92:                             1,
        !            93:                             vExtra_Width,
        !            94:                             Height + vExtra_Height,
        !            95:                             Fore,
        !            96:                             White_W,
        !            97:                             0,
        !            98:                             Fore)
        !            99:        MBW.Input := buttonReleased % + enterWindow)
        !           100:        MBW.Cursor := Cursor
        !           101:        x_window$Map(MBW)
        !           102:        return (rep${ Window:   W,
        !           103:                      White_W:  White_W,
        !           104:                      MBW:      MBW,
        !           105:                      Cursor:   Cursor,
        !           106:                      Font:     Font,
        !           107:                      Fore:     Fore,
        !           108:                      Back:     Back,
        !           109:                      ForePix:  ForePix,
        !           110:                      BackPix:  BackPix,
        !           111:                      Plane:    Plane,
        !           112:                      Titles:   at$[],
        !           113:                      Ch_Width: Avg_Width,
        !           114:                      Height:   Height,
        !           115:                      Width:    vLeft_Offset })
        !           116:        end Init
        !           117: 
        !           118:     Reset = proc (MB: cvt)
        !           119:        x_window$Destroy(MB.White_W)
        !           120:        for T: title in at$Elements(MB.Titles) do
        !           121:            menu$Reset(T.Menu)
        !           122:            end
        !           123:        MB.Titles := at$[]
        !           124:        MB.Width  := vLeft_Offset
        !           125:        MB.White_W := x_window$Create(
        !           126:                      0,
        !           127:                      0,
        !           128:                      vWExtra_Width,
        !           129:                      MB.Height + vWExtra_Height,
        !           130:                      MB.Back,
        !           131:                      x_display$Root(),
        !           132:                      0,
        !           133:                      MB.Back)
        !           134:        MB.White_W.Input := buttonReleased % + enterWindow)
        !           135:        MB.White_W.Cursor := MB.Cursor
        !           136:        MB.MBW := x_window$Create(
        !           137:                      1,
        !           138:                      1,
        !           139:                      vExtra_Width,
        !           140:                      MB.Height + vExtra_Height,
        !           141:                      MB.Fore,
        !           142:                      MB.White_W,
        !           143:                      0,
        !           144:                      MB.Fore)
        !           145:        MB.MBW.Input := buttonReleased % + enterWindow)
        !           146:        MB.MBW.Cursor := MB.Cursor
        !           147:        x_window$Map(MB.MBW)
        !           148:        end Reset
        !           149: 
        !           150:     Insert = proc (MB: cvt, M: menu, Before_M: menu) signals (not_found)
        !           151:        for I: int in at$Indexes(MB.Titles) do
        !           152:            T: title := MB.Titles[I]
        !           153:            if (T.Menu = Before_M)
        !           154:               then M.Width := x_font$Width(MB.Font, M.Title) +
        !           155:                               (MB.Ch_Width *
        !           156:                                (vLeft_Space + vRight_Space))
        !           157:                    MB.Width := MB.Width + M.Width
        !           158:                    x_window$Change(MB.White_W, 
        !           159:                                    MB.Width - vLeft_Offset + vWExtra_Width,
        !           160:                                    MB.Height + vWExtra_Height)
        !           161:                    x_window$Change(MB.MBW, 
        !           162:                                    MB.Width - vLeft_Offset + vExtra_Width,
        !           163:                                    MB.Height + vExtra_Height)
        !           164:                    M.Start := T.Menu.Start
        !           165:                    MW: x_window := x_window$Create(
        !           166:                                        M.Start, vTop_Offset,
        !           167:                                        M.Width, MB.Height,
        !           168:                                        MB.Back,
        !           169:                                        MB.MBW,
        !           170:                                        0,
        !           171:                                        MB.Fore)
        !           172:                    MW.Input := buttonReleased + enterWindow
        !           173:                    MW.Cursor := MB.Cursor
        !           174:                    x_window$Map(MW)
        !           175:                    New_T: title := title${ Menu:   M,
        !           176:                                            Window: MW }
        !           177:                    at$AddH(MB.Titles, New_T)
        !           178:                    for J: int in int$From_To(at$High(MB.Titles) - 1, I) do
        !           179:                        T := MB.Titles[J]
        !           180:                        MB.Titles[J+1] := MB.Titles[J]
        !           181:                        T.Menu.Start := T.Menu.Start + M.Width
        !           182:                        x_window$Move(T.Window, T.Menu.Start, 0)
        !           183:                        end
        !           184:                    MB.Titles[I] := New_T
        !           185:                    return
        !           186:               end
        !           187:            end
        !           188:        signal Not_Found
        !           189:        end Insert
        !           190: 
        !           191:     Append = proc (MB: cvt, M: menu)
        !           192:        M.Start  := MB.Width
        !           193:        M.Width := x_font$Width(MB.Font, M.Title) +
        !           194:                   (MB.Ch_Width *
        !           195:                    (vLeft_Space + vRight_Space))
        !           196:        MB.Width := MB.Width + M.Width
        !           197:        x_window$Change(MB.White_W, 
        !           198:                        MB.Width - vLeft_Offset + vWExtra_Width,
        !           199:                        MB.Height + vWExtra_Height)
        !           200:        x_window$Change(MB.MBW, 
        !           201:                        MB.Width - vLeft_Offset + vExtra_Width,
        !           202:                        MB.Height + vExtra_Height)
        !           203:        MW: x_window := x_window$Create(
        !           204:                            M.Start, vTop_Offset,
        !           205:                            M.Width, MB.Height,
        !           206:                            MB.Back,
        !           207:                            MB.MBW,
        !           208:                            0,
        !           209:                            MB.Fore)
        !           210:        MW.Input := buttonReleased + enterWindow
        !           211:        MW.Cursor := MB.Cursor
        !           212:        x_window$Map(MW)
        !           213:        at$AddH(MB.Titles, title${ Menu:   M,
        !           214:                                   Window: MW })
        !           215:        end Append
        !           216: 
        !           217:     Remove = proc (MB: cvt, M: menu) signals (not_found)
        !           218:        for I: int in at$Indexes(MB.Titles) do
        !           219:            if (MB.Titles[I].Menu = M)
        !           220:               then MW: x_window := MB.Titles[I].Window
        !           221:                    for J: int in int$From_To(I+1, at$High(MB.Titles)) do
        !           222:                        T: title := MB.Titles[J]
        !           223:                        T.Menu.Start := T.Menu.Start - M.Width
        !           224:                        MB.Titles[J-1] := T
        !           225:                        end
        !           226:                    at$RemH(MB.Titles)
        !           227:                    x_window$Destroy(MW)
        !           228:                    MB.Width := MB.Width - M.Width
        !           229:                    x_window$Change(MB.White_W,
        !           230:                                    MB.Width - vLeft_Offset + vWExtra_Width,
        !           231:                                    MB.Height + vWExtra_Height)
        !           232:                    x_window$Change(MB.MBW,
        !           233:                                    MB.Width - vLeft_Offset + vExtra_Width,
        !           234:                                    MB.Height + vExtra_Height)
        !           235:                    menu$Reset(M)
        !           236:                    return
        !           237:               end
        !           238:            end
        !           239:        signal Not_Found
        !           240:        end Remove
        !           241: 
        !           242:     Select = proc [evt: type] (MB: cvt, Start_X: int, Start_Y: int,
        !           243:                               Expose_Handler: ehand_proc, Expose_Hand_Arg: evt)
        !           244:               returns (menu, menu_item) signals (none)
        !           245:        ehand_proc = proctype(x_window, int, int, int, int, x_window, evt)
        !           246:        own E: event := x_input$Empty_Event()
        !           247:        %% There are three windows of interest:
        !           248:        %%   The main window (of which this is a menu bar) (MB.Window)
        !           249:        %%   The pop-up menu bar window.
        !           250:        %%   The (current) pull-down menu.
        !           251:        W_X:      int,
        !           252:        W_Y:      int,
        !           253:        W_Width:  int,
        !           254:        W_Height: int,
        !           255:        W_Border: int,
        !           256:        W_Map:    int,
        !           257:        W_Kind:   int,
        !           258:        W_Icon:   x_window := x_window$Query(MB.Window)
        !           259:        Left: int := int$Max(W_X + Start_X - (MB.Width / 2), 0)
        !           260:        Top:  int := int$Max(W_Y + Start_Y - (MB.Height / 2), 0)
        !           261: 
        !           262:        Display_Bar(MB, Left, Top)
        !           263: 
        !           264:        X: int := W_X + Start_X + vLeft_Offset - Left
        !           265:        Y: int := W_Y + Start_Y + vTop_Offset - Top
        !           266: 
        !           267:        Selected_T: title := Title_Selected(X, Y, MB)
        !           268:        Select_Menu(Selected_T, MB, Top, Left)
        !           269: 
        !           270:        Have_Item: bool := false
        !           271:        Selected_Item: menu_item
        !           272: 
        !           273:        while (true) do
        !           274:            x_input$DeQ(E)
        !           275:            if      (E.Kind = ButtonReleased  cand  E.Value = MiddleButton)
        !           276:               then break
        !           277:             elseif (E.Kind = EnterWindow)
        !           278:               then %% Check if a Title.
        !           279:                    if (E.Win = Selected_T.Window)
        !           280:                       then continue           %% Same old title
        !           281:                       end
        !           282:                    for New_T: title in at$Elements(MB.Titles) do
        !           283:                        if (E.Win = New_T.Window)
        !           284:                           then DeSelect_Menu(Selected_T, MB)
        !           285:                                Select_Menu(New_T, MB, Top, Left)
        !           286:                                Selected_T := New_T
        !           287:                                continue        %% New title
        !           288:                           end
        !           289:                        end;
        !           290:                    %% Must be a new item.
        !           291:                    if (Have_Item)
        !           292:                       then %%% ???
        !           293:                            continue
        !           294:                       end
        !           295:                    Selected_Item := Item_Selected(E.Win,
        !           296:                                                   Selected_T, MB)
        !           297:                       except when None:
        !           298:                                   continue
        !           299:                              end
        !           300:                    Select_Item(Selected_Item, Selected_T)
        !           301:                    Have_Item := true
        !           302:             elseif (E.Kind = LeaveWindow)
        !           303:               then if (~ (Have_Item cand 
        !           304:                           menu_item$Match(Selected_Item, E.Win)))
        !           305:                       then %%% ?????
        !           306:                            continue
        !           307:                       else DeSelect_Item(Selected_Item,
        !           308:                                          Selected_T)
        !           309:                            Have_Item := false
        !           310:                       end
        !           311:             elseif (E.Kind = ExposeRegion)
        !           312:               then Expose_Handler(E.Win, E.X, E.Y, E.X0, E.Y0, E.Sub, Expose_Hand_Arg)
        !           313:             end
        !           314:            end
        !           315:        %X, Y, SubW := x_window$Query_Mouse(TopW)
        !           316:        %Item_Was_Selected: bool := (Have_Item cand
        !           317:        %                           Inside_Item(SubW, Selected_Item))
        !           318:        Item_Was_Selected: bool := Have_Item
        !           319:        if (Item_Was_Selected)
        !           320:           then Flash_Item(Selected_Item, Selected_T)
        !           321:                DeSelect_Item(Selected_Item, Selected_T)
        !           322:           end
        !           323:        DeSelect_Menu(Selected_T, MB)
        !           324: 
        !           325:        x_window$UnMap(MB.White_W)
        !           326:        if (Item_Was_Selected)
        !           327:           then return (Selected_T.Menu, Selected_Item)
        !           328:           else signal None
        !           329:           end
        !           330:        end Select
        !           331: 
        !           332:     Title_Selected  = proc (X: int, Y: int, MB: rep) returns (title) signals (none)
        !           333:        if ((Y < 0) cor (Y >= MB.Height))
        !           334:           then signal None
        !           335:           end
        !           336:        for T: title in at$Elements(MB.Titles) do
        !           337:            if ((X >= T.Menu.Start) cand (X < T.Menu.Start + T.Menu.Width))
        !           338:               then return (T)
        !           339:               end
        !           340:            end
        !           341:        signal None
        !           342:        end Title_Selected
        !           343: 
        !           344:     Select_Menu = proc (Menu_T: title, MB: rep, Top: int, Left: int)
        !           345:        if (Menu_T = at$Bottom(MB.Titles))
        !           346:           then Left := Left - vLeft_Offset
        !           347:           end
        !           348:        menu$Select(Menu_T.Menu,
        !           349:                    (Left + Menu_T.Menu.Start + vLine_Width),
        !           350:                    (Top + vTop_Offset + MB.Height + vLine_Width))
        !           351:        x_window$Pix_Fill(Menu_T.Window, 0, x_bitmap$None(), 0, 0,
        !           352:                          Menu_T.Menu.Width, MB.Height, GXinvert, MB.Plane)
        !           353:        end Select_Menu
        !           354: 
        !           355:     DeSelect_Menu = proc (Menu_T: title, MB: rep)
        !           356:        menu$DeSelect(Menu_T.Menu)
        !           357:        if (Menu_T = at$Bottom(MB.Titles))
        !           358:           then %% Lower left highlight
        !           359:                x_window$Pix_Set(MB.MBW, MB.BackPix,
        !           360:                                 0,
        !           361:                                 MB.Height + vExtra_Height - vHighLight_Height,
        !           362:                                 vHighLight_Height, vHighLight_Width)
        !           363: 
        !           364:           end
        !           365:        x_window$Pix_Fill(Menu_T.Window, 0, x_bitmap$None(), 0, 0,
        !           366:                          Menu_T.Menu.Width, MB.Height, GXinvert, MB.Plane)
        !           367:        end DeSelect_Menu
        !           368: 
        !           369:     Inside_Item = proc (SubW: x_window, MI: menu_item)
        !           370:                    returns (bool)
        !           371:        return (menu_item$Match(MI, SubW))
        !           372:        end Inside_Item
        !           373: 
        !           374:     Item_Selected = proc (Sub_W: x_window, T: title, MB: rep)
        !           375:                      returns (menu_item) signals (none)
        !           376:        for TstMI: menu_item in menu$All_Items(T.Menu) do
        !           377:            if (menu_item$Match(TstMI, Sub_W))
        !           378:               then if (TstMI.Selectable cand TstMI.Enabled)
        !           379:                       then return (TstMI)
        !           380:                       else signal None
        !           381:                       end
        !           382:               end
        !           383:            end
        !           384:        signal None
        !           385:        end Item_Selected
        !           386: 
        !           387:     Select_Item = proc (MI: menu_item, M_T: title)
        !           388:        menu_item$Invert(MI, M_T.Menu.Max_Width)
        !           389:        end Select_Item
        !           390: 
        !           391:     DeSelect_Item = proc (MI: menu_item, M_T: title)
        !           392:        menu_item$Invert(MI, M_T.Menu.Max_Width)
        !           393:        end DeSelect_Item
        !           394: 
        !           395:     Flash_Item = proc (MI: menu_item, M_T: title)
        !           396:        M: menu := M_T.Menu
        !           397:        for I: int in int$From_To(1, 6) do
        !           398:            menu_item$Invert(MI, M.Max_Width)
        !           399:            x_flush()
        !           400:            _Sleep(30)
        !           401:            end
        !           402:        end Flash_Item
        !           403: 
        !           404:     Display_Bar = proc (MB: rep, Left: int, Top: int)
        !           405:        White_W: x_window := MB.White_W
        !           406:        x_window$Move(White_W, Left, Top)
        !           407:        x_window$Map(White_W)
        !           408:        Black_W: x_window := MB.MBW
        !           409:        %% Lower left highlight
        !           410:        x_window$Pix_Set(Black_W, MB.BackPix,
        !           411:                         0,
        !           412:                         MB.Height + vExtra_Height - vHighLight_Height,
        !           413:                         vHighLight_Height, vHighLight_Width)
        !           414:        %% Upper right highlight
        !           415:        x_window$Pix_Set(Black_W, MB.BackPix,
        !           416:                         MB.Width - vLeft_Offset + vExtra_Width - vHighLight_Width,
        !           417:                         0,
        !           418:                         vHighLight_Height, vHighLight_Width)
        !           419:        for T: title in at$Elements(MB.Titles) do
        !           420:            x_window$Text(T.Window, T.Menu.Title, MB.Font,
        !           421:                          i_xor(MB.BackPix, MB.Plane), MB.BackPix,
        !           422:                          (vLeft_Space * MB.Ch_Width),
        !           423:                          vTop_Space)
        !           424:            end
        !           425:        end Display_Bar
        !           426: 
        !           427:    Get_Cursor = proc (MB: cvt) returns (x_cursor)
        !           428:        return(MB.Cursor)
        !           429:        end Get_Cursor
        !           430: 
        !           431:    Get_Fore = proc (MB: cvt) returns (x_pixmap)
        !           432:        return(MB.Fore)
        !           433:        end Get_Fore
        !           434: 
        !           435:    Get_Back = proc (MB: cvt) returns (x_pixmap)
        !           436:        return(MB.Back)
        !           437:        end Get_Back
        !           438: 
        !           439:    Get_ForePix = proc (MB: cvt) returns (int)
        !           440:        return(MB.ForePix)
        !           441:        end Get_ForePix
        !           442: 
        !           443:    Get_BackPix = proc (MB: cvt) returns (int)
        !           444:        return(MB.BackPix)
        !           445:        end Get_BackPix
        !           446: 
        !           447:    Get_Plane = proc (MB: cvt) returns (int)
        !           448:        return(MB.Plane)
        !           449:        end Get_Plane
        !           450: 
        !           451:     end menu_bar
        !           452: 
        !           453: menu = cluster is 
        !           454:        new,
        !           455:        reset,
        !           456:        equal,
        !           457:        get_title,
        !           458:        append,
        !           459:        remove,
        !           460:        item_changed,
        !           461:        all_items,
        !           462:        set_start,     get_start,
        !           463:        set_width,     get_width,
        !           464:        get_num_items,
        !           465:        get_max_width,
        !           466:        get_window,
        !           467:        select,         deselect
        !           468:        
        !           469:     mis = sequence[menu_item]
        !           470: 
        !           471:     rep = record[ Title:     string,
        !           472:                  MB:        menu_bar,
        !           473:                  Items:     mis,
        !           474:                  Start:     int,
        !           475:                  Height:    int,
        !           476:                  Max_Width: int,
        !           477:                  Width:     int,
        !           478:                  White_W:   x_window,
        !           479:                  Window:    x_window ]
        !           480: 
        !           481:     vExtra_Width  = 4 * vLine_Width
        !           482:     vExtra_Height = 4 * vLine_Width
        !           483:     vWhite_Border  = 1
        !           484:     vWExtra_Width  = vExtra_Width  + (2 * vWhite_Border)
        !           485:     vWExtra_Height = vExtra_Height + (2 * vWhite_Border)
        !           486:     vTop_Offset   = vLine_Width
        !           487:     vLeft_Offset  = vLine_Width
        !           488:     vHighLight_Offset = vLine_Width
        !           489:     vHighLight_Height = vExtra_Height - vTop_Offset  - vHighLight_Offset
        !           490:     vHighLight_Width  = vExtra_Width  - vLeft_Offset - vHighLight_Offset
        !           491: 
        !           492:     New = proc (MB: menu_bar, Title: string) returns (cvt)
        !           493:        White_W: x_window := x_window$Create(   % A minimal window
        !           494:                                0, 0,
        !           495:                                vWExtra_Width,
        !           496:                                vWExtra_Height,
        !           497:                                MB.Back,
        !           498:                                x_display$Root(),
        !           499:                                0,
        !           500:                                MB.Back)
        !           501:        White_W.Input :=  buttonReleased % +
        !           502:                              %enterWindow +
        !           503:                              %leaveWindow
        !           504:        White_W.Cursor := MB.Cursor
        !           505:        Menu_W: x_window := x_window$Create(    % A minimal window
        !           506:                                1, 1,
        !           507:                                vExtra_Width,
        !           508:                                vExtra_Height,
        !           509:                                MB.Fore,
        !           510:                                White_W,
        !           511:                                0,
        !           512:                                MB.Fore)
        !           513:        Menu_W.Input := buttonReleased % +
        !           514:                              %enterWindow +
        !           515:                              %leaveWindow
        !           516:        Menu_W.Cursor := MB.Cursor
        !           517:        x_window$Map(Menu_W)
        !           518:        return (rep${ Title:     Title,
        !           519:                      MB:        MB,
        !           520:                      Items:     mis$[],
        !           521:                      Start:     0,
        !           522:                      Height:    vTop_Offset,
        !           523:                      Max_Width: 0,
        !           524:                      Width:     vLeft_Offset,
        !           525:                      White_W:   White_W,
        !           526:                      Window:    Menu_W })
        !           527:        end New
        !           528: 
        !           529:     Reset = proc (M: cvt)
        !           530:        %% ???
        !           531:        end Reset
        !           532: 
        !           533:     Equal = proc (M1: cvt, M2: cvt) returns (bool)
        !           534:        return (M1 = M2)
        !           535:        end Equal
        !           536: 
        !           537:     Get_Title = proc (M: cvt) returns (string)
        !           538:        return (M.Title)
        !           539:        end Get_Title
        !           540: 
        !           541:     Set_Width = proc (M: cvt, W: int)
        !           542:        M.Width := W
        !           543:        end Set_Width
        !           544: 
        !           545:     Get_Width = proc (M: cvt) returns (int)
        !           546:        return (M.Width)
        !           547:        end Get_Width
        !           548: 
        !           549:     Set_Start = proc (M: cvt, S: int)
        !           550:        M.Start := S
        !           551:        end Set_Start
        !           552: 
        !           553:     Get_Start = proc (M: cvt) returns (int)
        !           554:        return (M.Start)
        !           555:        end Get_Start
        !           556: 
        !           557:     Append = proc (M: cvt, MI: menu_item)
        !           558:        Max_Width: int := int$Max(MI.Width, M.Max_Width)
        !           559:        MI.Start := M.Height
        !           560:        M.Height := M.Height + MI.Height
        !           561:        x_window$Change(M.White_W,
        !           562:                        Max_Width + vWExtra_Width,
        !           563:                        M.Height - vTop_Offset + vWExtra_Height)
        !           564:        x_window$Change(M.Window,
        !           565:                        Max_Width + vExtra_Width,
        !           566:                        M.Height - vTop_Offset + vExtra_Height)
        !           567:        if (Max_Width > M.Max_Width)
        !           568:           then M.Max_Width := Max_Width
        !           569:                for TMI: menu_item in mis$Elements(M.Items) do
        !           570:                    menu_item$Setup(TMI, M.Window, vLeft_Offset, M.Max_Width)
        !           571:                    end
        !           572:           end
        !           573:        M.Items := mis$AddH(M.Items, MI)
        !           574:        menu_item$Setup(MI, M.Window, vLeft_Offset, M.Max_Width)
        !           575:        end Append
        !           576: 
        !           577:     Remove = proc (M: cvt, MI: menu_item) signals (not_found)
        !           578:        Max_Width: int := 0
        !           579:        Found: bool := false
        !           580:        for Tst_MI: menu_item in mis$Elements(M.Items) do
        !           581:            if (Tst_MI = MI)
        !           582:               then Found := true
        !           583:                    continue
        !           584:               end
        !           585:            if (Found)
        !           586:               then Tst_MI.Start := Tst_MI.Start - MI.Height
        !           587:               end
        !           588:            Max_Width := int$Max(Max_Width, Tst_MI.Width)
        !           589:            end
        !           590:        if (~ Found)
        !           591:           then signal Not_Found
        !           592:           end
        !           593:        M.Height    := M.Height - MI.Height
        !           594:        x_window$Change(M.White_W,
        !           595:                        Max_Width + vWExtra_Width,
        !           596:                        M.Height - vTop_Offset + vWExtra_Height)
        !           597:        x_window$Change(M.Window,
        !           598:                        Max_Width + vExtra_Width,
        !           599:                        M.Height - vTop_Offset + vExtra_Height)
        !           600:        M.Max_Width := Max_Width
        !           601:        for TMI: menu_item in mis$Elements(M.Items) do
        !           602:            menu_item$Setup(TMI, M.Window, vLeft_Offset, M.Max_Width)
        !           603:            end
        !           604:        menu_item$Reset(MI)
        !           605:        end Remove
        !           606: 
        !           607:     Item_Changed = proc (M: cvt, MI: menu_item) signals (not_found)
        !           608:        Max_Width: int := 0
        !           609:        for Tst_MI: menu_item in mis$Elements(M.Items) do
        !           610:            Max_Width := int$Max(Max_Width, Tst_MI.Width)
        !           611:            end
        !           612:        if (Max_Width ~= M.Max_Width)
        !           613:           then M.Max_Width := Max_Width
        !           614:                x_window$Change(M.White_W,
        !           615:                                Max_Width + vWExtra_Width,
        !           616:                                M.Height - vTop_Offset + vWExtra_Height)
        !           617:                x_window$Change(M.Window,
        !           618:                                Max_Width + vExtra_Width,
        !           619:                                M.Height - vTop_Offset + vExtra_Height)
        !           620:                for TMI: menu_item in mis$Elements(M.Items) do
        !           621:                    menu_item$Setup(TMI, M.Window, vLeft_Offset, M.Max_Width)
        !           622:                    end
        !           623:           end
        !           624:        end Item_Changed
        !           625: 
        !           626:     Get_Num_Items = proc (M: cvt) returns (int)
        !           627:        return (mis$Size(M.Items))
        !           628:        end Get_Num_Items
        !           629: 
        !           630:     Get_Max_Width = proc (M: cvt) returns (int)
        !           631:        return (M.Max_Width)
        !           632:        end Get_Max_Width
        !           633: 
        !           634:     All_Items = iter (M: cvt) yields (menu_item)
        !           635:        for MI: menu_item in mis$Elements(M.Items) do
        !           636:            yield(MI)
        !           637:            end
        !           638:        end All_Items
        !           639: 
        !           640:     Get_Window = proc (M: cvt) returns (x_window)
        !           641:        return (M.Window)
        !           642:        end Get_Window
        !           643: 
        !           644:     Select = proc (M: cvt, X: int, Y: int)
        !           645:        x_window$Move(M.White_W, X-1, Y)
        !           646:        x_window$Map(M.White_W)
        !           647:        %% Lower left highlight
        !           648:        x_window$Pix_Set(M.Window, M.MB.BackPix,
        !           649:                         0,
        !           650:                         M.Height - vTop_Offset + vExtra_Height - vHighLight_Height,
        !           651:                         vHighLight_Height, vHighLight_Width)
        !           652:        %% Upper right highlight
        !           653:        x_window$Pix_Set(M.Window, M.MB.BackPix,
        !           654:                         M.Max_Width + vExtra_Width -  vHighLight_Height,
        !           655:                         0,
        !           656:                         vHighLight_Height, vHighLight_Width)
        !           657:        for MI: menu_item in mis$Elements(M.Items) do
        !           658:            menu_item$Display(MI, M.Max_Width)
        !           659:            end;
        !           660:        end Select
        !           661: 
        !           662:     DeSelect = proc (M: cvt)
        !           663:        x_window$UnMap(M.White_W)
        !           664:        end DeSelect
        !           665: 
        !           666:     end menu
        !           667: 
        !           668: menu_item = cluster is
        !           669:        create, empty, equal,
        !           670:        set_enabled,    get_enabled,
        !           671:        set_selectable, get_selectable,
        !           672:        set_text,       get_text,
        !           673:        set_checked,    get_checked,
        !           674:        get_width,      get_height,
        !           675:        set_start,      get_start,
        !           676:        setup,          reset,
        !           677:        display,
        !           678:        invert,
        !           679:        match
        !           680: 
        !           681: 
        !           682:     mw = oneof[one: x_window, none: null]
        !           683:     mf = oneof[one: x_font, none: null]
        !           684: 
        !           685:     rep = record[
        !           686:              Checked:    bool,
        !           687:              Enabled:    bool,
        !           688:              Font:       mf,
        !           689:              MB:         menu_bar,
        !           690:              Chk_Width:  int,
        !           691:              Left_Fill:  int,
        !           692:              Height:     int,
        !           693:              Selectable: bool,
        !           694:              Start:      int,
        !           695:              Text:       string,
        !           696:              Width:      int,
        !           697:              Window:     mw
        !           698:                 ]
        !           699: 
        !           700:     vCheck_String = "* "
        !           701: 
        !           702:     Create = proc (MB: menu_bar, Text: string, Font: x_font) returns (cvt) 
        !           703:               signals (error(string))
        !           704:        Avg_Width: int,
        !           705:        Height: int,
        !           706:        Ch1: char,
        !           707:        ChLast: char,
        !           708:        BaseLine: int,
        !           709:        FixedWidth: bool := x_font$Query(Font)
        !           710:           resignal Error
        !           711:        Width: int := x_font$Width(Font, Text) + 
        !           712:                      x_font$Width(Font, vCheck_String) +
        !           713:                      (vLeft_Space + vRight_Space) * Avg_Width
        !           714:        return (rep${ Checked:    false,
        !           715:                      Enabled:    true,
        !           716:                      Font:       mf$Make_One(Font),
        !           717:                      MB:         MB,
        !           718:                      Chk_Width:   x_font$Width(Font, vCheck_String),
        !           719:                      Left_Fill:  (vLeft_Space * Avg_Width),
        !           720:                      Height:     Height + vTop_Space + vBottom_Space,
        !           721:                      Selectable: true,
        !           722:                      Start:      0,
        !           723:                      Text:       Text,
        !           724:                      Width:      Width,
        !           725:                      Window:     mw$Make_None(nil) })
        !           726:        end Create
        !           727: 
        !           728:     Empty = proc (MB: menu_bar) returns (cvt)
        !           729:        vEmpty_Height = 10
        !           730:        return (rep${ Checked:    false,
        !           731:                      Enabled:    false,
        !           732:                      Font:       mf$Make_None(nil),
        !           733:                      MB:         MB,
        !           734:                      Chk_Width:  0,
        !           735:                      Left_Fill:  0,
        !           736:                      Height:     vEmpty_Height,
        !           737:                      Selectable: false,
        !           738:                      Start:      0,
        !           739:                      Text:       "",
        !           740:                      Width:      0,
        !           741:                      Window:     mw$Make_None(nil) })
        !           742:        end Empty
        !           743: 
        !           744:     Equal = proc (MI1: cvt, MI2: cvt) returns (bool)
        !           745:        return (MI1 = MI2)
        !           746:        end Equal
        !           747: 
        !           748:     Set_Enabled = proc (MI: cvt, E: bool)
        !           749:        MI.Enabled := E
        !           750:        end Set_Enabled
        !           751: 
        !           752:     Get_Enabled = proc (MI: cvt) returns (bool)
        !           753:        return (MI.Enabled)
        !           754:        end Get_Enabled
        !           755: 
        !           756:     Set_Checked = proc (MI: cvt, C: bool)
        !           757:        MI.Checked := C
        !           758:        end Set_Checked
        !           759: 
        !           760:     Get_Checked = proc (MI: cvt) returns (bool)
        !           761:        return (MI.Checked)
        !           762:        end Get_Checked
        !           763: 
        !           764:     Set_Selectable = proc (MI: cvt, S: bool)
        !           765:        MI.Selectable := S
        !           766:        end Set_Selectable
        !           767: 
        !           768:     Get_Selectable = proc (MI: cvt) returns (bool)
        !           769:        return (MI.Selectable)
        !           770:        end Get_Selectable
        !           771: 
        !           772:     Set_Text = proc (MI: cvt, Text: string) signals (is_empty)
        !           773:        Font: x_font := mf$Value_One(MI.Font)
        !           774:           except when Wrong_Tag:
        !           775:                       signal Is_Empty
        !           776:                  end
        !           777:        MI.Text := Text
        !           778:        Avg_Width: int,
        !           779:        Height: int,
        !           780:        Ch1: char,
        !           781:        ChLast: char,
        !           782:        BaseLine: int,
        !           783:        FixedWidth: bool := x_font$Query(Font)
        !           784:        MI.Width := x_font$Width(Font, Text) + 
        !           785:                    x_font$Width(Font, vCheck_String) +
        !           786:                    (vLeft_Space + vRight_Space) * Avg_Width
        !           787:        end Set_Text
        !           788: 
        !           789:     Get_Text = proc (MI: cvt) returns (string)
        !           790:        return (MI.Text)
        !           791:        end Get_Text
        !           792: 
        !           793:     Get_Width = proc (MI: cvt) returns (int)
        !           794:        return (MI.Width)
        !           795:        end Get_Width
        !           796: 
        !           797:     Get_Height = proc (MI: cvt) returns (int)
        !           798:        return (MI.Height)
        !           799:        end Get_Height
        !           800: 
        !           801:     Get_Start = proc (MI: cvt) returns (int)
        !           802:        return (MI.Start)
        !           803:        end Get_Start
        !           804: 
        !           805:     Set_Start = proc (MI: cvt, Start: int)
        !           806:        MI.Start := Start
        !           807:        end Set_Start
        !           808: 
        !           809:     Setup = proc (MI: cvt, Menu_W: x_window, Left_Start: int, Full_Width: int)
        !           810:        W: x_window := mw$Value_One(MI.Window)
        !           811:           except when Wrong_Tag:
        !           812:                       W := x_window$Create(
        !           813:                                Left_Start, MI.Start,
        !           814:                                Full_Width, MI.Height,
        !           815:                                MI.MB.Back,
        !           816:                                Menu_W,
        !           817:                                0,
        !           818:                                MI.MB.Fore)
        !           819:                       W.Input := buttonReleased + 
        !           820:                                  enterWindow +
        !           821:                                  leaveWindow
        !           822:                       W.Cursor := MI.MB.Cursor
        !           823:                       x_window$Map(W)
        !           824:                       MI.Window := mw$Make_One(W)
        !           825:                       return
        !           826:                  end
        !           827:        x_window$Change(W, Full_Width, MI.Height)
        !           828:        x_window$Move(W, Left_Start, MI.Start)
        !           829:        end Setup
        !           830: 
        !           831:     Display = proc (MI: cvt, Full_Width: int)
        !           832:        W: x_window := mw$Value_One(MI.Window)
        !           833:        if (MI.Selectable)
        !           834:           then if (MI.Checked)
        !           835:                   then x_window$Text(W,
        !           836:                                      vCheck_String, mf$Value_One(MI.Font),
        !           837:                                      MI.MB.ForePix, MI.MB.BackPix,
        !           838:                                      MI.Left_Fill, vTop_Space)
        !           839:                   end
        !           840:                x_window$Text(W,
        !           841:                              MI.Text, mf$Value_One(MI.Font),
        !           842:                              MI.MB.ForePix, MI.MB.BackPix,
        !           843:                              (MI.Left_Fill + MI.Chk_Width), vTop_Space)
        !           844:                if (~ MI.Enabled)
        !           845:                   then % x_window$Tile_Set(W, x_display$Gray(),
        !           846:                        %                 0, vTop_Space,
        !           847:                        %                 Full_Width,
        !           848:                        %                 MI.Height)
        !           849:                   end
        !           850:           end
        !           851:           except when Wrong_Tag:  %% No Font.
        !           852:                  end
        !           853:        end Display
        !           854: 
        !           855:     Reset = proc (MI: cvt)
        !           856:        x_window$Destroy(mw$Value_One(MI.Window))
        !           857:           except when Wrong_Tag:
        !           858:                       return
        !           859:                  end
        !           860:        MI.Window := mw$Make_None(nil)
        !           861:        end Reset
        !           862:  
        !           863:     Invert = proc (MI: cvt, Full_Width: int)
        !           864:        x_window$Pix_Fill(mw$Value_One(MI.Window), 0, x_bitmap$None(), 0, 0,
        !           865:                          Full_Width, MI.Height, GXinvert, MI.MB.Plane)
        !           866:           except when Wrong_Tag:
        !           867:                  end
        !           868:        end Invert
        !           869: 
        !           870:     Match = proc (MI: cvt, W: x_window) returns (bool)
        !           871:        return (mw$Value_One(MI.Window) = W)
        !           872:           except when Wrong_Tag:
        !           873:                       return (false)
        !           874:                  end
        !           875:        end Match
        !           876: 
        !           877:     end menu_item

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.