1  {$INCLUDE Switches.inc}


2  unit Select;


3 


4  interface


5 


6  uses


7  Protocol, ClientTools, Term, ScreenTools, IsoEngine, PVSB, BaseWin, UDpiControls,


8  LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Graphics, Controls, Forms,


9  ExtCtrls, ButtonB, ButtonBase, Menus, Types;


10 


11  const


12  MaxLayer = 3;


13 


14  type


15  TListKind = (kProject, kAdvance, kFarAdvance, kCities, kCityEvents, kModels,


16  kEModels, kAllEModels, kTribe, kScience, kShipPart, kEShipPart, kChooseTech,


17  kChooseETech, kChooseModel, kChooseEModel, kChooseCity, kChooseECity,


18  kStealTech, kGov, kMission);


19 


20  { TListDlg }


21 


22  TListDlg = class(TFramedDlg)


23  CloseBtn: TButtonB;


24  Layer2Btn: TButtonB;


25  Layer1Btn: TButtonB;


26  Layer0Btn: TButtonB;


27  ToggleBtn: TButtonB;


28  Popup: TPopupMenu;


29  procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;


30  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);


31  procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;


32  x, y: integer);


33  procedure FormCreate(Sender: TObject);


34  procedure FormDestroy(Sender: TObject);


35  procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;


36  Shift: TShiftState; x, y: integer);


37  procedure FormPaint(Sender: TObject);


38  procedure CloseBtnClick(Sender: TObject);


39  procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);


40  procedure FormShow(Sender: TObject);


41  procedure ModeBtnClick(Sender: TObject);


42  procedure ToggleBtnClick(Sender: TObject);


43  procedure FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);


44  procedure PlayerClick(Sender: TObject);


45  private


46  Kind: TListKind;


47  LineDistance, MaxLines, cixProject, pView, Sel, DispLines, Layer, nColumn,


48  TechNameSpace, ScienceNation: integer;


49  sb: TPVScrollbar;


50  Lines, FirstShrinkedLine: array [0 .. MaxLayer  1] of integer;


51  code: array [0 .. MaxLayer  1, 0 .. 4095] of integer;


52  Column: array [0 .. nPl  1] of integer;


53  Closable, MultiPage: boolean;


54  ScienceNationDot: TDpiBitmap;


55  procedure ScrollBarUpdate(Sender: TObject);


56  procedure InitLines;


57  procedure line(ca: TDpiCanvas; l: integer; NonText, lit: boolean);


58  function RenameCity(cix: integer): boolean;


59  function RenameModel(mix: integer): boolean;


60  procedure OnScroll(var m: TMessage); message WM_VSCROLL;


61  procedure OnMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;


62  public


63  result: integer;


64  function OnlyChoice(TestKind: TListKind): integer;


65  // 2=empty, 1=ambiguous, other=only choice


66  procedure OffscreenPaint; override;


67  procedure ShowNewContent(NewMode: integer; ListKind: TListKind);


68  procedure ShowNewContent_CityProject(NewMode, cix: integer);


69  procedure ShowNewContent_MilReport(NewMode, p: integer);


70  procedure EcoChange;


71  procedure TechChange;


72  procedure AddCity;


73  procedure RemoveUnit;


74  end;


75 


76  TModalSelectDlg = TListDlg;


77 


78  const


79  cpType = $10000;


80  mixAll = $10000;


81  adAll = $10000;


82 


83  var


84  ListDlg: TListDlg;


85  ModalSelectDlg: TModalSelectDlg;


86 


87  implementation


88 


89  uses


90  CityScreen, Help, UnitStat, Tribes, Inp;


91 


92  {$R *.lfm}


93 


94  const


95  CityNameSpace = 127;


96 


97  MustChooseKind = [kTribe, kStealTech, kGov];


98 


99  procedure TListDlg.FormCreate(Sender: TObject);


100  begin


101  inherited;


102  Canvas.Font.Assign(UniFont[ftNormal]);


103  sb := TPVScrollbar.Create(Self);


104  sb.SetBorderSpacing(36, 10, 36);


105  sb.OnUpdate := ScrollBarUpdate;


106  InitButtons();


107  Kind := kMission;


108  Layer0Btn.Hint := Phrases.Lookup('BTN_IMPRS');


109  Layer1Btn.Hint := Phrases.Lookup('BTN_WONDERS');


110  Layer2Btn.Hint := Phrases.Lookup('BTN_CLASSES');


111  ScienceNationDot := TDpiBitmap.Create;


112  ScienceNationDot.PixelFormat := pf24bit;


113  ScienceNationDot.SetSize(17, 17);


114  ScienceNationDot.Canvas.FillRect(0, 0, ScienceNationDot.Width, ScienceNationDot.Height);


115  end;


116 


117  procedure TListDlg.FormDestroy(Sender: TObject);


118  begin


119  FreeAndNil(sb);


120  FreeAndNil(ScienceNationDot);


121  end;


122 


123  procedure TListDlg.CloseBtnClick(Sender: TObject);


124  begin


125  Closable := true;


126  Close;


127  end;


128 


129  procedure TListDlg.FormCloseQuery(Sender: TObject; var CanClose: boolean);


130  begin


131  CanClose := Closable or not(Kind in MustChooseKind);


132  end;


133 


134  procedure TListDlg.OnScroll(var m: TMessage);


135  begin


136  { TODO: Handled by MouseWheel event


137  if sb.Process(m) then begin


138  Sel := 2;


139  SmartUpdateContent(true);


140  end;


141  }


142  end;


143 


144  procedure TListDlg.OnMouseLeave(var Msg: TMessage);


145  begin


146  if not Closable and (Sel <> 2) then


147  begin


148  line(Canvas, Sel, false, false);


149  Sel := 2;


150  end;


151  end;


152 


153  procedure TListDlg.FormPaint(Sender: TObject);


154  var


155  s: string;


156  begin


157  inherited;


158  Canvas.Font.Assign(UniFont[ftNormal]);


159  if Sel <> 2 then


160  line(Canvas, Sel, false, true);


161  s := '';


162  if (Kind = kAdvance) and (MyData.FarTech <> adNone) then


163  s := Format(Phrases.Lookup('TECHFOCUS'),


164  [Phrases.Lookup('ADVANCES', MyData.FarTech)])


165  else if Kind = kModels then


166  s := Tribe[me].TPhrase('SHORTNAME')


167  else if Kind = kEModels then


168  s := Tribe[pView].TPhrase('SHORTNAME') + ' (' +


169  TurnToString(MyRO.EnemyReport[pView].TurnOfMilReport) + ')';


170  if s <> '' then


171  LoweredTextOut(Canvas, 1, MainTexture,


172  (ClientWidth  BiColorTextWidth(Canvas, s)) div 2, 31, s);


173  if not MultiPage and (Kind in [kProject, kAdvance, kFarAdvance]) and not Phrases2FallenBackToEnglish


174  then


175  begin


176  s := Phrases2.Lookup('SHIFTCLICK');


177  LoweredTextOut(Canvas, 2, MainTexture,


178  (ClientWidth  BiColorTextWidth(Canvas, s)) div 2, ClientHeight  29, s);


179  end;


180  end;


181 


182  procedure TListDlg.line(ca: TDpiCanvas; l: integer; NonText, lit: boolean);


183  // paint a line


184 


185  procedure DisplayProject(x, y, pix: integer);


186  begin


187  if pix and (cpType or cpImp) = 0 then


188  with Tribe[me].ModelPicture[pix and cpIndex] do


189  Sprite(offscreen, HGr, x, y, 64, 48, pix mod 10 * 65 + 1,


190  pix div 10 * 49 + 1)


191  else


192  begin


193  Frame(offscreen.Canvas, x + (16  1), y + (16  2), x + (16 + xSizeSmall),


194  y + (16  1 + ySizeSmall), MainTexture.clBevelLight,


195  MainTexture.clBevelShade);


196  if pix and cpType = 0 then


197  if (pix and cpIndex = imPalace) and (MyRO.Government <> gAnarchy) then


198  DpiBitBlt(offscreen.Canvas.Handle, x + 16, y + (16  1), xSizeSmall,


199  ySizeSmall, SmallImp.Canvas.Handle, (MyRO.Government  1) *


200  xSizeSmall, ySizeSmall, SRCCOPY)


201  else


202  DpiBitBlt(offscreen.Canvas.Handle, x + 16, y + (16  1), xSizeSmall,


203  ySizeSmall, SmallImp.Canvas.Handle, pix and cpIndex mod 7 *


204  xSizeSmall, (pix and cpIndex + SystemIconLines * 7) div 7 *


205  ySizeSmall, SRCCOPY)


206  else


207  DpiBitBlt(offscreen.Canvas.Handle, x + 16, y + (16  1), xSizeSmall,


208  ySizeSmall, SmallImp.Canvas.Handle, (3 + pix and cpIndex) *


209  xSizeSmall, 0, SRCCOPY)


210  end;


211  end;


212 


213  procedure ReplaceText(x, y, Color: integer; s: string);


214  var


215  TextSize: TSize;


216  begin


217  if ca = Canvas then


218  begin


219  TextSize.cx := BiColorTextWidth(ca, s);


220  TextSize.cy := ca.TextHeight(s);


221  if y + TextSize.cy >= TitleHeight + InnerHeight then


222  TextSize.cy := TitleHeight + InnerHeight  y;


223  Fill(ca, x, y, TextSize.cx, TextSize.cy, (wMaintexture  ClientWidth)


224  div 2, (hMaintexture  ClientHeight) div 2);


225  end;


226  LoweredTextOut(ca, Color, MainTexture, x, y, s);


227  end;


228 


229  var


230  icon, ofs, x, y, y0, lix, i, j, TextColor, Available, first, test,


231  FutureCount, growth, TrueFood, TrueProd: integer;


232  CityReport: TCityReportNew;


233  mox: ^TModelInfo;


234  s, number: string;


235  CanGrow: boolean;


236  begin


237  lix := code[Layer, sb.Position + l];


238  y0 := 2 + (l + 1) * LineDistance;


239  if sb.Position + l >= FirstShrinkedLine[Layer] then


240  ofs := (sb.Position + l  FirstShrinkedLine[Layer]) and 1 * 33


241  else { if FirstShrinkedLine[Layer]<Lines[Layer] then }


242  ofs := 33;


243 


244  if Kind in [kCities, kCityEvents] then


245  with MyCity[lix] do


246  begin


247  x := 104  76;


248  y := y0;


249  if ca = Canvas then


250  begin


251  x := x + SideFrame;


252  y := y + TitleHeight


253  end;


254  if lit then


255  TextColor := MainTexture.clLitText


256  else


257  TextColor := 1;


258  s := CityName(ID);


259  while BiColorTextWidth(ca, s) > CityNameSpace do


260  delete(s, length(s), 1);


261  ReplaceText(x + 15, y, TextColor, s);


262 


263  if NonText then


264  with offscreen.Canvas do


265  begin // city size


266  brush.Color := $000000;


267  fillrect(rect(x  4  11, y + 1, x  4 + 13, y + 21));


268  brush.Color := $FFFFFF;


269  fillrect(rect(x  4  12, y, x  4 + 12, y + 20));


270  brush.style := bsClear;


271  Font.Color := $000000;


272  s := inttostr(MyCity[lix].Size);


273  TextOut(x  4  textwidth(s) div 2, y, s);


274  end;


275 


276  if Kind = kCityEvents then


277  begin


278  first := 1;


279  for j := 0 to nCityEventPriority  1 do


280  if (Flags and CityRepMask and CityEventPriority[j] <> 0) then


281  begin


282  first := j;


283  Break


284  end;


285  if first >= 0 then


286  begin


287  i := 0;


288  test := 1;


289  while test < CityEventPriority[first] do


290  begin


291  inc(i);


292  inc(test, test)


293  end;


294  s := CityEventName(i);


295  { if CityEventPriority[first]=chNoGrowthWarning then


296  if Built[imAqueduct]=0 then


297  s:=Format(s,[Phrases.Lookup('IMPROVEMENTS',imAqueduct)])


298  else begin s:=Format(s,[Phrases.Lookup('IMPROVEMENTS',imSewer)]); i:=17 end; }


299  ReplaceText(x + (CityNameSpace + 4 + 40 + 18 + 8), y, TextColor, s);


300  if NonText then


301  begin


302  Sprite(offscreen, HGrSystem, 105  76 + CityNameSpace + 4 + 40,


303  y0 + 1, 18, 18, 1 + i mod 3 * 19, 1 + i div 3 * 19);


304  x := InnerWidth  26;


305  for j := nCityEventPriority  1 downto first + 1 do


306  if (Flags and CityRepMask and CityEventPriority[j] <> 0) then


307  begin


308  i := 0;


309  test := 1;


310  while test < CityEventPriority[j] do


311  begin


312  inc(i);


313  inc(test, test)


314  end;


315  if (CityEventPriority[j] = chNoGrowthWarning) and


316  (Built[imAqueduct] > 0) then


317  i := 17;


318  Sprite(offscreen, HGrSystem, x, y0 + 1, 18, 18,


319  1 + i mod 3 * 19, 1 + i div 3 * 19);


320  dec(x, 20)


321  end


322  end


323  end


324  end


325  else


326  begin


327  CityReport.HypoTiles := 1;


328  CityReport.HypoTaxRate := 1;


329  CityReport.HypoLuxuryRate := 1;


330  Server(sGetCityReportNew, me, lix, CityReport);


331  TrueFood := Food;


332  TrueProd := Prod;


333  if supervising then


334  begin // normalize city from afterturn state


335  dec(TrueFood, CityReport.FoodSurplus);


336  if TrueFood < 0 then


337  TrueFood := 0; // shouldn't happen


338  dec(TrueProd, CityReport.Production);


339  if TrueProd < 0 then


340  TrueProd := 0; // shouldn't happen


341  end;


342 


343  s := ''; // disorder info


344  if Flags and chCaptured <> 0 then


345  s := Phrases.Lookup('CITYEVENTS', 14)


346  else if CityReport.HappinessBalance < 0 then


347  s := Phrases.Lookup('CITYEVENTS', 0);


348  if s <> '' then


349  begin { disorder }


350  if NonText then


351  begin


352  DarkGradient(offscreen.Canvas, 99 + 31 + CityNameSpace + 4,


353  y0 + 2, 131, 3);


354  ca.Font.Assign(UniFont[ftSmall]);


355  RisedTextout(offscreen.Canvas, 103 + CityNameSpace + 4 + 31,


356  y0 + 1, s);


357  ca.Font.Assign(UniFont[ftNormal]);


358  end


359  end


360  else


361  begin


362  { s:=IntToStr(CityReport.FoodSurplus);


363  ReplaceText(x+(CityNameSpace+4+48)BiColorTextWidth(ca,s),y,TextColor,s); }


364  s := inttostr(CityReport.Science);


365  ReplaceText(x + CityNameSpace + 4 + 370 + 48  BiColorTextWidth(ca,


366  s), y, TextColor, s);


367  s := inttostr(CityReport.Production);


368  ReplaceText(x + CityNameSpace + 4 + 132  BiColorTextWidth(ca, s), y,


369  TextColor, s);


370  if NonText then


371  begin


372  // Sprite(offscreen,HGrSystem,x+CityNameSpace+4+333+1,y+6,10,10,66,115);


373  Sprite(offscreen, HGrSystem, x + CityNameSpace + 4 + 370 + 48 + 1,


374  y + 6, 10, 10, 77, 126);


375  Sprite(offscreen, HGrSystem, x + CityNameSpace + 4 + 132 + 1, y + 6,


376  10, 10, 88, 115);


377  end


378  end;


379  s := inttostr(CityTaxBalance(lix, CityReport));


380  ReplaceText(x + CityNameSpace + 4 + 370  BiColorTextWidth(ca, s), y,


381  TextColor, s);


382  // if Project and (cpImp+cpIndex)<>cpImp+imTrGoods then


383  // ReplaceText(x+CityNameSpace+4+333+1,y,TextColor,Format('%d/%d',[TrueProd,CityReport.ProjectCost]));


384  if NonText then


385  begin


386  Sprite(offscreen, HGrSystem, x + CityNameSpace + 4 + 370 + 1, y + 6,


387  10, 10, 132, 115);


388 


389  // food progress


390  CanGrow := (Size < MaxCitySize) and (MyRO.Government <> gFuture) and


391  (CityReport.FoodSurplus > 0) and


392  ((Size < NeedAqueductSize) or (Built[imAqueduct] = 1) and


393  (Size < NeedSewerSize) or (Built[imSewer] = 1));


394  PaintRelativeProgressBar(offscreen.Canvas, 1, x + 15 + CityNameSpace +


395  4, y + 7, 68, TrueFood, CutCityFoodSurplus(CityReport.FoodSurplus,


396  (MyRO.Government <> gAnarchy) and (Flags and chCaptured = 0),


397  MyRO.Government, Size), CityReport.Storage, CanGrow, MainTexture);


398 


399  if Project <> cpImp + imTrGoods then


400  begin


401  DisplayProject(ofs + 104  76 + x  28 + CityNameSpace + 4 + 206 


402  60, y0  15, Project);


403 


404  // production progress


405  growth := CityReport.Production;


406  if (growth < 0) or (MyRO.Government = gAnarchy) or


407  (Flags and chCaptured <> 0) then


408  growth := 0;


409  PaintRelativeProgressBar(offscreen.Canvas, 4,


410  x + CityNameSpace + 4 + 304  60 + 9, y + 7, 68, TrueProd, growth,


411  CityReport.ProjectCost, true, MainTexture);


412  end;


413  end


414  end;


415  end


416  else if Kind in [kModels, kEModels] then


417  begin


418  x := 104;


419  y := y0;


420  if ca = Canvas then


421  begin


422  x := x + SideFrame;


423  y := y + TitleHeight


424  end;


425  if lit then


426  TextColor := MainTexture.clLitText


427  else


428  TextColor := 1;


429  if Kind = kModels then


430  begin


431  Available := 0;


432  for j := 0 to MyRO.nUn  1 do


433  if (MyUn[j].Loc >= 0) and (MyUn[j].mix = lix) then


434  inc(Available);


435  if MainScreen.mNames.Checked then


436  s := Tribe[me].ModelName[lix]


437  else


438  s := Format(Tribe[me].TPhrase('GENMODEL'), [lix]);


439  if NonText then


440  DisplayProject(8 + ofs, y0  15, lix);


441  end


442  else


443  begin


444  Available := MyRO.EnemyReport[pView].UnCount[lix];


445  if MainScreen.mNames.Checked then


446  s := Tribe[pView].ModelName[lix]


447  else


448  s := Format(Tribe[pView].TPhrase('GENMODEL'), [lix]);


449  if NonText then


450  with Tribe[pView].ModelPicture[lix] do


451  Sprite(offscreen, HGr, 8 + ofs, y0  15, 64, 48, pix mod 10 * 65 + 1,


452  pix div 10 * 49 + 1);


453  end;


454  if Available > 0 then


455  ReplaceText(x + 32  BiColorTextWidth(ca, inttostr(Available)), y,


456  TextColor, inttostr(Available));


457  ReplaceText(x + 40, y, TextColor, s);


458  end


459  else


460  begin


461  case Kind of


462  kAllEModels, kChooseEModel:


463  if lix = mixAll then


464  s := Phrases.Lookup('PRICECAT_ALLMODEL')


465  else


466  begin


467  mox := @MyRO.EnemyModel[lix];


468  if MainScreen.mNames.Checked then


469  begin


470  s := Tribe[mox.Owner].ModelName[mox.mix];


471  if (Kind = kAllEModels) and (code[1, sb.Position + l] = 0) then


472  s := Format(Tribe[mox.Owner].TPhrase('OWNED'), [s]);


473  end


474  else


475  s := Format(Tribe[mox.Owner].TPhrase('GENMODEL'), [mox.mix]);


476  if NonText then


477  with Tribe[mox.Owner].ModelPicture[mox.mix] do


478  Sprite(offscreen, HGr, 8 + ofs, y0  15, 64, 48,


479  pix mod 10 * 65 + 1, pix div 10 * 49 + 1);


480  end;


481  kChooseModel:


482  if lix = mixAll then


483  s := Phrases.Lookup('PRICECAT_ALLMODEL')


484  else


485  begin


486  s := Tribe[me].ModelName[lix];


487  if NonText then


488  DisplayProject(8 + ofs, y0  15, lix);


489  end;


490  kProject:


491  begin


492  if lix and cpType <> 0 then


493  s := Phrases.Lookup('CITYTYPE', lix and cpIndex)


494  else if lix and cpImp = 0 then


495  with MyModel[lix and cpIndex] do


496  begin


497  s := Tribe[me].ModelName[lix and cpIndex];


498  if lix and cpConscripts <> 0 then


499  s := Format(Phrases.Lookup('CONSCRIPTS'), [s]);


500  end


501  else


502  begin


503  s := Phrases.Lookup('IMPROVEMENTS', lix and cpIndex);


504  if (Imp[lix and cpIndex].Kind in [ikNatLocal, ikNatGlobal]) and


505  (MyRO.NatBuilt[lix and cpIndex] > 0) or


506  (lix and cpIndex in [imPower, imHydro, imNuclear]) and


507  (MyCity[cixProject].Built[imPower] + MyCity[cixProject].Built


508  [imHydro] + MyCity[cixProject].Built[imNuclear] > 0) then


509  s := Format(Phrases.Lookup('NATEXISTS'), [s]);


510  end;


511  if NonText then


512  DisplayProject(8 + ofs, y0  15, lix);


513  end;


514  kAdvance, kFarAdvance, kScience, kChooseTech, kChooseETech, kStealTech:


515  begin


516  if lix = adAll then


517  s := Phrases.Lookup('PRICECAT_ALLTECH')


518  else


519  begin


520  if lix = adNexus then


521  s := Phrases.Lookup('NEXUS')


522  else if lix = adNone then


523  s := Phrases.Lookup('NOFARTECH')


524  else if lix = adMilitary then


525  s := Phrases.Lookup('INITUNIT')


526  else


527  begin


528  s := Phrases.Lookup('ADVANCES', lix);


529  if (Kind = kAdvance) and (lix in FutureTech) then


530  if MyRO.Tech[lix] < tsApplicable then


531  s := s + ' 1'


532  else


533  s := s + ' ' + inttostr(MyRO.Tech[lix] + 1);


534  end;


535  if BiColorTextWidth(ca, s) > TechNameSpace + 8 then


536  begin


537  repeat


538  delete(s, length(s), 1);


539  until BiColorTextWidth(ca, s) <= TechNameSpace + 5;


540  s := s + '.';


541  end;


542 


543  if NonText then


544  begin // show tech icon


545  if lix = adNexus then


546  begin


547  Frame(offscreen.Canvas, (8 + 16  1), y0  1, (8 + 16 + 36),


548  y0 + 20, MainTexture.clBevelLight, MainTexture.clBevelShade);


549  Dump(offscreen, HGrSystem, (8 + 16), y0, 36, 20, 223, 295)


550  end


551  else if lix = adNone then


552  begin


553  Frame(offscreen.Canvas, (8 + 16  1), y0  1, (8 + 16 + 36),


554  y0 + 20, MainTexture.clBevelLight, MainTexture.clBevelShade);


555  Dump(offscreen, HGrSystem, (8 + 16), y0, 36, 20, 260, 295)


556  end


557  else if lix = adMilitary then


558  begin


559  Frame(offscreen.Canvas, (8 + 16  1), y0  1, (8 + 16 + 36),


560  y0 + 20, MainTexture.clBevelLight, MainTexture.clBevelShade);


561  Dump(offscreen, HGrSystem, (8 + 16), y0, 36, 20, 38, 295)


562  end


563  else


564  begin


565  Frame(offscreen.Canvas, (8 + 16  1), y0  1,


566  (8 + 16 + xSizeSmall), y0 + ySizeSmall,


567  MainTexture.clBevelLight, MainTexture.clBevelShade);


568  if AdvIcon[lix] < 84 then


569  DpiBitBlt(offscreen.Canvas.Handle, (8 + 16), y0, xSizeSmall,


570  ySizeSmall, SmallImp.Canvas.Handle,


571  (AdvIcon[lix] + SystemIconLines * 7) mod 7 * xSizeSmall,


572  (AdvIcon[lix] + SystemIconLines * 7) div 7 *


573  ySizeSmall, SRCCOPY)


574  else


575  Dump(offscreen, HGrSystem, (8 + 16), y0, 36, 20,


576  1 + (AdvIcon[lix]  84) mod 8 * 37,


577  295 + (AdvIcon[lix]  84) div 8 * 21);


578  j := AdvValue[lix] div 1000;


579  DpiBitBlt(Handle, (8 + 16  4), y0 + 2, 14, 14,


580  GrExt[HGrSystem].Mask.Canvas.Handle, 127 + j * 15,


581  85, SRCAND);


582  Sprite(offscreen, HGrSystem, (8 + 16  5), y0 + 1, 14, 14,


583  127 + j * 15, 85);


584  end;


585  end;


586  end;


587 


588  if NonText and (Kind in [kAdvance, kScience]) then


589  begin // show research state


590  for j := 0 to nColumn  1 do


591  begin


592  FutureCount := 0;


593  if j = 0 then // own science


594  if lix = MyRO.ResearchTech then


595  begin


596  Server(sGetTechCost, me, 0, icon);


597  icon := 4 + MyRO.Research * 4 div icon;


598  if icon > 4 + 3 then


599  icon := 4 + 3


600  end


601  else if (lix >= adMilitary) then


602  icon := 1


603  else if lix in FutureTech then


604  begin


605  icon := 1;


606  FutureCount := MyRO.Tech[lix];


607  end


608  else if MyRO.Tech[lix] = tsSeen then


609  icon := 1


610  else if MyRO.Tech[lix] >= tsApplicable then


611  icon := 2


612  else


613  icon := 1


614  else


615  with MyRO.EnemyReport[Column[j]]^ do // enemy science


616  if (MyRO.Alive and (1 shl Column[j]) <> 0) and


617  (TurnOfCivilReport >= 0) and (lix = ResearchTech) and


618  ((lix = adMilitary) or (lix in FutureTech) or


619  (Tech[lix] < tsApplicable)) then


620  begin


621  icon := 4 + ResearchDone div 25;


622  if icon > 4 + 3 then


623  icon := 4 + 3


624  end


625  else if lix = adMilitary then


626  icon := 1


627  else if lix in FutureTech then


628  begin


629  icon := 1;


630  FutureCount := Tech[lix]


631  end


632  else if Tech[lix] >= tsApplicable then


633  icon := 2


634  else if Tech[lix] = tsSeen then


635  icon := 1


636  else


637  icon := 1;


638  if icon >= 0 then


639  Sprite(offscreen, HGrSystem, 104  33 + 15 + 3 + TechNameSpace +


640  24 * j, y0 + 3, 14, 14, 67 + icon * 15, 85)


641  else if (Kind = kScience) and (FutureCount > 0) then


642  begin


643  number := inttostr(FutureCount);


644  RisedTextout(ca, 104  33 + 15 + 10 + TechNameSpace + 24 * j 


645  BiColorTextWidth(ca, number) div 2, y0, number);


646  end


647  end


648  end;


649  end; // kAdvance, kScience


650  kTribe:


651  s := TribeNames[lix];


652  kShipPart:


653  begin


654  s := Phrases.Lookup('IMPROVEMENTS', imShipComp + lix) + ' (' +


655  inttostr(MyRO.Ship[me].Parts[lix]) + ')';


656  if NonText then


657  DisplayProject(8 + ofs, y0  15, cpImp + imShipComp + lix);


658  end;


659  kEShipPart:


660  begin


661  s := Phrases.Lookup('IMPROVEMENTS', imShipComp + lix) + ' (' +


662  inttostr(MyRO.Ship[DipMem[me].pContact].Parts[lix]) + ')';


663  if NonText then


664  DisplayProject(8 + ofs, y0  15, cpImp + imShipComp + lix);


665  end;


666  kGov:


667  begin


668  s := Phrases.Lookup('GOVERNMENT', lix);


669  if NonText then


670  begin


671  Frame(offscreen.Canvas, 8 + 16  1, y0  15 + (16  2),


672  8 + 16 + xSizeSmall, y0  15 + (16  1 + ySizeSmall),


673  MainTexture.clBevelLight, MainTexture.clBevelShade);


674  DpiBitBlt(offscreen.Canvas.Handle, 8 + 16, y0  15 + (16  1),


675  xSizeSmall, ySizeSmall, SmallImp.Canvas.Handle,


676  (lix  1) * xSizeSmall, ySizeSmall, SRCCOPY);


677  end


678  end;


679  kMission:


680  s := Phrases.Lookup('SPYMISSION', lix);


681  end;


682  case Kind of


683  kTribe, kMission: // center text


684  if Lines[0] > MaxLines then


685  x := (InnerWidth  GetSystemMetrics(SM_CXVSCROLL)) div 2 


686  BiColorTextWidth(ca, s) div 2


687  else


688  x := InnerWidth div 2  BiColorTextWidth(ca, s) div 2;


689  kAdvance, kFarAdvance, kScience, kChooseTech, kChooseETech,


690  kStealTech, kGov:


691  x := 104  33;


692  kAllEModels:


693  x := 104;


694  else


695  x := 104 + 15;


696  end;


697  y := y0;


698  if ca = Canvas then


699  begin


700  x := x + SideFrame;


701  y := y + TitleHeight


702  end;


703  if lit then


704  TextColor := MainTexture.clLitText


705  else


706  TextColor := 1;


707  { if Kind=kTribe then ReplaceText_Tribe(x,y,TextColor,


708  integer(TribeNames.Objects[lix]),s)


709  else } ReplaceText(x, y, TextColor, s);


710  end


711  end;


712 


713  procedure TListDlg.OffscreenPaint;


714  var


715  i, j: integer;


716  begin


717  case Kind of


718  kCities:


719  Caption := Tribe[me].TPhrase('TITLE_CITIES');


720  kCityEvents:


721  Caption := Format(Phrases.Lookup('TITLE_EVENTS'),


722  [TurnToString(MyRO.Turn)]);


723  end;


724 


725  inherited;


726  offscreen.Canvas.Font.Assign(UniFont[ftNormal]);


727  FillOffscreen(0, 0, InnerWidth, InnerHeight);


728  with offscreen.Canvas do


729  begin


730  if Kind = kScience then


731  for i := 1 to nColumn  1 do


732  begin


733  Pen.Color := $000000;


734  MoveTo(104  33 + 15 + TechNameSpace + 24 * i, 0);


735  LineTo(104  33 + 15 + TechNameSpace + 24 * i, InnerHeight);


736  MoveTo(104  33 + 15 + TechNameSpace + 9 * 2 + 24 * i, 0);


737  LineTo(104  33 + 15 + TechNameSpace + 9 * 2 + 24 * i, InnerHeight);


738  if MyRO.EnemyReport[Column[i]].TurnOfCivilReport >= MyRO.Turn  1 then


739  begin


740  brush.Color := Tribe[Column[i]].Color;


741  fillrect(rect(104  33 + 14 + TechNameSpace + 24 * i + 1 * 2, 0,


742  104  33 + 17 + TechNameSpace + 24 * i + 8 * 2, InnerHeight));


743  brush.style := bsClear;


744  end


745  else


746  begin // colored player columns


747  Pen.Color := Tribe[Column[i]].Color;


748  for j := 1 to 8 do


749  begin


750  MoveTo(104  33 + 15 + TechNameSpace + 24 * i + j * 2, 0);


751  LineTo(104  33 + 15 + TechNameSpace + 24 * i + j * 2, InnerHeight);


752  end


753  end;


754  end;


755  for i := 1 to DispLines do


756  if (i + sb.Position >= 0) and (i + sb.Position < Lines[Layer]) then


757  Self.line(offscreen.Canvas, i, true, false)


758  end;


759  MarkUsedOffscreen(InnerWidth, 8 + 48 + DispLines * LineDistance);


760  end;


761 


762  procedure TListDlg.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;


763  x, y: integer);


764  var


765  i0, Sel0, iColumn, OldScienceNation, xScreen: integer;


766  s: string;


767  begin


768  y := y  TitleHeight;


769  i0 := sb.Position;


770  Sel0 := Sel;


771  if (x >= SideFrame) and (x < SideFrame + InnerWidth) and (y >= 0) and


772  (y < InnerHeight) and (y mod LineDistance >= 4) and (y mod LineDistance < 20)


773  then


774  Sel := y div LineDistance  1


775  else


776  Sel := 2;


777  if (Sel < 1) or (Sel > DispLines) or (Sel + i0 < 0) or


778  (Sel + i0 >= Lines[Layer]) then


779  Sel := 2;


780  if Sel <> Sel0 then


781  begin


782  if Sel0 <> 2 then


783  line(Canvas, Sel0, false, false);


784  if Sel <> 2 then


785  line(Canvas, Sel, false, true)


786  end;


787 


788  if Kind = kScience then


789  begin // show nation under cursor position


790  OldScienceNation := ScienceNation;


791  ScienceNation := 1;


792  if (x >= SideFrame + (104  33 + 15 + TechNameSpace)) and


793  ((x  SideFrame  (104  33 + 15 + TechNameSpace)) mod 24 <= 18) and


794  (y >= 0) and (y < InnerHeight) then


795  begin


796  iColumn := (x  SideFrame  (104  33 + 15 + TechNameSpace)) div 24;


797  if (iColumn >= 1) and (iColumn < nColumn) then


798  ScienceNation := Column[iColumn];


799  end;


800  if ScienceNation <> OldScienceNation then


801  begin


802  Fill(Canvas, 9, ClientHeight  29, ClientWidth  18, 24,


803  (wMaintexture  ClientWidth) div 2,


804  (hMaintexture  ClientHeight) div 2);


805  if ScienceNation >= 0 then


806  begin


807  s := Tribe[ScienceNation].TPhrase('SHORTNAME');


808  if MyRO.Alive and (1 shl ScienceNation) = 0 then


809  s := Format(Phrases.Lookup('SCIENCEREPORT_EXTINCT'), [s]) // extinct


810  else if MyRO.EnemyReport[ScienceNation].TurnOfCivilReport < MyRO.Turn  1


811  then


812  s := s + ' (' + TurnToString(MyRO.EnemyReport[ScienceNation]


813  .TurnOfCivilReport) + ')'; // old report


814  xScreen := (ClientWidth  BiColorTextWidth(Canvas, s)) div 2;


815  LoweredTextOut(Canvas, 1, MainTexture, xScreen + 10,


816  ClientHeight  29, s);


817  BitBltCanvas(ScienceNationDot.Canvas, 0, 0, 17, 17, Canvas,


818  xScreen  10, ClientHeight  27, SRCCOPY);


819  ImageOp_BCC(ScienceNationDot, Templates, 0, 0, 114, 211, 17, 17,


820  MainTexture.clBevelShade, Tribe[ScienceNation].Color);


821  DpiBitBlt(Canvas.Handle, xScreen  10, ClientHeight  27, 17, 17,


822  ScienceNationDot.Canvas.Handle, 0, 0, SRCCOPY);


823  end;


824  end


825  end;


826  end;


827 


828  procedure TListDlg.FormMouseWheel(Sender: TObject; Shift: TShiftState;


829  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);


830  begin


831  if sb.ProcessMouseWheel(WheelDelta) then begin


832  PaintBox1MouseMove(nil, [], MousePos.X  Left,


833  MousePos.Y  Top);


834  end;


835  end;


836 


837  function TListDlg.RenameCity(cix: integer): boolean;


838  var


839  CityNameInfo: TCityNameInfo;


840  begin


841  InputDlg.Caption := Phrases.Lookup('TITLE_CITYNAME');


842  InputDlg.EInput.Text := CityName(MyCity[cix].ID);


843  InputDlg.CenterToRect(BoundsRect);


844  InputDlg.ShowModal;


845  if (InputDlg.ModalResult = mrOK) and (InputDlg.EInput.Text <> '') and


846  (InputDlg.EInput.Text <> CityName(MyCity[cix].ID)) then


847  begin


848  CityNameInfo.ID := MyCity[cix].ID;


849  CityNameInfo.NewName := InputDlg.EInput.Text;


850  Server(cSetCityName + (length(CityNameInfo.NewName) + 8) div 4, me, 0,


851  CityNameInfo);


852  if CityDlg.Visible then


853  begin


854  CityDlg.FormShow(nil);


855  CityDlg.Invalidate


856  end;


857  result := true


858  end


859  else


860  result := false


861  end;


862 


863  function TListDlg.RenameModel(mix: integer): boolean;


864  var


865  ModelNameInfo: TModelNameInfo;


866  begin


867  InputDlg.Caption := Phrases.Lookup('TITLE_MODELNAME');


868  InputDlg.EInput.Text := Tribe[me].ModelName[mix];


869  InputDlg.CenterToRect(BoundsRect);


870  InputDlg.ShowModal;


871  if (InputDlg.ModalResult = mrOK) and (InputDlg.EInput.Text <> '') and


872  (InputDlg.EInput.Text <> Tribe[me].ModelName[mix]) then


873  begin


874  ModelNameInfo.mix := mix;


875  ModelNameInfo.NewName := InputDlg.EInput.Text;


876  Server(cSetModelName + (length(ModelNameInfo.NewName) + 1 + 4 + 3) div 4,


877  me, 0, ModelNameInfo);


878  if UnitStatDlg.Visible then


879  begin


880  UnitStatDlg.FormShow(nil);


881  UnitStatDlg.Invalidate


882  end;


883  result := true


884  end


885  else


886  result := false


887  end;


888 


889  procedure TListDlg.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;


890  Shift: TShiftState; x, y: integer);


891  var


892  lix: integer;


893  begin


894  if sb.Position + Sel >= 0 then


895  lix := code[Layer, sb.Position + Sel];


896  if Kind in [kScience, kCities, kCityEvents, kModels, kEModels, kAllEModels]


897  then


898  include(Shift, ssShift); // don't close list window


899  if (ssLeft in Shift) and not(ssShift in Shift) then


900  begin


901  if Sel <> 2 then


902  begin


903  result := lix;


904  Closable := true;


905  Close


906  end


907  end


908  else if (ssLeft in Shift) and (ssShift in Shift) then


909  begin // show help/info popup


910  if Sel <> 2 then


911  case Kind of


912  kCities:


913  MainScreen.ZoomToCity(MyCity[lix].Loc);


914  kCityEvents:


915  MainScreen.ZoomToCity(MyCity[lix].Loc, false, MyCity[lix].Flags and


916  CityRepMask);


917  kModels, kChooseModel:


918  if lix <> mixAll then


919  UnitStatDlg.ShowNewContent_OwnModel(FWindowMode or


920  wmPersistent, lix);


921  kEModels:


922  UnitStatDlg.ShowNewContent_EnemyModel(FWindowMode or wmPersistent,


923  code[1, sb.Position + Sel]);


924  kAllEModels, kChooseEModel:


925  if lix <> mixAll then


926  UnitStatDlg.ShowNewContent_EnemyModel(FWindowMode or


927  wmPersistent, lix);


928  kAdvance, kFarAdvance, kScience, kChooseTech, kChooseETech, kStealTech:


929  if lix = adMilitary then


930  HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkText,


931  HelpDlg.TextIndex('MILRES'))


932  else if lix < adMilitary then


933  HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkAdv, lix);


934  kProject:


935  if lix = cpImp + imTrGoods then


936  HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkText,


937  HelpDlg.TextIndex('TRADINGGOODS'))


938  else if lix and (cpImp + cpType) = 0 then


939  UnitStatDlg.ShowNewContent_OwnModel(FWindowMode or wmPersistent,


940  lix and cpIndex)


941  else if (lix and cpType = 0) and (lix <> cpImp + imTrGoods) then


942  HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkImp,


943  lix and cpIndex);


944  kGov:


945  HelpDlg.ShowNewContent(FWindowMode or wmPersistent, hkMisc,


946  miscGovList);


947  kShipPart, kEShipPart:


948  ;


949  end


950  end


951  else if ssRight in Shift then


952  begin


953  if Sel <> 2 then


954  case Kind of


955  kCities, kCityEvents:


956  if RenameCity(lix) then


957  SmartUpdateContent;


958  kModels:


959  if RenameModel(lix) then


960  SmartUpdateContent;


961  end


962  end


963  end;


964 


965  procedure TListDlg.InitLines;


966  var


967  required: array [0 .. nAdv  1] of integer;


968 


969  procedure TryAddImpLine(Layer, Project: integer);


970  begin


971  if Server(sSetCityProject  sExecute, me, cixProject, Project) >= rExecuted


972  then


973  begin


974  code[Layer, Lines[Layer]] := Project;


975  inc(Lines[Layer]);


976  end;


977  end;


978 


979  procedure SortTechs;


980  var


981  i, j, swap: integer;


982  begin // sort by advancedness


983  for i := 0 to Lines[0]  2 do


984  if code[0, i] < adMilitary then


985  for j := i + 1 to Lines[0]  1 do


986  if AdvValue[code[0, i]] * nAdv + code[0, i] < AdvValue[code[0, j]] *


987  nAdv + code[0, j] then


988  begin


989  swap := code[0, i];


990  code[0, i] := code[0, j];


991  code[0, j] := swap


992  end;


993  end;


994 


995  procedure SortCities;


996  var


997  i, j, swap: integer;


998  begin


999  for i := 0 to Lines[0]  2 do


1000  for j := i + 1 to Lines[0]  1 do


1001  if CityName(MyCity[code[0, i]].ID) > CityName(MyCity[code[0, j]].ID)


1002  then


1003  begin


1004  swap := code[0, i];


1005  code[0, i] := code[0, j];


1006  code[0, j] := swap


1007  end;


1008  end;


1009 


1010  function ModelSortValue(const mi: TModelInfo;


1011  MixPlayers: boolean = false): integer;


1012  begin


1013  result := (mi.Domain + 1) shl 28  mi.mix;


1014  if MixPlayers then


1015  dec(result, ModelCode(mi) shl 16);


1016  end;


1017 


1018  procedure SortModels;


1019  var


1020  i, j, swap: integer;


1021  begin // sort by code[2]


1022  for i := 0 to Lines[0]  2 do


1023  for j := i + 1 to Lines[0]  1 do


1024  if code[2, i] > code[2, j] then


1025  begin


1026  swap := code[0, i];


1027  code[0, i] := code[0, j];


1028  code[0, j] := swap;


1029  swap := code[1, i];


1030  code[1, i] := code[1, j];


1031  code[1, j] := swap;


1032  swap := code[2, i];


1033  code[2, i] := code[2, j];


1034  code[2, j] := swap;


1035  end;


1036  end;


1037 


1038  procedure MarkPreqs(i: integer);


1039  begin


1040  required[i] := 1;


1041  if MyRO.Tech[i] < tsSeen then


1042  begin


1043  if (AdvPreq[i, 0] >= 0) then


1044  MarkPreqs(AdvPreq[i, 0]);


1045  if (AdvPreq[i, 1] >= 0) then


1046  MarkPreqs(AdvPreq[i, 1]);


1047  end


1048  end;


1049 


1050  var


1051  Loc1, i, j, p1, dx, dy, mix, emix, EnemyType, TestEnemyType: integer;


1052  mi: TModelInfo;


1053  PPicture, PTestPicture: ^TModelPicture;


1054  ModelOk: array [0 .. 4095] of boolean;


1055  ok: boolean;


1056  begin


1057  for i := 0 to MaxLayer  1 do


1058  begin


1059  Lines[i] := 0;


1060  FirstShrinkedLine[i] := MaxInt


1061  end;


1062  case Kind of


1063  kProject:


1064  begin


1065  // improvements


1066  code[0, 0] := cpImp + imTrGoods;


1067  Lines[0] := 1;


1068  for i := 28 to nImp  1 do


1069  if Imp[i].Kind = ikCommon then


1070  TryAddImpLine(0, i + cpImp);


1071  for i := 28 to nImp  1 do


1072  if not(Imp[i].Kind in [ikCommon, ikTrGoods]) and


1073  ((MyRO.NatBuilt[i] = 0) or (Imp[i].Kind = ikNatLocal)) then


1074  TryAddImpLine(0, i + cpImp);


1075  for i := 0 to nCityType  1 do


1076  if MyData.ImpOrder[i, 0] >= 0 then


1077  begin


1078  code[0, Lines[0]] := cpType + i;


1079  inc(Lines[0]);


1080  end;


1081 


1082  // wonders


1083  for i := 0 to 27 do


1084  TryAddImpLine(1, i + cpImp);


1085 


1086  // units


1087  for i := 0 to MyRO.nModel  1 do


1088  begin


1089  { if MyModel[i].Kind=mkSlaves then


1090  ok:= MyRO.Wonder[woPyramids].EffectiveOwner=me


1091  else } if MyModel[i].Domain = dSea then


1092  begin


1093  ok := false;


1094  for dx := 2 to 2 do


1095  for dy := 2 to 2 do


1096  if abs(dx) + abs(dy) = 2 then


1097  begin


1098  Loc1 := dLoc(MyCity[cixProject].Loc, dx, dy);


1099  if (Loc1 >= 0) and (Loc1 < G.lx * G.ly) and


1100  ((MyMap[Loc1] and fTerrain = fShore) or


1101  (MyMap[Loc1] and fCanal > 0)) then


1102  ok := true;


1103  end


1104  end


1105  else


1106  ok := true;


1107  if ok then


1108  begin


1109  if MyModel[i].Status and msObsolete = 0 then


1110  begin


1111  code[2, Lines[2]] := i;


1112  inc(Lines[2])


1113  end;


1114  if MyModel[i].Status and msAllowConscripts <> 0 then


1115  begin


1116  code[2, Lines[2]] := i + cpConscripts;


1117  inc(Lines[2])


1118  end;


1119  end;


1120  end;


1121  FirstShrinkedLine[2] := 0;


1122  end;


1123  kAdvance:


1124  begin


1125  nColumn := 1;


1126  if MyData.FarTech <> adNone then


1127  begin


1128  FillChar(required, SizeOf(required), 0);


1129  MarkPreqs(MyData.FarTech);


1130  end;


1131  for i := 0 to nAdv  1 do


1132  if ((i in FutureTech) or (MyRO.Tech[i] < tsApplicable)) and


1133  (Server(sSetResearch  sExecute, me, i, nil^) >= rExecuted) and


1134  ((MyData.FarTech = adNone) or (required[i] > 0)) then


1135  begin


1136  code[0, Lines[0]] := i;


1137  inc(Lines[0]);


1138  end;


1139  SortTechs;


1140  if Lines[0] = 0 then // no more techs  offer nexus


1141  begin


1142  code[0, Lines[0]] := adNexus;


1143  inc(Lines[0]);


1144  end;


1145  ok := false;


1146  for i := 0 to nDomains  1 do


1147  if (upgrade[i, 0].Preq = preNone) or


1148  (MyRO.Tech[upgrade[i, 0].Preq] >= tsApplicable) then


1149  ok := true;


1150  if ok then { new unit class }


1151  begin


1152  code[0, Lines[0]] := adMilitary;


1153  inc(Lines[0])


1154  end;


1155  end;


1156  kFarAdvance:


1157  begin


1158  code[0, Lines[0]] := adNone;


1159  inc(Lines[0]);


1160  for i := 0 to nAdv  1 do


1161  if not(i in FutureTech) and (MyRO.Tech[i] < tsApplicable) and


1162  ((AdvValue[i] < 2000) or (MyRO.Tech[adMassProduction] > tsNA)) and


1163  ((AdvValue[i] < 1000) or (MyRO.Tech[adScience] > tsNA)) then


1164  begin


1165  code[0, Lines[0]] := i;


1166  inc(Lines[0]);


1167  end;


1168  SortTechs;


1169  end;


1170  kChooseTech:


1171  begin


1172  for i := 0 to nAdv  1 do


1173  if not(i in FutureTech) and (MyRO.Tech[i] >= tsApplicable) and


1174  (MyRO.EnemyReport[DipMem[me].pContact].Tech[i] < tsSeen) then


1175  begin


1176  code[0, Lines[0]] := i;


1177  inc(Lines[0]);


1178  end;


1179  SortTechs;


1180  // if Lines[0]>1 then


1181  begin


1182  code[0, Lines[0]] := adAll;


1183  inc(Lines[0]);


1184  end;


1185  end;


1186  kChooseETech:


1187  begin


1188  for i := 0 to nAdv  1 do


1189  if not(i in FutureTech) and (MyRO.Tech[i] < tsSeen) and


1190  (MyRO.EnemyReport[DipMem[me].pContact].Tech[i] >= tsApplicable) then


1191  begin


1192  code[0, Lines[0]] := i;


1193  inc(Lines[0]);


1194  end;


1195  SortTechs;


1196  // if Lines[0]>1 then


1197  begin


1198  code[0, Lines[0]] := adAll;


1199  inc(Lines[0]);


1200  end;


1201  end;


1202  kStealTech:


1203  begin


1204  for i := 0 to nAdv  1 do


1205  if Server(sStealTech  sExecute, me, i, nil^) >= rExecuted then


1206  begin


1207  code[0, Lines[0]] := i;


1208  inc(Lines[0]);


1209  end;


1210  SortTechs;


1211  end;


1212  kScience:


1213  begin


1214  Column[0] := me;


1215  nColumn := 1;


1216  for EnemyType := 0 to 2 do


1217  for p1 := 0 to nPl  1 do


1218  if (MyRO.EnemyReport[p1] <> nil) and


1219  ((MyRO.EnemyReport[p1].TurnOfContact >= 0) or


1220  (MyRO.EnemyReport[p1].TurnOfCivilReport >= 0)) then


1221  begin


1222  if MyRO.Alive and (1 shl p1) = 0 then


1223  TestEnemyType := 2 // extinct enemy  move to right end


1224  else if MyRO.EnemyReport[p1].TurnOfCivilReport >= MyRO.Turn  1


1225  then


1226  TestEnemyType := 0 // current report  move to left end


1227  else


1228  TestEnemyType := 1;


1229  if TestEnemyType = EnemyType then


1230  begin


1231  Column[nColumn] := p1;


1232  inc(nColumn);


1233  end;


1234  end;


1235  for i := 0 to nAdv  1 do


1236  begin


1237  ok := (MyRO.Tech[i] <> tsNA) or (MyRO.ResearchTech = i);


1238  for j := 1 to nColumn  1 do


1239  with MyRO.EnemyReport[Column[j]]^ do


1240  if (Tech[i] <> tsNA) or (TurnOfCivilReport >= 0) and


1241  (ResearchTech = i) then


1242  ok := true;


1243  if ok then


1244  begin


1245  code[0, Lines[0]] := i;


1246  inc(Lines[0]);


1247  end;


1248  end;


1249  SortTechs;


1250 


1251  ok := MyRO.ResearchTech = adMilitary;


1252  for j := 1 to nColumn  1 do


1253  with MyRO.EnemyReport[Column[j]]^ do


1254  if (MyRO.Alive and (1 shl Column[j]) <> 0) and


1255  (TurnOfCivilReport >= 0) and (ResearchTech = adMilitary) then


1256  ok := true;


1257  if ok then


1258  begin


1259  code[0, Lines[0]] := adMilitary;


1260  inc(Lines[0]);


1261  end


1262  end;


1263  kCities { , kChooseCity } :


1264  begin


1265  if ClientMode < scContact then


1266  for i := 0 to MyRO.nCity  1 do


1267  if MyCity[i].Loc >= 0 then


1268  begin


1269  code[0, Lines[0]] := i;


1270  inc(Lines[0])


1271  end;


1272  SortCities;


1273  FirstShrinkedLine[0] := 0


1274  end;


1275  kCityEvents:


1276  begin


1277  for i := 0 to MyRO.nCity  1 do


1278  if (MyCity[i].Loc >= 0) and (MyCity[i].Flags and CityRepMask <> 0)


1279  then


1280  begin


1281  code[0, Lines[0]] := i;


1282  inc(Lines[0])


1283  end;


1284  SortCities;


1285  FirstShrinkedLine[0] := 0


1286  end;


1287  { kChooseECity:


1288  begin


1289  for i:=0 to MyRO.nEnemyCity1 do


1290  if (MyRO.EnemyCity[i].Loc>=0)


1291  and (MyRO.EnemyCity[i].owner=DipMem[me].pContact) then


1292  begin code[0,Lines[0]]:=i; inc(Lines[0]); end;


1293  FirstShrinkedLine:=0


1294  end; }


1295  kModels:


1296  begin


1297  for mix := 0 to MyRO.nModel  1 do


1298  begin


1299  code[0, mix] := mix;


1300  MakeModelInfo(me, mix, MyModel[mix], mi);


1301  code[2, mix] := ModelSortValue(mi);


1302  end;


1303  Lines[0] := MyRO.nModel;


1304  SortModels;


1305  FirstShrinkedLine[0] := 0


1306  end;


1307  kChooseModel:


1308  begin


1309  for mix := 3 to MyRO.nModel  1 do


1310  begin // check if opponent already has this model


1311  MakeModelInfo(me, mix, MyModel[mix], mi);


1312  ok := true;


1313  for emix := 0 to MyRO.nEnemyModel  1 do


1314  if (MyRO.EnemyModel[emix].Owner = DipMem[me].pContact) and


1315  IsSameModel(MyRO.EnemyModel[emix], mi) then


1316  ok := false;


1317  if ok then


1318  begin


1319  code[0, Lines[0]] := mix;


1320  MakeModelInfo(me, mix, MyModel[mix], mi);


1321  code[2, Lines[0]] := ModelSortValue(mi);


1322  inc(Lines[0]);


1323  end;


1324  end;


1325  SortModels;


1326  // if Lines[0]>1 then


1327  begin


1328  code[0, Lines[0]] := mixAll;


1329  inc(Lines[0]);


1330  end;


1331  FirstShrinkedLine[0] := 0


1332  end;


1333  kChooseEModel:


1334  begin


1335  if MyRO.TestFlags and tfUncover <> 0 then


1336  Server(sGetModels, me, 0, nil^);


1337  for emix := 0 to MyRO.nEnemyModel  1 do


1338  ModelOk[emix] := MyRO.EnemyModel[emix].Owner = DipMem[me].pContact;


1339  for mix := 0 to MyRO.nModel  1 do


1340  begin // don't list models I already have


1341  MakeModelInfo(me, mix, MyModel[mix], mi);


1342  for emix := 0 to MyRO.nEnemyModel  1 do


1343  ModelOk[emix] := ModelOk[emix] and


1344  not IsSameModel(MyRO.EnemyModel[emix], mi);


1345  end;


1346  for emix := 0 to MyRO.nEnemyModel  1 do


1347  if ModelOk[emix] then


1348  begin


1349  if Tribe[DipMem[me].pContact].ModelPicture


1350  [MyRO.EnemyModel[emix].mix].HGr = 0 then


1351  InitEnemyModel(emix);


1352  code[0, Lines[0]] := emix;


1353  code[2, Lines[0]] := ModelSortValue(MyRO.EnemyModel[emix]);


1354  inc(Lines[0]);


1355  end;


1356  SortModels;


1357  // if not IsMilReportNew(DipMem[me].pContact) or (Lines[0]>1) then


1358  begin


1359  code[0, Lines[0]] := mixAll;


1360  inc(Lines[0]);


1361  end;


1362  FirstShrinkedLine[0] := 0


1363  end;


1364  kEModels:


1365  begin


1366  for i := 0 to MyRO.EnemyReport[pView].nModelCounted  1 do


1367  begin


1368  code[1, Lines[0]] := MyRO.nEnemyModel  1;


1369  while (code[1, Lines[0]] >= 0) and


1370  not((MyRO.EnemyModel[code[1, Lines[0]]].Owner = pView) and


1371  (MyRO.EnemyModel[code[1, Lines[0]]].mix = i)) do


1372  dec(code[1, Lines[0]]);


1373  if Tribe[pView].ModelPicture[i].HGr = 0 then


1374  InitEnemyModel(code[1, Lines[0]]);


1375  code[0, Lines[0]] := i;


1376  code[2, Lines[0]] :=


1377  ModelSortValue(MyRO.EnemyModel[code[1, Lines[0]]]);


1378  inc(Lines[0]);


1379  end;


1380  SortModels;


1381  FirstShrinkedLine[0] := 0


1382  end;


1383  kAllEModels:


1384  begin


1385  if (MyRO.TestFlags and tfUncover <> 0) or (G.Difficulty[me] = 0) then


1386  Server(sGetModels, me, 0, nil^);


1387  for emix := 0 to MyRO.nEnemyModel  1 do


1388  if (MyRO.EnemyModel[emix].mix >= 3) and


1389  (MyRO.EnemyModel[emix].Kind in [mkSelfDeveloped, mkEnemyDeveloped])


1390  then


1391  begin


1392  PPicture := @Tribe[MyRO.EnemyModel[emix].Owner].ModelPicture


1393  [MyRO.EnemyModel[emix].mix];


1394  if PPicture.HGr = 0 then


1395  InitEnemyModel(emix);


1396  ok := true;


1397  if MainScreen.mNames.Checked then


1398  for j := 0 to Lines[0]  1 do


1399  begin


1400  PTestPicture := @Tribe[MyRO.EnemyModel[code[0, j]].Owner]


1401  .ModelPicture[MyRO.EnemyModel[code[0, j]].mix];


1402  if (PPicture.HGr = PTestPicture.HGr) and


1403  (PPicture.pix = PTestPicture.pix) and


1404  (ModelHash(MyRO.EnemyModel[emix])


1405  = ModelHash(MyRO.EnemyModel[code[0, j]])) then


1406  begin


1407  code[1, j] := 1;


1408  ok := false;


1409  Break


1410  end;


1411  end;


1412  if ok then


1413  begin


1414  code[0, Lines[0]] := emix;


1415  code[1, Lines[0]] := 0;


1416  code[2, Lines[0]] := ModelSortValue(MyRO.EnemyModel[emix], true);


1417  inc(Lines[0]);


1418  end


1419  end;


1420  SortModels;


1421  FirstShrinkedLine[0] := 0


1422  end;


1423  kTribe:


1424  for i := 0 to TribeNames.Count  1 do


1425  begin


1426  code[0, Lines[0]] := i;


1427  inc(Lines[0])


1428  end;


1429  (* kDeliver:


1430  if MyRO.Treaty[DipMem[me].pContact]<trAlliance then


1431  begin // suggest next treaty level


1432  code[0,Lines[0]]:=opTreaty+MyRO.Treaty[DipMem[me].pContact]+1;


1433  inc(Lines[0]);


1434  end;


1435  if MyRO.Treaty[DipMem[me].pContact]=trNone then


1436  begin // suggest peace


1437  code[0,Lines[0]]:=opTreaty+trPeace;


1438  inc(Lines[0]);


1439  end;


1440  if MyRO.Treaty[DipMem[me].pContact]>trNone then


1441  begin // suggest next treaty level


1442  code[0,Lines[0]]:=opTreaty+MyRO.Treaty[DipMem[me].pContact]1;


1443  inc(Lines[0]);


1444  end; *)


1445  kShipPart:


1446  begin


1447  Lines[0] := 0;


1448  for i := 0 to nShipPart  1 do


1449  if MyRO.Ship[me].Parts[i] > 0 then


1450  begin


1451  code[0, Lines[0]] := i;


1452  inc(Lines[0]);


1453  end;


1454  end;


1455  kEShipPart:


1456  begin


1457  Lines[0] := 0;


1458  for i := 0 to nShipPart  1 do


1459  if MyRO.Ship[DipMem[me].pContact].Parts[i] > 0 then


1460  begin


1461  code[0, Lines[0]] := i;


1462  inc(Lines[0]);


1463  end;


1464  end;


1465  kGov:


1466  for i := 1 to nGov  1 do


1467  if (GovPreq[i] <> preNA) and


1468  ((GovPreq[i] = preNone) or (MyRO.Tech[GovPreq[i]] >= tsApplicable))


1469  then


1470  begin


1471  code[0, Lines[0]] := i;


1472  inc(Lines[0])


1473  end;


1474  kMission:


1475  for i := 0 to nSpyMission  1 do


1476  begin


1477  code[0, Lines[0]] := i;


1478  inc(Lines[0])


1479  end;


1480  end;


1481 


1482  if Kind = kProject then // test if choice fitting to one screen


1483  if Lines[0] + Lines[1] + Lines[2] <= MaxLines then


1484  begin


1485  for i := 0 to Lines[1]  1 do // add wonders to first page


1486  begin


1487  code[0, Lines[0]] := code[1, i];


1488  inc(Lines[0]);


1489  end;


1490  Lines[1] := 0;


1491  FirstShrinkedLine[0] := Lines[0];


1492  for i := 0 to Lines[2]  1 do // add models to first page


1493  begin


1494  code[0, Lines[0]] := code[2, i];


1495  inc(Lines[0]);


1496  end;


1497  Lines[2] := 0;


1498  end;


1499  end; // InitLines


1500 


1501  function TListDlg.OnlyChoice(TestKind: TListKind): integer;


1502  begin


1503  Kind := TestKind;


1504  InitLines;


1505  if Lines[0] = 0 then


1506  result := 2


1507  else if Lines[0] > 1 then


1508  result := 1


1509  else


1510  result := code[0, 0];


1511  end;


1512 


1513  procedure TListDlg.FormShow(Sender: TObject);


1514  var


1515  i: integer;


1516  begin


1517  result := 1;


1518  Closable := false;


1519 


1520  if Kind = kTribe then


1521  begin


1522  LineDistance := 21; // looks ugly with scrollbar


1523  MaxLines := (hMaintexture  (24 + TitleHeight + NarrowFrame))


1524  div LineDistance  1;


1525  end


1526  else


1527  begin


1528  LineDistance := 24;


1529  MaxLines := (hMaintexture  (24 + TitleHeight + WideFrame))


1530  div LineDistance  1;


1531  end;


1532  InitLines;


1533 


1534  MultiPage := false;


1535  for i := 1 to MaxLayer  1 do


1536  if Lines[i] > 0 then


1537  MultiPage := true;


1538  WideBottom := MultiPage or (Kind = kScience) or


1539  not Phrases2FallenBackToEnglish and


1540  (Kind in [kProject, kAdvance, kFarAdvance]);


1541  if (Kind = kAdvance) and (MyData.FarTech <> adNone) or (Kind = kModels) or


1542  (Kind = kEModels) then


1543  TitleHeight := WideFrame + 20


1544  else


1545  TitleHeight := WideFrame;


1546 


1547  DispLines := Lines[0];


1548  for i := 0 to MaxLayer  1 do


1549  if Lines[i] > DispLines then


1550  DispLines := Lines[i];


1551  if WideBottom then


1552  begin


1553  if DispLines > MaxLines then


1554  DispLines := MaxLines;


1555  InnerHeight := LineDistance * (DispLines + 1) + 24;


1556  ClientHeight := InnerHeight + TitleHeight + WideFrame


1557  end


1558  else


1559  begin


1560  if DispLines > MaxLines then


1561  DispLines := MaxLines;


1562  InnerHeight := LineDistance * (DispLines + 1) + 24;


1563  ClientHeight := InnerHeight + TitleHeight + NarrowFrame;


1564  end;


1565  assert(ClientHeight <= hMaintexture);


1566 


1567  TechNameSpace := 224;


1568  case Kind of


1569  kGov:


1570  InnerWidth := 272;


1571  kCities, kCityEvents:


1572  InnerWidth := 640  18;


1573  kTribe:


1574  if Lines[0] > MaxLines then


1575  InnerWidth := 280 + GetSystemMetrics(SM_CXVSCROLL)


1576  else


1577  InnerWidth := 280;


1578  kScience:


1579  begin


1580  InnerWidth := 104  33 + 15 + 8 + TechNameSpace + 24 * nColumn +


1581  GetSystemMetrics(SM_CXVSCROLL);


1582  if InnerWidth + 2 * SideFrame > 640 then


1583  begin


1584  TechNameSpace := TechNameSpace + 640  InnerWidth  2 * SideFrame;


1585  InnerWidth := 640  2 * SideFrame


1586  end


1587  end;


1588  kAdvance, kFarAdvance:


1589  InnerWidth := 104  33 + 15 + 8 + TechNameSpace + 24 +


1590  GetSystemMetrics(SM_CXVSCROLL);


1591  kChooseTech, kChooseETech, kStealTech:


1592  InnerWidth := 104  33 + 15 + 8 + TechNameSpace +


1593  GetSystemMetrics(SM_CXVSCROLL);


1594  else


1595  InnerWidth := 363;


1596  end;


1597  ClientWidth := InnerWidth + 2 * SideFrame;


1598 


1599  CloseBtn.Left := ClientWidth  38;


1600  CaptionLeft := ToggleBtn.Left + ToggleBtn.Width;


1601  CaptionRight := CloseBtn.Left;


1602  { TODO:


1603  SetWindowPos(sb.ScrollBar.Handle, 0, SideFrame + InnerWidth  GetSystemMetrics(SM_CXVSCROLL),


1604  TitleHeight, GetSystemMetrics(SM_CXVSCROLL), LineDistance * DispLines + 48,


1605  SWP_NOZORDER or SWP_NOREDRAW);


1606  }


1607 


1608  if WindowMode = wmModal then


1609  begin { center on screen }


1610  if Kind = kTribe then


1611  Left := (DpiScreen.Width  800) * 3 div 8 + 130


1612  else


1613  Left := (DpiScreen.Width  Width) div 2;


1614  Top := (DpiScreen.Height  Height) div 2;


1615  if Kind = kProject then


1616  Top := Top + 48;


1617  end;


1618 


1619  Layer0Btn.Visible := MultiPage and (Lines[0] > 0);


1620  Layer1Btn.Visible := MultiPage and (Lines[1] > 0);


1621  Layer2Btn.Visible := MultiPage and (Lines[2] > 0);


1622  if Kind = kProject then


1623  begin


1624  Layer0Btn.Top := ClientHeight  31;


1625  Layer0Btn.Left := ClientWidth div 2  (12 + 29);


1626  Layer0Btn.Down := true;


1627  Layer1Btn.Top := ClientHeight  31;


1628  Layer1Btn.Left := ClientWidth div 2  (12  29);


1629  Layer1Btn.Down := false;


1630  Layer2Btn.Top := ClientHeight  31;


1631  Layer2Btn.Left := ClientWidth div 2  12;


1632  Layer2Btn.Down := false;


1633  end;


1634 


1635  Layer := 0;


1636  Sel := 2;


1637  ScienceNation := 1;


1638  sb.Init(Lines[Layer]  1, DispLines);


1639 


1640  OffscreenPaint;


1641  end;


1642 


1643  procedure TListDlg.ShowNewContent(NewMode: integer; ListKind: TListKind);


1644  var


1645  i: integer;


1646  ShowFocus, forceclose: boolean;


1647  begin


1648  forceclose := (ListKind <> Kind) and


1649  not((Kind = kCities) and (ListKind = kCityEvents)) and


1650  not((Kind = kCityEvents) and (ListKind = kCities)) and


1651  not((Kind = kModels) and (ListKind = kEModels)) and


1652  not((Kind = kEModels) and (ListKind = kModels));


1653 


1654  Kind := ListKind;


1655  ModalIndication := not(Kind in MustChooseKind);


1656  case Kind of


1657  kProject:


1658  Caption := Phrases.Lookup('TITLE_PROJECT');


1659  kAdvance:


1660  Caption := Phrases.Lookup('TITLE_TECHSELECT');


1661  kFarAdvance:


1662  Caption := Phrases.Lookup('TITLE_FARTECH');


1663  kModels, kEModels:


1664  Caption := Phrases.Lookup('FRMILREP');


1665  kAllEModels:


1666  Caption := Phrases.Lookup('TITLE_EMODELS');


1667  kTribe:


1668  Caption := Phrases.Lookup('TITLE_TRIBE');


1669  kScience:


1670  Caption := Phrases.Lookup('TITLE_SCIENCE');


1671  kShipPart, kEShipPart:


1672  Caption := Phrases.Lookup('TITLE_CHOOSESHIPPART');


1673  kChooseTech, kChooseETech:


1674  Caption := Phrases.Lookup('TITLE_CHOOSETECH');


1675  kChooseModel, kChooseEModel:


1676  Caption := Phrases.Lookup('TITLE_CHOOSEMODEL');


1677  kStealTech:


1678  Caption := Phrases.Lookup('TITLE_CHOOSETECH');


1679  kGov:


1680  Caption := Phrases.Lookup('TITLE_GOV');


1681  kMission:


1682  Caption := Phrases.Lookup('TITLE_SPYMISSION');


1683  end;


1684 


1685  case Kind of


1686  kMission:


1687  HelpContext := 'SPYMISSIONS';


1688  else


1689  HelpContext := 'CONCEPTS'


1690  end;


1691 


1692  if Kind = kAdvance then


1693  begin


1694  ToggleBtn.ButtonIndex := 13;


1695  ToggleBtn.Hint := Phrases.Lookup('FARTECH')


1696  end


1697  else if Kind = kCities then


1698  begin


1699  ToggleBtn.ButtonIndex := 15;


1700  ToggleBtn.Hint := Phrases.Lookup('BTN_PAGE')


1701  end


1702  else


1703  begin


1704  ToggleBtn.ButtonIndex := 28;


1705  ToggleBtn.Hint := Phrases.Lookup('BTN_SELECT')


1706  end;


1707 


1708  if Kind = kAdvance then // show focus button?


1709  if MyData.FarTech <> adNone then


1710  ShowFocus := true


1711  else


1712  begin


1713  ShowFocus := false;


1714  for i := 0 to nAdv  1 do


1715  if not(i in FutureTech) and (MyRO.Tech[i] < tsApplicable) and


1716  ((AdvValue[i] < 2000) or (MyRO.Tech[adMassProduction] > tsNA)) and


1717  ((AdvValue[i] < 1000) or (MyRO.Tech[adScience] > tsNA)) and


1718  (Server(sSetResearch  sExecute, me, i, nil^) < rExecuted) then


1719  ShowFocus := true;


1720  end;


1721  ToggleBtn.Visible := (Kind = kCities) and not supervising or (Kind = kAdvance)


1722  and ShowFocus or (Kind = kModels) or (Kind = kEModels);


1723  CloseBtn.Visible := not(Kind in MustChooseKind);


1724 


1725  inherited ShowNewContent(NewMode, forceclose);


1726  end; // ShowNewContent


1727 


1728  procedure TListDlg.ShowNewContent_CityProject(NewMode, cix: integer);


1729  begin


1730  cixProject := cix;


1731  ShowNewContent(NewMode, kProject);


1732  end;


1733 


1734  procedure TListDlg.ShowNewContent_MilReport(NewMode, p: integer);


1735  begin


1736  pView := p;


1737  if p = me then


1738  ShowNewContent(NewMode, kModels)


1739  else


1740  ShowNewContent(NewMode, kEModels)


1741  end;


1742 


1743  procedure TListDlg.PlayerClick(Sender: TObject);


1744  begin


1745  if TComponent(Sender).Tag = me then


1746  Kind := kModels


1747  else


1748  begin


1749  Kind := kEModels;


1750  pView := TComponent(Sender).Tag;


1751  end;


1752  InitLines;


1753  Sel := 2;


1754  sb.Init(Lines[Layer]  1, DispLines);


1755  OffscreenPaint;


1756  Invalidate


1757  end;


1758 


1759  procedure TListDlg.ModeBtnClick(Sender: TObject);


1760  begin


1761  Layer0Btn.Down := Sender = Layer0Btn;


1762  Layer1Btn.Down := Sender = Layer1Btn;


1763  Layer2Btn.Down := Sender = Layer2Btn;


1764  Layer := TComponent(Sender).Tag;


1765 


1766  Sel := 2;


1767  sb.Init(Lines[Layer]  1, DispLines);


1768  SmartUpdateContent


1769  end;


1770 


1771  procedure TListDlg.ToggleBtnClick(Sender: TObject);


1772  var


1773  p1: integer;


1774  m: TMenuItem;


1775  begin


1776  case Kind of


1777  kAdvance:


1778  begin


1779  result := adFar;


1780  Closable := true;


1781  Close


1782  end;


1783  kCities, kCityEvents:


1784  begin


1785  if Kind = kCities then


1786  Kind := kCityEvents


1787  else


1788  Kind := kCities;


1789  OffscreenPaint;


1790  Invalidate;


1791  end;


1792  kModels, kEModels:


1793  begin


1794  EmptyMenu(Popup.Items);


1795  if G.Difficulty[me] > 0 then


1796  begin


1797  m := TMenuItem.Create(Popup);


1798  m.RadioItem := true;


1799  m.Caption := Tribe[me].TPhrase('SHORTNAME');


1800  m.Tag := me;


1801  m.OnClick := PlayerClick;


1802  if Kind = kModels then


1803  m.Checked := true;


1804  Popup.Items.Add(m);


1805  end;


1806  for p1 := 0 to nPl  1 do


1807  if (p1 <> me) and (MyRO.EnemyReport[p1] <> nil) and


1808  (MyRO.EnemyReport[p1].TurnOfMilReport >= 0) then


1809  begin


1810  m := TMenuItem.Create(Popup);


1811  m.RadioItem := true;


1812  m.Caption := Tribe[p1].TPhrase('SHORTNAME');


1813  m.Tag := p1;


1814  m.OnClick := PlayerClick;


1815  if (Kind = kEModels) and (p1 = pView) then


1816  m.Checked := true;


1817  Popup.Items.Add(m);


1818  end;


1819  Popup.Popup(Left + ToggleBtn.Left, Top + ToggleBtn.Top +


1820  ToggleBtn.Height);


1821  end


1822  end


1823  end;


1824 


1825  procedure TListDlg.FormKeyDown(Sender: TObject; var Key: word;


1826  Shift: TShiftState);


1827  begin


1828  if (Key = VK_F2) and (Kind in [kModels, kEModels]) then // my key


1829  // !!! toggle


1830  else if (Key = VK_F3) and (Kind in [kCities, kCityEvents]) then // my key


1831  ToggleBtnClick(nil)


1832  else if ((Key = VK_ESCAPE) or (Key = VK_RETURN)) and not CloseBtn.Visible then


1833  // prevent closing


1834  else


1835  inherited


1836  end;


1837 


1838  procedure TListDlg.EcoChange;


1839  begin


1840  if Visible and (Kind = kCities) then


1841  SmartUpdateContent


1842  end;


1843 


1844  procedure TListDlg.TechChange;


1845  begin


1846  if Visible and (Kind = kScience) then


1847  begin


1848  FormShow(nil);


1849  Invalidate;


1850  end;


1851  end;


1852 


1853  procedure TListDlg.AddCity;


1854  begin


1855  if Visible and (Kind = kCities) then


1856  begin


1857  FormShow(nil);


1858  Invalidate;


1859  end;


1860  end;


1861 


1862  procedure TListDlg.RemoveUnit;


1863  begin


1864  if ListDlg.Visible and (Kind = kModels) then


1865  SmartUpdateContent;


1866  end;


1867 


1868  procedure TListDlg.ScrollBarUpdate(Sender: TObject);


1869  begin


1870  Sel := 2;


1871  SmartUpdateContent(true);


1872  end;


1873 


1874  end.

