Files @ r28562:f4e6bb137cec
Branch filter:

Location: cpp/openttd-patchpack/source/src/window_gui.h - annotation

Jonathan G Rennison
Codechange: Split bit numbers from values in RailTypeFlags, RoadTypeFlags enums (#11877)
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r26613:35f34aec3be8
r8139:4fc34c1bc2fb
r8224:194097dc7288
r10208:ef8fcc3dc4ca
r9127:933c13888121
r11080:fa7a0af18489
r20630:ef21f6deaa7e
r8106:01dbd10fde05
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r11085:c87a330fb4c2
r11085:c87a330fb4c2
r8106:01dbd10fde05
r8106:01dbd10fde05
r14900:c679fdaeebe6
r8106:01dbd10fde05
r28484:6c45ae85594c
r28484:6c45ae85594c
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28120:a498e2364ad4
r26564:ef037e649ab3
r28105:28eb4146877d
r26564:ef037e649ab3
r28120:a498e2364ad4
r26564:ef037e649ab3
r26564:ef037e649ab3
r26564:ef037e649ab3
r26564:ef037e649ab3
r26564:ef037e649ab3
r26564:ef037e649ab3
r26564:ef037e649ab3
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28484:6c45ae85594c
r28544:d4a14037f165
r28544:d4a14037f165
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28484:6c45ae85594c
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r28544:d4a14037f165
r26564:ef037e649ab3
r26564:ef037e649ab3
r15292:4dd646d9f2a5
r11085:c87a330fb4c2
r26543:21aece3310ed
r28410:d9c73d685bbc
r26543:21aece3310ed
r26543:21aece3310ed
r26543:21aece3310ed
r26543:21aece3310ed
r27203:f97d3eea51fc
r8106:01dbd10fde05
r11159:7d27c716be29
r25449:15dfd9f10301
r25449:15dfd9f10301
r11159:7d27c716be29
r11159:7d27c716be29
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r13786:6205ecbdf2fa
r20398:419006c5117e
r20398:419006c5117e
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r11368:058349c3a02c
r11368:058349c3a02c
r28078:5e5d6c0447b1
r27737:728d55b97775
r27861:6269475166e0
r11456:7f48bd533d22
r11456:7f48bd533d22
r11368:058349c3a02c
r28078:5e5d6c0447b1
r28078:5e5d6c0447b1
r19944:25a78576fb5e
r11456:7f48bd533d22
r11456:7f48bd533d22
r23607:36c15679007d
r27737:728d55b97775
r27861:6269475166e0
r27861:6269475166e0
r20398:419006c5117e
r20284:215a33b6727c
r20285:68e5b14aeae7
r27737:728d55b97775
r27737:728d55b97775
r20288:668117e170ea
r27737:728d55b97775
r27737:728d55b97775
r20285:68e5b14aeae7
r20284:215a33b6727c
r20284:215a33b6727c
r20389:a738ecb74b1a
r20389:a738ecb74b1a
r27737:728d55b97775
r27737:728d55b97775
r21991:3c6b5831c12b
r20389:a738ecb74b1a
r20389:a738ecb74b1a
r20389:a738ecb74b1a
r20389:a738ecb74b1a
r20389:a738ecb74b1a
r8106:01dbd10fde05
r8106:01dbd10fde05
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r13739:747ed1f003e3
r19745:d8f95208ad9e
r19745:d8f95208ad9e
r27580:953c5017a71d
r8106:01dbd10fde05
r8106:01dbd10fde05
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r8106:01dbd10fde05
r12698:23a20e8bb850
r9273:0df9c11598cc
r12698:23a20e8bb850
r12698:23a20e8bb850
r12698:23a20e8bb850
r9273:0df9c11598cc
r9273:0df9c11598cc
r8857:5317aca8d1c7
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18773:1df705d87864
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r12513:4e8212c376c5
r12513:4e8212c376c5
r12513:4e8212c376c5
r12513:4e8212c376c5
r12516:c08ba30c5de1
r9184:cdb864f70553
r24333:94ef0c6c84e2
r12513:4e8212c376c5
r27737:728d55b97775
r27737:728d55b97775
r27737:728d55b97775
r27737:728d55b97775
r9184:cdb864f70553
r9184:cdb864f70553
r19787:20d2473dd1cb
r19787:20d2473dd1cb
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r25134:0991175ec165
r23485:fed0218478a1
r23485:fed0218478a1
r9267:fc1bdc961cd4
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8925:2b882cd5b1b6
r25564:c875d92c537a
r25564:c875d92c537a
r25564:c875d92c537a
r9142:8eefd8081b0a
r20280:ca1fc41725ff
r12344:55f4f10a88d5
r21990:cedbcf015b65
r9142:8eefd8081b0a
r23538:8df50944b27a
r17379:14ef3e1cd869
r25564:c875d92c537a
r25564:c875d92c537a
r25564:c875d92c537a
r9082:63eb44b1f81c
r20280:ca1fc41725ff
r9142:8eefd8081b0a
r13516:8be3f02950fd
r13516:8be3f02950fd
r13516:8be3f02950fd
r13516:8be3f02950fd
r13516:8be3f02950fd
r13516:8be3f02950fd
r25449:15dfd9f10301
r9082:63eb44b1f81c
r20280:ca1fc41725ff
r18667:3b72643a9c00
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r28256:2bc91b6194f4
r28256:2bc91b6194f4
r27737:728d55b97775
r27737:728d55b97775
r18667:3b72643a9c00
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r8106:01dbd10fde05
r8857:5317aca8d1c7
r8857:5317aca8d1c7
r11084:003adceca07c
r8106:01dbd10fde05
r12098:ea98e7a20927
r23607:36c15679007d
r28445:cc3abc9b847d
r28369:5011749b8738
r28351:b17bd3a7c49f
r23607:36c15679007d
r14030:1a6d55406e7d
r8106:01dbd10fde05
r28353:bfc4ab63f376
r15773:ff4666256eee
r12098:ea98e7a20927
r25449:15dfd9f10301
r8106:01dbd10fde05
r13068:ef726b675d8c
r28353:bfc4ab63f376
r13384:22c4648e5a38
r28353:bfc4ab63f376
r13062:680961bd134a
r28353:bfc4ab63f376
r28353:bfc4ab63f376
r13062:680961bd134a
r28353:bfc4ab63f376
r28353:bfc4ab63f376
r26677:ed03294010b5
r19787:20d2473dd1cb
r27869:dc15a02a4e81
r20643:19ed64eb09ff
r20652:9222c445efac
r27288:52957325547f
r20643:19ed64eb09ff
r20280:ca1fc41725ff
r28348:9ebffeb7fcc0
r20280:ca1fc41725ff
r12099:18755901efa7
r27799:ab7d36d10264
r27799:ab7d36d10264
r27799:ab7d36d10264
r28112:bca7556a6bb6
r27799:ab7d36d10264
r27799:ab7d36d10264
r11159:7d27c716be29
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18667:3b72643a9c00
r18773:1df705d87864
r28353:bfc4ab63f376
r28353:bfc4ab63f376
r18773:1df705d87864
r18667:3b72643a9c00
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r28355:6fb226bd4d6d
r28355:6fb226bd4d6d
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r13560:251ed15297e0
r11159:7d27c716be29
r8106:01dbd10fde05
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r23607:36c15679007d
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r13560:251ed15297e0
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r13560:251ed15297e0
r13560:251ed15297e0
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r11159:7d27c716be29
r28353:bfc4ab63f376
r11159:7d27c716be29
r13560:251ed15297e0
r11159:7d27c716be29
r11159:7d27c716be29
r14118:5a7149954f05
r28353:bfc4ab63f376
r13000:0de5fabb6b7b
r28353:bfc4ab63f376
r28353:bfc4ab63f376
r19780:e3df08729d5a
r28353:bfc4ab63f376
r28353:bfc4ab63f376
r8106:01dbd10fde05
r12702:8d80b3faf211
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27922:2729fb601f93
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r28127:a210f6ce658a
r28127:a210f6ce658a
r27925:68a3401ad732
r27925:68a3401ad732
r27925:68a3401ad732
r28353:bfc4ab63f376
r9082:63eb44b1f81c
r9273:0df9c11598cc
r9273:0df9c11598cc
r28353:bfc4ab63f376
r21814:76dbe7ca0bbf
r9273:0df9c11598cc
r25565:6a5de7df7ea1
r27991:0d8a4a945cd0
r25564:c875d92c537a
r10184:9c5fe3a1bdab
r9115:dd5b7219608f
r27156:89c8fe808a48
r9115:dd5b7219608f
r14030:1a6d55406e7d
r14030:1a6d55406e7d
r14030:1a6d55406e7d
r23607:36c15679007d
r14030:1a6d55406e7d
r14030:1a6d55406e7d
r14030:1a6d55406e7d
r14030:1a6d55406e7d
r18667:3b72643a9c00
r18667:3b72643a9c00
r18773:1df705d87864
r17379:14ef3e1cd869
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r13809:115a4521641e
r28350:2ccb2f8f699f
r13809:115a4521641e
r13809:115a4521641e
r13809:115a4521641e
r20285:68e5b14aeae7
r20285:68e5b14aeae7
r13809:115a4521641e
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r27737:728d55b97775
r13396:9a85c6cac76a
r13396:9a85c6cac76a
r12264:fea334a13752
r12264:fea334a13752
r9166:f7d35b4ebc22
r16591:81de49de095c
r16591:81de49de095c
r16591:81de49de095c
r16591:81de49de095c
r9166:f7d35b4ebc22
r11081:725ce4237987
r12264:fea334a13752
r12264:fea334a13752
r12264:fea334a13752
r12264:fea334a13752
r12264:fea334a13752
r28353:bfc4ab63f376
r12264:fea334a13752
r12264:fea334a13752
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r12427:88c1949f3666
r13695:e0bf1a35834a
r12427:88c1949f3666
r12313:f8317da11c46
r28353:bfc4ab63f376
r12313:f8317da11c46
r12313:f8317da11c46
r12506:9513e5fe26bf
r12506:9513e5fe26bf
r12506:9513e5fe26bf
r12506:9513e5fe26bf
r12506:9513e5fe26bf
r28353:bfc4ab63f376
r12506:9513e5fe26bf
r27570:dc26d10816f1
r27570:dc26d10816f1
r27570:dc26d10816f1
r23914:c5deff3c5b90
r11081:725ce4237987
r27570:dc26d10816f1
r27570:dc26d10816f1
r27570:dc26d10816f1
r27570:dc26d10816f1
r27570:dc26d10816f1
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r13812:cb6499cc6628
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r20398:419006c5117e
r20398:419006c5117e
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r13812:cb6499cc6628
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9317:9275560f46df
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r14399:3f819c0da60a
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r15486:d71d1a627ee5
r15486:d71d1a627ee5
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r23485:fed0218478a1
r15462:27da1dfa46e0
r15462:27da1dfa46e0
r15462:27da1dfa46e0
r28353:bfc4ab63f376
r15462:27da1dfa46e0
r15462:27da1dfa46e0
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r23485:fed0218478a1
r28353:bfc4ab63f376
r23485:fed0218478a1
r23485:fed0218478a1
r15241:1536e1ddc5ef
r15241:1536e1ddc5ef
r15241:1536e1ddc5ef
r15241:1536e1ddc5ef
r28353:bfc4ab63f376
r15241:1536e1ddc5ef
r15241:1536e1ddc5ef
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9317:9275560f46df
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r23124:8fa6d269005b
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r23124:8fa6d269005b
r23124:8fa6d269005b
r27942:f7389062d120
r23124:8fa6d269005b
r23124:8fa6d269005b
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9317:9275560f46df
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r11519:80d5a7e0eeb8
r12516:c08ba30c5de1
r9166:f7d35b4ebc22
r13334:52f3226937dd
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r9166:f7d35b4ebc22
r28353:bfc4ab63f376
r19390:275f04088f5c
r9166:f7d35b4ebc22
r19779:721c0094fe5a
r19779:721c0094fe5a
r19779:721c0094fe5a
r28353:bfc4ab63f376
r19779:721c0094fe5a
r19779:721c0094fe5a
r9166:f7d35b4ebc22
r23607:36c15679007d
r14335:7a29cdf9bb36
r14335:7a29cdf9bb36
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r17476:d3b7a183536d
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r16050:f8b5963745b7
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r16050:f8b5963745b7
r27942:f7389062d120
r16050:f8b5963745b7
r16050:f8b5963745b7
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r27942:f7389062d120
r26613:35f34aec3be8
r26613:35f34aec3be8
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9317:9275560f46df
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r27942:f7389062d120
r9166:f7d35b4ebc22
r9166:f7d35b4ebc22
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r15070:eb6f0a8e1d86
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25446:9682bee6326c
r25446:9682bee6326c
r25446:9682bee6326c
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25449:15dfd9f10301
r25309:481585034052
r25309:481585034052
r25449:15dfd9f10301
r25447:018c1f2f90ee
r25309:481585034052
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25309:481585034052
r25447:018c1f2f90ee
r25447:018c1f2f90ee
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25309:481585034052
r25446:9682bee6326c
r25447:018c1f2f90ee
r25447:018c1f2f90ee
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25449:15dfd9f10301
r25309:481585034052
r25448:e6a2acfde755
r25447:018c1f2f90ee
r25447:018c1f2f90ee
r8106:01dbd10fde05
r8106:01dbd10fde05
r15610:623a23fb6560
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r26613:35f34aec3be8
r15610:623a23fb6560
r13062:680961bd134a
r13062:680961bd134a
r23607:36c15679007d
r13062:680961bd134a
r13062:680961bd134a
r28353:bfc4ab63f376
r13062:680961bd134a
r28351:b17bd3a7c49f
r28351:b17bd3a7c49f
r28351:b17bd3a7c49f
r23607:36c15679007d
r13062:680961bd134a
r13062:680961bd134a
r13062:680961bd134a
r13062:680961bd134a
r13062:680961bd134a
r28353:bfc4ab63f376
r13062:680961bd134a
r28351:b17bd3a7c49f
r28351:b17bd3a7c49f
r28351:b17bd3a7c49f
r13062:680961bd134a
r13062:680961bd134a
r15610:623a23fb6560
r15610:623a23fb6560
r13384:22c4648e5a38
r13384:22c4648e5a38
r23607:36c15679007d
r13384:22c4648e5a38
r13384:22c4648e5a38
r28353:bfc4ab63f376
r13384:22c4648e5a38
r13384:22c4648e5a38
r13384:22c4648e5a38
r13384:22c4648e5a38
r13062:680961bd134a
r9267:fc1bdc961cd4
r12448:183925908279
r9267:fc1bdc961cd4
r9267:fc1bdc961cd4
r9267:fc1bdc961cd4
r9267:fc1bdc961cd4
r20280:ca1fc41725ff
r12448:183925908279
r12448:183925908279
r17056:6d2c96219506
r12448:183925908279
r27991:0d8a4a945cd0
r9267:fc1bdc961cd4
r9267:fc1bdc961cd4
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r27799:ab7d36d10264
r27799:ab7d36d10264
r27799:ab7d36d10264
r28112:bca7556a6bb6
r27799:ab7d36d10264
r27799:ab7d36d10264
r9143:e484ce861c88
r9143:e484ce861c88
r21930:fe446f7b57e5
r10238:f2215d7dd22b
r9143:e484ce861c88
r21931:d35ef28a5c46
r23607:36c15679007d
r9143:e484ce861c88
r9143:e484ce861c88
r21931:d35ef28a5c46
r9143:e484ce861c88
r21931:d35ef28a5c46
r23607:36c15679007d
r9203:1587086284e7
r9143:e484ce861c88
r8106:01dbd10fde05
r8106:01dbd10fde05
r8106:01dbd10fde05
r27591:abff3cb311c1
r8106:01dbd10fde05
r8106:01dbd10fde05
r28353:bfc4ab63f376
r8106:01dbd10fde05
r8268:4e9851bbf247
r8106:01dbd10fde05
r8268:4e9851bbf247
r8268:4e9851bbf247
r8268:4e9851bbf247
r8106:01dbd10fde05
r8268:4e9851bbf247
r15459:b0230d10448f
r8106:01dbd10fde05
r15258:e76d2b83d072
r8106:01dbd10fde05
r15258:e76d2b83d072
r24510:ec6a3064485b
r15258:e76d2b83d072
r15258:e76d2b83d072
r24510:ec6a3064485b
r8106:01dbd10fde05
r15258:e76d2b83d072
r8106:01dbd10fde05
r11081:725ce4237987
r11081:725ce4237987
r15773:ff4666256eee
r8106:01dbd10fde05
r8106:01dbd10fde05
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file window_gui.h Functions, definitions and such used only by the GUI. */

#ifndef WINDOW_GUI_H
#define WINDOW_GUI_H

#include "vehiclelist.h"
#include "vehicle_type.h"
#include "viewport_type.h"
#include "company_type.h"
#include "tile_type.h"
#include "widget_type.h"
#include "string_type.h"

/**
 * Flags to describe the look of the frame
 */
enum FrameFlags {
	FR_NONE         =  0,
	FR_TRANSPARENT  =  1 << 0,  ///< Makes the background transparent if set
	FR_BORDERONLY   =  1 << 4,  ///< Draw border only, no background
	FR_LOWERED      =  1 << 5,  ///< If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
	FR_DARKENED     =  1 << 6,  ///< If set the background is darker, allows for lowered frames with normal background colour when used with FR_LOWERED (ie. dropdown boxes)
};

DECLARE_ENUM_AS_BIT_SET(FrameFlags)

class WidgetDimensions {
public:
	RectPadding imgbtn;        ///< Padding around image button image.
	RectPadding inset;         ///< Padding inside inset container.
	RectPadding vscrollbar;    ///< Padding inside vertical scrollbar buttons.
	RectPadding hscrollbar;    ///< Padding inside horizontal scrollbar buttons.
	RectPadding bevel;         ///< Bevel thickness, affected by "scaled bevels" game option.
	RectPadding fullbevel;     ///< Always-scaled bevel thickness.
	RectPadding framerect;     ///< Standard padding inside many panels.
	RectPadding frametext;     ///< Padding inside frame with text.
	RectPadding matrix;        ///< Padding of WWT_MATRIX items.
	RectPadding shadebox;      ///< Padding around image in shadebox widget.
	RectPadding stickybox;     ///< Padding around image in stickybox widget.
	RectPadding debugbox;      ///< Padding around image in debugbox widget.
	RectPadding defsizebox;    ///< Padding around image in defsizebox widget.
	RectPadding resizebox;     ///< Padding around image in resizebox widget.
	RectPadding closebox;      ///< Padding around image in closebox widget.
	RectPadding captiontext;   ///< Padding for text within caption widget.
	RectPadding dropdowntext;  ///< Padding of drop down list item.
	RectPadding dropdownlist;  ///< Padding of complete drop down list.
	RectPadding modalpopup;    ///< Spacing for popup warning/information windows.
	RectPadding picker;        ///< Padding for a picker (dock, station, etc) window.
	RectPadding sparse;        ///< Padding used for 'sparse' widget window, usually containing multiple frames.
	RectPadding sparse_resize; ///< Padding used for a resizeable 'sparse' widget window, usually containing multiple frames.

	int vsep_picker;          ///< Vertical spacing of picker-window widgets.
	int vsep_normal;          ///< Normal vertical spacing.
	int vsep_sparse;          ///< Normal vertical spacing for 'sparse' widget window.
	int vsep_wide;            ///< Wide vertical spacing.
	int hsep_normal;          ///< Normal horizontal spacing.
	int hsep_wide;            ///< Wide horizontal spacing.
	int hsep_indent;          ///< Width of identation for tree layouts.

	static const WidgetDimensions unscaled; ///< Unscaled widget dimensions.
	static WidgetDimensions scaled;         ///< Widget dimensions scaled for current zoom level.

private:
	/**
	 * Distances used in drawing widgets.
	 * These constants should not be used elsewhere, use scaled/unscaled WidgetDimensions instead.
	 */
	enum WidgetDrawDistances {
		WD_SHADEBOX_WIDTH   = 12, ///< Minimum width of a standard shade box widget.
		WD_STICKYBOX_WIDTH  = 12, ///< Minimum width of a standard sticky box widget.
		WD_DEBUGBOX_WIDTH   = 12, ///< Minimum width of a standard debug box widget.
		WD_DEFSIZEBOX_WIDTH = 12, ///< Minimum width of a standard defsize box widget.
		WD_RESIZEBOX_WIDTH  = 12, ///< Minimum width of a resize box widget.
		WD_CLOSEBOX_WIDTH   = 11, ///< Minimum width of a close box widget.

		WD_CAPTION_HEIGHT   = 14, ///< Minimum height of a title bar.
		WD_DROPDOWN_HEIGHT  = 12, ///< Minimum height of a drop down widget.
	};

	friend NWidgetLeaf;
};

inline constexpr WidgetDimensions WidgetDimensions::unscaled = {
	.imgbtn        = { .left =  1, .top =  1, .right =  1, .bottom =  1},
	.inset         = { .left =  2, .top =  1, .right =  2, .bottom =  1},
	.vscrollbar    = { .left =  2, .top =  3, .right =  2, .bottom =  3},
	.hscrollbar    = { .left =  3, .top =  2, .right =  3, .bottom =  2},
	.bevel         = { .left =  1, .top =  1, .right =  1, .bottom =  1},
	.fullbevel     = { .left =  1, .top =  1, .right =  1, .bottom =  1},
	.framerect     = { .left =  2, .top =  1, .right =  2, .bottom =  1},
	.frametext     = { .left =  6, .top =  6, .right =  6, .bottom =  6},
	.matrix        = { .left =  2, .top =  3, .right =  2, .bottom =  1},
	.shadebox      = { .left =  2, .top =  3, .right =  2, .bottom =  3},
	.stickybox     = { .left =  2, .top =  3, .right =  2, .bottom =  3},
	.debugbox      = { .left =  2, .top =  3, .right =  2, .bottom =  3},
	.defsizebox    = { .left =  2, .top =  3, .right =  2, .bottom =  3},
	.resizebox     = { .left =  2, .top =  2, .right =  2, .bottom =  2},
	.closebox      = { .left =  2, .top =  2, .right =  1, .bottom =  2},
	.captiontext   = { .left =  2, .top =  2, .right =  2, .bottom =  2},
	.dropdowntext  = { .left =  2, .top =  1, .right =  2, .bottom =  1},
	.dropdownlist  = { .left =  1, .top =  2, .right =  1, .bottom =  2},
	.modalpopup    = { .left = 20, .top = 10, .right = 20, .bottom = 10},
	.picker        = { .left =  3, .top =  3, .right =  3, .bottom =  3},
	.sparse        = { .left = 10, .top =  8, .right = 10, .bottom =  8},
	.sparse_resize = { .left = 10, .top =  8, .right = 10, .bottom =  0},
	.vsep_picker   = 1,
	.vsep_normal   = 2,
	.vsep_sparse   = 4,
	.vsep_wide     = 8,
	.hsep_normal   = 2,
	.hsep_wide     = 6,
	.hsep_indent   = 10,
};

/* widget.cpp */
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);

inline void DrawFrameRect(const Rect &r, Colours colour, FrameFlags flags)
{
	DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, flags);
}

void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_colour, StringID str, StringAlignment align, FontSize fs);

/* window.cpp */
using WindowList = std::list<Window *>;
extern WindowList _z_windows;
extern Window *_focused_window;


/** How do we the window to be placed? */
enum WindowPosition {
	WDP_MANUAL,        ///< Manually align the window (so no automatic location finding)
	WDP_AUTO,          ///< Find a place automatically
	WDP_CENTER,        ///< Center the window
	WDP_ALIGN_TOOLBAR, ///< Align toward the toolbar
};

Point GetToolbarAlignedWindowPosition(int window_width);

struct HotkeyList;

/**
 * High level window description
 */
struct WindowDesc : ZeroedMemoryAllocator {

	WindowDesc(const char * const file, const int line, WindowPosition default_pos, const char *ini_key, int16_t def_width_trad, int16_t def_height_trad,
			WindowClass window_class, WindowClass parent_class, uint32_t flags,
			const NWidgetPart *nwid_begin, const NWidgetPart *nwid_end, HotkeyList *hotkeys = nullptr);

	~WindowDesc();

	const char * const file; ///< Source file of this definition
	const int line; ///< Source line of this definition
	WindowPosition default_pos;    ///< Preferred position of the window. @see WindowPosition()
	WindowClass cls;               ///< Class of the window, @see WindowClass.
	WindowClass parent_cls;        ///< Class of the parent window. @see WindowClass
	const char *ini_key;           ///< Key to store window defaults in openttd.cfg. \c nullptr if nothing shall be stored.
	uint32_t flags;                  ///< Flags. @see WindowDefaultFlag
	const NWidgetPart *nwid_begin; ///< Beginning of nested widget parts describing the window.
	const NWidgetPart *nwid_end; ///< Ending of nested widget parts describing the window.
	HotkeyList *hotkeys;           ///< Hotkeys for the window.

	bool pref_sticky;              ///< Preferred stickyness.
	int16_t pref_width;              ///< User-preferred width of the window. Zero if unset.
	int16_t pref_height;             ///< User-preferred height of the window. Zero if unset.

	int16_t GetDefaultWidth() const;
	int16_t GetDefaultHeight() const;

	static void LoadFromConfig();
	static void SaveToConfig();

private:
	int16_t default_width_trad;      ///< Preferred initial width of the window (pixels at 1x zoom).
	int16_t default_height_trad;     ///< Preferred initial height of the window (pixels at 1x zoom).

	/**
	 * Dummy private copy constructor to prevent compilers from
	 * copying the structure, which fails due to _window_descs.
	 */
	WindowDesc(const WindowDesc &other);
};

/**
 * Window default widget/window handling flags
 */
enum WindowDefaultFlag {
	WDF_CONSTRUCTION    =   1 << 0, ///< This window is used for construction; close it whenever changing company.
	WDF_MODAL           =   1 << 1, ///< The window is a modal child of some other window, meaning the parent is 'inactive'
	WDF_NO_FOCUS        =   1 << 2, ///< This window won't get focus/make any other window lose focus when click
	WDF_NO_CLOSE        =   1 << 3, ///< This window can't be interactively closed
};

/**
 * Data structure for resizing a window
 */
struct ResizeInfo {
	uint step_width;  ///< Step-size of width resize changes
	uint step_height; ///< Step-size of height resize changes
};

/** State of a sort direction button. */
enum SortButtonState {
	SBS_OFF,  ///< Do not sort (with this button).
	SBS_DOWN, ///< Sort ascending.
	SBS_UP,   ///< Sort descending.
};

/**
 * Window flags.
 */
enum WindowFlags {
	WF_TIMEOUT           = 1 <<  0, ///< Window timeout counter.

	WF_DRAGGING          = 1 <<  3, ///< Window is being dragged.
	WF_SIZING_RIGHT      = 1 <<  4, ///< Window is being resized towards the right.
	WF_SIZING_LEFT       = 1 <<  5, ///< Window is being resized towards the left.
	WF_SIZING            = WF_SIZING_RIGHT | WF_SIZING_LEFT, ///< Window is being resized.
	WF_STICKY            = 1 <<  6, ///< Window is made sticky by user
	WF_DISABLE_VP_SCROLL = 1 <<  7, ///< Window does not do autoscroll, @see HandleAutoscroll().
	WF_WHITE_BORDER      = 1 <<  8, ///< Window white border counter bit mask.
	WF_HIGHLIGHTED       = 1 <<  9, ///< Window has a widget that has a highlight.
	WF_CENTERED          = 1 << 10, ///< Window is centered and shall stay centered after ReInit.
};
DECLARE_ENUM_AS_BIT_SET(WindowFlags)

static const int TIMEOUT_DURATION = 7; ///< The initial timeout value for WF_TIMEOUT.
static const int WHITE_BORDER_DURATION = 3; ///< The initial timeout value for WF_WHITE_BORDER.

/**
 * Data structure for a window viewport.
 * A viewport is either following a vehicle (its id in then in #follow_vehicle), or it aims to display a specific
 * location #dest_scrollpos_x, #dest_scrollpos_y (#follow_vehicle is then #INVALID_VEHICLE).
 * The actual location being shown is #scrollpos_x, #scrollpos_y.
 * @see InitializeViewport(), UpdateViewportPosition(), UpdateViewportCoordinates().
 */
struct ViewportData : Viewport {
	VehicleID follow_vehicle; ///< VehicleID to follow if following a vehicle, #INVALID_VEHICLE otherwise.
	int32_t scrollpos_x;        ///< Currently shown x coordinate (virtual screen coordinate of topleft corner of the viewport).
	int32_t scrollpos_y;        ///< Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
	int32_t dest_scrollpos_x;   ///< Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewport).
	int32_t dest_scrollpos_y;   ///< Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewport).
};

struct QueryString;

/* misc_gui.cpp */
enum TooltipCloseCondition {
	TCC_RIGHT_CLICK,
	TCC_HOVER,
	TCC_NONE,
	TCC_EXIT_VIEWPORT,
};

/**
 * Data structure for an opened window
 */
struct Window : ZeroedMemoryAllocator {
private:
	static std::vector<Window *> closed_windows;

protected:
	void InitializeData(WindowNumber window_number);
	void InitializePositionSize(int x, int y, int min_width, int min_height);
	virtual void FindWindowPlacementAndResize(int def_width, int def_height);

	std::vector<int> scheduled_invalidation_data;  ///< Data of scheduled OnInvalidateData() calls.

	/* Protected to prevent deletion anywhere outside Window::DeleteClosedWindows(). */
	virtual ~Window();

public:
	Window(WindowDesc *desc);

	/**
	 * Helper allocation function to disallow something.
	 * Don't allow arrays; arrays of Windows are pointless as you need
	 * to destruct them all at the same time too, which is kinda hard.
	 * @param size the amount of space not to allocate
	 */
	inline void *operator new[](size_t size) = delete;

	WindowDesc *window_desc;    ///< Window description
	WindowFlags flags;          ///< Window flags
	WindowClass window_class;   ///< Window class
	WindowNumber window_number; ///< Window number within the window class

	int scale; ///< Scale of this window -- used to determine how to resize.

	uint8_t timeout_timer;      ///< Timer value of the WF_TIMEOUT for flags.
	uint8_t white_border_timer; ///< Timer value of the WF_WHITE_BORDER for flags.

	int left;   ///< x position of left edge of the window
	int top;    ///< y position of top edge of the window
	int width;  ///< width of the window (number of pixels to the right in x direction)
	int height; ///< Height of the window (number of pixels down in y direction)

	ResizeInfo resize;  ///< Resize information

	Owner owner;        ///< The owner of the content shown in this window. Company colour is acquired from this variable.

	ViewportData *viewport;          ///< Pointer to viewport data, if present.
	const NWidgetCore *nested_focus; ///< Currently focused nested widget, or \c nullptr if no nested widget has focus.
	std::map<WidgetID, QueryString*> querystrings; ///< QueryString associated to WWT_EDITBOX widgets.
	std::unique_ptr<NWidgetBase> nested_root; ///< Root of the nested tree.
	WidgetLookup widget_lookup; ///< Indexed access to the nested widget tree. Do not access directly, use #Window::GetWidget() instead.
	NWidgetStacked *shade_select;    ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c nullptr, window cannot shade.
	Dimension unshaded_size;         ///< Last known unshaded size (only valid while shaded).

	WidgetID mouse_capture_widget;   ///< ID of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture.

	Window *parent;                  ///< Parent window.
	WindowList::iterator z_position;

	template <class NWID>
	inline const NWID *GetWidget(WidgetID widnum) const;
	template <class NWID>
	inline NWID *GetWidget(WidgetID widnum);

	const Scrollbar *GetScrollbar(WidgetID widnum) const;
	Scrollbar *GetScrollbar(WidgetID widnum);

	const QueryString *GetQueryString(WidgetID widnum) const;
	QueryString *GetQueryString(WidgetID widnum);
	void UpdateQueryStringSize();

	virtual const struct Textbuf *GetFocusedTextbuf() const;
	virtual Point GetCaretPosition() const;
	virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
	virtual ptrdiff_t GetTextCharacterAtPosition(const Point &pt) const;

	void InitNested(WindowNumber number = 0);
	void CreateNestedTree();
	void FinishInitNested(WindowNumber window_number = 0);

	template<typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
	void FinishInitNested(T number)
	{
		this->FinishInitNested(number.base());
	}

	/**
	 * Set the timeout flag of the window and initiate the timer.
	 */
	inline void SetTimeout()
	{
		this->flags |= WF_TIMEOUT;
		this->timeout_timer = TIMEOUT_DURATION;
	}

	/**
	 * Set the timeout flag of the window and initiate the timer.
	 */
	inline void SetWhiteBorder()
	{
		this->flags |= WF_WHITE_BORDER;
		this->white_border_timer = WHITE_BORDER_DURATION;
	}

	void DisableAllWidgetHighlight();
	void SetWidgetHighlight(WidgetID widget_index, TextColour highlighted_colour);
	bool IsWidgetHighlighted(WidgetID widget_index) const;

	/**
	 * Sets the enabled/disabled status of a widget.
	 * By default, widgets are enabled.
	 * On certain conditions, they have to be disabled.
	 * @param widget_index index of this widget in the window
	 * @param disab_stat status to use ie: disabled = true, enabled = false
	 */
	inline void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
	{
		NWidgetCore *nwid = this->GetWidget<NWidgetCore>(widget_index);
		if (nwid != nullptr) nwid->SetDisabled(disab_stat);
	}

	/**
	 * Sets a widget to disabled.
	 * @param widget_index index of this widget in the window
	 */
	inline void DisableWidget(WidgetID widget_index)
	{
		SetWidgetDisabledState(widget_index, true);
	}

	/**
	 * Sets a widget to Enabled.
	 * @param widget_index index of this widget in the window
	 */
	inline void EnableWidget(WidgetID widget_index)
	{
		SetWidgetDisabledState(widget_index, false);
	}

	/**
	 * Gets the enabled/disabled status of a widget.
	 * @param widget_index index of this widget in the window
	 * @return status of the widget ie: disabled = true, enabled = false
	 */
	inline bool IsWidgetDisabled(WidgetID widget_index) const
	{
		return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
	}

	/**
	 * Check if given widget is focused within this window
	 * @param widget_index : index of the widget in the window to check
	 * @return true if given widget is the focused window in this window
	 */
	inline bool IsWidgetFocused(WidgetID widget_index) const
	{
		return this->nested_focus != nullptr && this->nested_focus->index == widget_index;
	}

	/**
	 * Check if given widget has user input focus. This means that both the window
	 * has focus and that the given widget has focus within the window.
	 * @param widget_index : index of the widget in the window to check
	 * @return true if given widget is the focused window in this window and this window has focus
	 */
	inline bool IsWidgetGloballyFocused(WidgetID widget_index) const
	{
		return _focused_window == this && IsWidgetFocused(widget_index);
	}

	/**
	 * Sets the lowered/raised status of a widget.
	 * @param widget_index index of this widget in the window
	 * @param lowered_stat status to use ie: lowered = true, raised = false
	 */
	inline void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
	{
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
	}

	/**
	 * Invert the lowered/raised  status of a widget.
	 * @param widget_index index of this widget in the window
	 */
	inline void ToggleWidgetLoweredState(WidgetID widget_index)
	{
		bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
		this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
	}

	/**
	 * Marks a widget as lowered.
	 * @param widget_index index of this widget in the window
	 */
	inline void LowerWidget(WidgetID widget_index)
	{
		SetWidgetLoweredState(widget_index, true);
	}

	/**
	 * Marks a widget as raised.
	 * @param widget_index index of this widget in the window
	 */
	inline void RaiseWidget(WidgetID widget_index)
	{
		SetWidgetLoweredState(widget_index, false);
	}

	/**
	 * Marks a widget as raised and dirty (redraw), when it is marked as lowered.
	 * @param widget_index index of this widget in the window
	 */
	inline void RaiseWidgetWhenLowered(byte widget_index)
	{
		if (this->IsWidgetLowered(widget_index)) {
			this->RaiseWidget(widget_index);
			this->SetWidgetDirty(widget_index);
		}
	}

	/**
	 * Gets the lowered state of a widget.
	 * @param widget_index index of this widget in the window
	 * @return status of the widget ie: lowered = true, raised= false
	 */
	inline bool IsWidgetLowered(WidgetID widget_index) const
	{
		return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
	}

	void UnfocusFocusedWidget();
	bool SetFocusedWidget(WidgetID widget_index);

	EventState HandleEditBoxKey(WidgetID wid, char32_t key, uint16_t keycode);
	virtual void InsertTextString(WidgetID wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end);

	void HandleButtonClick(WidgetID widget);
	int GetRowFromWidget(int clickpos, WidgetID widget, int padding, int line_height = -1) const;

	void RaiseButtons(bool autoraise = false);

	/**
	 * Sets the enabled/disabled status of a list of widgets.
	 * By default, widgets are enabled.
	 * On certain conditions, they have to be disabled.
	 * @param disab_stat status to use ie: disabled = true, enabled = false
	 * @param widgets list of widgets
	 */
	template<typename... Args>
	void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
	{
		(SetWidgetDisabledState(widgets, disab_stat), ...);
	}

	/**
	 * Sets the lowered/raised status of a list of widgets.
	 * @param lowered_stat status to use ie: lowered = true, raised = false
	 * @param widgets list of widgets
	 */
	template<typename... Args>
	void SetWidgetsLoweredState(bool lowered_stat, Args... widgets)
	{
		(SetWidgetLoweredState(widgets, lowered_stat), ...);
	}

	/**
	 * Raises the widgets and sets widgets dirty that are lowered.
	 * @param widgets list of widgets
	 */
	template<typename... Args>
	void RaiseWidgetsWhenLowered(Args... widgets)
	{
		(this->RaiseWidgetWhenLowered(widgets), ...);
	}

	void SetWidgetDirty(WidgetID widget_index) const;

	void DrawWidgets() const;
	void DrawViewport() const;
	void DrawSortButtonState(WidgetID widget, SortButtonState state) const;
	static int SortButtonWidth();

	void CloseChildWindows(WindowClass wc = WC_INVALID) const;
	virtual void Close(int data = 0);
	static void DeleteClosedWindows();

	void SetDirty() const;
	void ReInit(int rx = 0, int ry = 0, bool reposition = false);

	/** Is window shaded currently? */
	inline bool IsShaded() const
	{
		return this->shade_select != nullptr && this->shade_select->shown_plane == SZSP_HORIZONTAL;
	}

	void SetShaded(bool make_shaded);

	void InvalidateData(int data = 0, bool gui_scope = true);
	void ProcessScheduledInvalidations();
	void ProcessHighlightedInvalidations();

	/*** Event handling ***/

	/**
	 * Notification that the nested widget tree gets initialized. The event can be used to perform general computations.
	 * @note #nested_root and/or #widget_lookup (normally accessed via #GetWidget()) may not exist during this call.
	 */
	virtual void OnInit() { }

	virtual void ApplyDefaults();

	/**
	 * Compute the initial position of the window.
	 * @param sm_width      Smallest width of the window.
	 * @param sm_height     Smallest height of the window.
	 * @param window_number The window number of the new window.
	 * @return Initial position of the top-left corner of the window.
	 */
	virtual Point OnInitialPosition(int16_t sm_width, int16_t sm_height, int window_number);

	/**
	 * The window must be repainted.
	 * @note This method should not change any state, it should only use drawing functions.
	 */
	virtual void OnPaint()
	{
		this->DrawWidgets();
	}

	/**
	 * Draw the contents of a nested widget.
	 * @param r      Rectangle occupied by the widget.
	 * @param widget Number of the widget to draw.
	 * @note This method may not change any state, it may only use drawing functions.
	 */
	virtual void DrawWidget([[maybe_unused]] const Rect &r, [[maybe_unused]] WidgetID widget) const {}

	/**
	 * Update size and resize step of a widget in the window.
	 * After retrieval of the minimal size and the resize-steps of a widget, this function is called to allow further refinement,
	 * typically by computing the real maximal size of the content. Afterwards, \a size is taken to be the minimal size of the widget
	 * and \a resize is taken to contain the resize steps. For the convenience of the callee, \a padding contains the amount of
	 * padding between the content and the edge of the widget. This should be added to the returned size.
	 * @param widget  Widget number.
	 * @param size    Size of the widget.
	 * @param padding Recommended amount of space between the widget content and the widget edge.
	 * @param fill    Fill step of the widget.
	 * @param resize  Resize step of the widget.
	 */
	virtual void UpdateWidgetSize([[maybe_unused]] WidgetID widget, [[maybe_unused]] Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) {}

	/**
	 * Initialize string parameters for a widget.
	 * Calls to this function are made during initialization to measure the size (that is as part of #InitNested()), during drawing,
	 * and while re-initializing the window. Only for widgets that render text initializing is requested.
	 * @param widget  Widget number.
	 */
	virtual void SetStringParameters([[maybe_unused]] WidgetID widget) const {}

	/**
	 * The window has gained focus.
	 */
	virtual void OnFocus();

	/**
	 * The window has lost focus.
	 * @param closing True iff the window has lost focus in the process of closing.
	 */
	virtual void OnFocusLost(bool closing);

	/**
	 * A key has been pressed.
	 * @param key     the Unicode value of the key.
	 * @param keycode the untranslated key code including shift state.
	 * @return #ES_HANDLED if the key press has been handled and no other
	 *         window should receive the event.
	 */
	virtual EventState OnKeyPress([[maybe_unused]] char32_t key, [[maybe_unused]] uint16_t keycode) { return ES_NOT_HANDLED; }

	virtual EventState OnHotkey(int hotkey);

	/**
	 * The state of the control key has changed
	 * @return #ES_HANDLED if the change has been handled and no other
	 *         window should receive the event.
	 */
	virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }


	/**
	 * A click with the left mouse button has been made on the window.
	 * @param pt     the point inside the window that has been clicked.
	 * @param widget the clicked widget.
	 * @param click_count Number of fast consecutive clicks at same position
	 */
	virtual void OnClick([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget, [[maybe_unused]] int click_count) {}

	/**
	 * A click with the right mouse button has been made on the window.
	 * @param pt     the point inside the window that has been clicked.
	 * @param widget the clicked widget.
	 * @return true if the click was actually handled, i.e. do not show a
	 *         tooltip if tooltip-on-right-click is enabled.
	 */
	virtual bool OnRightClick([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget) { return false; }

	/**
	 * The mouse is hovering over a widget in the window, perform an action for it.
	 * @param pt     The point where the mouse is hovering.
	 * @param widget The widget where the mouse is hovering.
	 */
	virtual void OnHover([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget) {}

	/**
	 * Event to display a custom tooltip.
	 * @param pt     The point where the mouse is located.
	 * @param widget The widget where the mouse is located.
	 * @return True if the event is handled, false if it is ignored.
	 */
	virtual bool OnTooltip([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget, [[maybe_unused]] TooltipCloseCondition close_cond) { return false; }

	/**
	 * An 'object' is being dragged at the provided position, highlight the target if possible.
	 * @param pt     The point inside the window that the mouse hovers over.
	 * @param widget The widget the mouse hovers over.
	 */
	virtual void OnMouseDrag([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget) {}

	/**
	 * A dragged 'object' has been released.
	 * @param pt     the point inside the window where the release took place.
	 * @param widget the widget where the release took place.
	 */
	virtual void OnDragDrop([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget) {}

	/**
	 * Handle the request for (viewport) scrolling.
	 * @param delta the amount the viewport must be scrolled.
	 */
	virtual void OnScroll([[maybe_unused]] Point delta) {}

	/**
	 * The mouse is currently moving over the window or has just moved outside
	 * of the window. In the latter case pt is (-1, -1).
	 * @param pt     the point inside the window that the mouse hovers over.
	 * @param widget the widget the mouse hovers over.
	 */
	virtual void OnMouseOver([[maybe_unused]] Point pt, [[maybe_unused]] WidgetID widget) {}

	/**
	 * The mouse wheel has been turned.
	 * @param wheel the amount of movement of the mouse wheel.
	 */
	virtual void OnMouseWheel([[maybe_unused]] int wheel) {}


	/**
	 * Called for every mouse loop run, which is at least once per (game) tick.
	 */
	virtual void OnMouseLoop() {}

	/**
	 * Called once per (game) tick.
	 */
	virtual void OnGameTick() {}

	/**
	 * Called periodically.
	 */
	virtual void OnRealtimeTick([[maybe_unused]] uint delta_ms) {}

	/**
	 * Called when this window's timeout has been reached.
	 */
	virtual void OnTimeout() {}


	/**
	 * Called after the window got resized.
	 * For nested windows with a viewport, call NWidgetViewport::UpdateViewportCoordinates.
	 */
	virtual void OnResize() {}

	/**
	 * A dropdown option associated to this window has been selected.
	 * @param widget the widget (button) that the dropdown is associated with.
	 * @param index  the element in the dropdown that is selected.
	 */
	virtual void OnDropdownSelect([[maybe_unused]] WidgetID widget, [[maybe_unused]] int index) {}

	virtual void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close);

	/**
	 * The text in an editbox has been edited.
	 * @param widget The widget of the editbox.
	 */
	virtual void OnEditboxChanged([[maybe_unused]] WidgetID widget) {}

	/**
	 * The query window opened from this window has closed.
	 * @param str the new value of the string, nullptr if the window
	 *            was cancelled or an empty string when the default
	 *            button was pressed, i.e. StrEmpty(str).
	 */
	virtual void OnQueryTextFinished([[maybe_unused]] char *str) {}

	/**
	 * Some data on this window has become invalid.
	 * @param data information about the changed data.
	 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
	 */
	virtual void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) {}

	/**
	 * The user clicked some place on the map when a tile highlight mode
	 * has been set.
	 * @param pt   the exact point on the map that has been clicked.
	 * @param tile the tile on the map that has been clicked.
	 */
	virtual void OnPlaceObject([[maybe_unused]] Point pt, [[maybe_unused]] TileIndex tile) {}

	/**
	 * The user clicked on a vehicle while HT_VEHICLE has been set.
	 * @param v clicked vehicle
	 * @return true if the click is handled, false if it is ignored
	 * @pre v->IsPrimaryVehicle() == true
	 */
	virtual bool OnVehicleSelect([[maybe_unused]] const struct Vehicle *v) { return false; }

	/**
	 * The user clicked on a vehicle while HT_VEHICLE has been set.
	 * @param v clicked vehicle
	 * @return True if the click is handled, false if it is ignored
	 * @pre v->IsPrimaryVehicle() == true
	 */
	virtual bool OnVehicleSelect([[maybe_unused]] VehicleList::const_iterator begin, [[maybe_unused]] VehicleList::const_iterator end) { return false; }

	/**
	 * The user cancelled a tile highlight mode that has been set.
	 */
	virtual void OnPlaceObjectAbort() {}


	/**
	 * The user is dragging over the map when the tile highlight mode
	 * has been set.
	 * @param select_method the method of selection (allowed directions)
	 * @param select_proc   what will be created when the drag is over.
	 * @param pt            the exact point on the map where the mouse is.
	 */
	virtual void OnPlaceDrag([[maybe_unused]] ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt) {}

	/**
	 * The user has dragged over the map when the tile highlight mode
	 * has been set.
	 * @param select_method the method of selection (allowed directions)
	 * @param select_proc   what should be created.
	 * @param pt            the exact point on the map where the mouse was released.
	 * @param start_tile    the begin tile of the drag.
	 * @param end_tile      the end tile of the drag.
	 */
	virtual void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, [[maybe_unused]] TileIndex start_tile, [[maybe_unused]] TileIndex end_tile) {}

	/**
	 * The user moves over the map when a tile highlight mode has been set
	 * when the special mouse mode has been set to 'PRESIZE' mode. An
	 * example of this is the tile highlight for dock building.
	 * @param pt   the exact point on the map where the mouse is.
	 * @param tile the tile on the map where the mouse is.
	 */
	virtual void OnPlacePresize([[maybe_unused]] Point pt, [[maybe_unused]] TileIndex tile) {}

	/*** End of the event handling ***/

	/**
	 * Is the data related to this window NewGRF inspectable?
	 * @return true iff it is inspectable.
	 */
	virtual bool IsNewGRFInspectable() const { return false; }

	/**
	 * Show the NewGRF inspection window. When this function is called it is
	 * up to the window to call and pass the right parameters to the
	 * ShowInspectWindow function.
	 * @pre this->IsNewGRFInspectable()
	 */
	virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); }

	/**
	 * Iterator to iterate all valid Windows
	 * @tparam TtoBack whether we iterate towards the back.
	 */
	template <bool TtoBack>
	struct WindowIterator {
		typedef Window *value_type;
		typedef value_type *pointer;
		typedef value_type &reference;
		typedef size_t difference_type;
		typedef std::forward_iterator_tag iterator_category;

		explicit WindowIterator(WindowList::iterator start) : it(start)
		{
			this->Validate();
		}
		explicit WindowIterator(const Window *w) : it(w->z_position) {}

		bool operator==(const WindowIterator &other) const { return this->it == other.it; }
		bool operator!=(const WindowIterator &other) const { return !(*this == other); }
		Window * operator*() const { return *this->it; }
		WindowIterator & operator++() { this->Next(); this->Validate(); return *this; }

		bool IsEnd() const { return this->it == _z_windows.end(); }

	private:
		WindowList::iterator it;
		void Validate()
		{
			while (!this->IsEnd() && *this->it == nullptr) this->Next();
		}
		void Next()
		{
			if constexpr (!TtoBack) {
				++this->it;
			} else if (this->it == _z_windows.begin()) {
				this->it = _z_windows.end();
			} else {
				--this->it;
			}
		}
	};
	using IteratorToFront = WindowIterator<false>; //!< Iterate in Z order towards front.
	using IteratorToBack = WindowIterator<true>; //!< Iterate in Z order towards back.

	/**
	 * Iterable ensemble of all valid Windows
	 * @tparam Tfront Wether we iterate from front
	 */
	template <bool Tfront>
	struct AllWindows {
		AllWindows() {}
		WindowIterator<Tfront> begin()
		{
			if constexpr (Tfront) {
				auto back = _z_windows.end();
				if (back != _z_windows.begin()) --back;
				return WindowIterator<Tfront>(back);
			} else {
				return WindowIterator<Tfront>(_z_windows.begin());
			}
		}
		WindowIterator<Tfront> end() { return WindowIterator<Tfront>(_z_windows.end()); }
	};
	using Iterate = AllWindows<false>; //!< Iterate all windows in whatever order is easiest.
	using IterateFromBack = AllWindows<false>; //!< Iterate all windows in Z order from back to front.
	using IterateFromFront = AllWindows<true>; //!< Iterate all windows in Z order from front to back.
};

/**
 * Generic helper function that checks if all elements of the range are equal with respect to the given predicate.
 * @param begin The start of the range.
 * @param end The end of the range.
 * @param pred The predicate to use.
 * @return True if all elements are equal, false otherwise.
 */
template <class It, class Pred>
inline bool AllEqual(It begin, It end, Pred pred)
{
	return std::adjacent_find(begin, end, std::not_fn(pred)) == end;
}

/**
 * Get the nested widget with number \a widnum from the nested widget tree.
 * @tparam NWID Type of the nested widget.
 * @param widnum Widget number of the widget to retrieve.
 * @return The requested widget if it is instantiated, \c nullptr otherwise.
 */
template <class NWID>
inline NWID *Window::GetWidget(WidgetID widnum)
{
	auto it = this->widget_lookup.find(widnum);
	if (it == std::end(this->widget_lookup)) return nullptr;
	NWID *nwid = dynamic_cast<NWID *>(it->second);
	assert(nwid != nullptr);
	return nwid;
}

/** Specialized case of #Window::GetWidget for the nested widget base class. */
template <>
inline const NWidgetBase *Window::GetWidget<NWidgetBase>(WidgetID widnum) const
{
	auto it = this->widget_lookup.find(widnum);
	if (it == std::end(this->widget_lookup)) return nullptr;
	return it->second;
}

/**
 * Get the nested widget with number \a widnum from the nested widget tree.
 * @tparam NWID Type of the nested widget.
 * @param widnum Widget number of the widget to retrieve.
 * @return The requested widget if it is instantiated, \c nullptr otherwise.
 */
template <class NWID>
inline const NWID *Window::GetWidget(WidgetID widnum) const
{
	return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
}


/**
 * Base class for windows opened from a toolbar.
 */
class PickerWindowBase : public Window {

public:
	PickerWindowBase(WindowDesc *desc, Window *parent) : Window(desc)
	{
		this->parent = parent;
	}

	void Close([[maybe_unused]] int data = 0) override;
};

Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
Window *FindWindowFromPt(int x, int y);

template<typename T, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value, int> = 0>
Window *BringWindowToFrontById(WindowClass cls, T number)
{
	return BringWindowToFrontById(cls, number.base());
}

/**
 * Open a new window.
 * @tparam Wcls %Window class to use if the window does not exist.
 * @param desc The pointer to the WindowDesc to be created
 * @param window_number the window number of the new window
 * @param return_existing If set, also return the window if it already existed.
 * @return %Window pointer of the newly created window, or the existing one if \a return_existing is set, or \c nullptr.
 */
template <typename Wcls>
Wcls *AllocateWindowDescFront(WindowDesc *desc, int window_number, bool return_existing = false)
{
	Wcls *w = static_cast<Wcls *>(BringWindowToFrontById(desc->cls, window_number));
	if (w != nullptr) return return_existing ? w : nullptr;
	return new Wcls(desc, window_number);
}

void RelocateAllWindows(int neww, int newh);

void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount = 0);

/* widget.cpp */
WidgetID GetWidgetFromPos(const Window *w, int x, int y);

extern Point _cursorpos_drag_start;

extern int _scrollbar_start_pos;
extern int _scrollbar_size;
extern byte _scroller_click_timeout;

extern bool _scrolling_viewport;
extern bool _mouse_hovering;

/** Mouse modes. */
enum SpecialMouseMode {
	WSM_NONE,     ///< No special mouse mode.
	WSM_DRAGDROP, ///< Drag&drop an object.
	WSM_SIZING,   ///< Sizing mode.
	WSM_PRESIZE,  ///< Presizing mode (docks, tunnels).
	WSM_DRAGGING, ///< Dragging mode (trees).
};
extern SpecialMouseMode _special_mouse_mode;

void SetFocusedWindow(Window *w);

void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y);

#endif /* WINDOW_GUI_H */