--- /dev/null
+unit TalkShowFrame;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, StdCtrls, SsParser, ExtCtrls, SppList, SppTypes, Logs,
+ BottleDef;
+
+type
+ TfrmTalkShow = class(TFrame)
+ ScrollBar: TScrollBar;
+ PaintBox: TPaintBox;
+ procedure PaintBoxPaint(Sender: TObject);
+ procedure ScrollBarChange(Sender: TObject);
+ private
+ FSsParser: TSsParser;
+ FLog: TLogItem;
+ FWholeHeight: integer;
+ procedure SetSsParser(const Value: TSsParser);
+ protected
+ function DrawSingleTalk(VertPos: integer;
+ Sur1, Sur2: integer; Talk: String): integer;
+ public
+ { Public \90é\8c¾ }
+ property SsParser: TSsParser read FSsParser write SetSsParser;
+ procedure View(ALog: TLogItem);
+ end;
+
+implementation
+
+{$R *.dfm}
+
+{ TfrmTalkShow }
+
+procedure TfrmTalkShow.SetSsParser(const Value: TSsParser);
+begin
+ FSsParser := Value;
+end;
+
+procedure TfrmTalkShow.View(ALog: TLogItem);
+begin
+ FSsParser.InputString := ALog.Script;
+ if FLog <> nil then
+ FreeAndNil(FLog);
+ FLog := TLogItem.Create(ALog);
+ FWholeHeight := -1; // \96¢\92è\8b`
+ PaintBoxPaint(self);
+end;
+
+procedure TfrmTalkShow.PaintBoxPaint(Sender: TObject);
+var i, x, y, sur, sur0, sur1: integer;
+ UnyuTalking, InSync: boolean;
+ Talk: String;
+ procedure TalkEnd;
+ begin
+ if Talk <> '' then
+ begin
+ if InSync then
+ y := y + DrawSingleTalk(y, sur0, sur1, Talk) + 5
+ else if UnyuTalking then
+ y := y + DrawSingleTalk(y, -1, sur1, Talk) + 5
+ else
+ y := y + DrawSingleTalk(y, sur0, -1, Talk) + 5;
+ Talk := '';
+ end;
+ end;
+begin
+ // \8fÁ\8b\8e
+ with PaintBox.Canvas do
+ begin
+ Brush.Color := Pref.BgColor;
+ Brush.Style := bsSolid;
+ FillRect(Rect(0, 0, PaintBox.Width, PaintBox.Height));
+ Brush.Style := bsClear;
+ end;
+
+ if FWholeHeight < 0 then // -1\82Í\96¢\92è\8b`
+ y := 0
+ else
+ y := - ScrollBar.Position;
+ sur0 := 0; // \83X\83R\81[\83v0\91¤\8f\89\8aú\83T\81[\83t\83B\83X
+ sur1 := 10; // \83X\83R\81[\83v1\91¤\8f\89\8aú\83T\81[\83t\83B\83X
+ Talk := '';
+ UnyuTalking := false;
+ InSync := false;
+ //
+ for i := 0 to FSsParser.Count-1 do
+ begin
+ if FSsParser[i] = '\h' then
+ begin
+ TalkEnd;
+ UnyuTalking := false;
+ end else if FSsParser[i] = '\u' then
+ begin
+ TalkEnd;
+ UnyuTalking := true;
+ end else if FSsParser[i] = '\_s' then
+ begin
+ TalkEnd;
+ InSync := not InSync;
+ end else if FSsParser.Match(FSsParser[i], '\s[%D]') > 0 then
+ begin
+ TalkEnd;
+ sur := StrToInt(FSsParser.GetParam(FSsParser[i], 1));
+ if InSync then
+ begin
+ sur0 := sur;
+ sur1 := sur;
+ end else if UnyuTalking then
+ sur1 := sur
+ else
+ sur0 := sur;
+ end else if FSsParser.Match(FSsParser[i], '\s%d') > 0 then
+ begin
+ TalkEnd;
+ sur := Ord(FSsParser[i][3]) - Ord('0');
+ if InSync then
+ begin
+ sur0 := sur;
+ sur1 := sur;
+ end else if UnyuTalking then
+ sur1 := sur
+ else
+ sur0 := sur;
+ end else if FSsParser.MarkUpType[i] in [mtStr, mtMeta] then
+ begin
+ Talk := Talk + FSsParser[i];
+ end;
+ end;
+ TalkEnd;
+ if FWholeHeight = -1 then
+ begin
+ FWholeHeight := y;
+ ScrollBar.Position := 0;
+ if FWholeHeight > PaintBox.Height then
+ begin
+ ScrollBar.Max := FWholeHeight - PaintBox.Height;
+ ScrollBar.Enabled := true;
+ end else
+ begin
+ ScrollBar.Max := 0;
+ ScrollBar.Enabled := false;
+ end;
+ end;
+end;
+
+function TfrmTalkShow.DrawSingleTalk(VertPos, Sur1, Sur2: integer;
+ Talk: String): integer;
+var Bmp: TBitmap;
+ H: integer;
+ ARect: TRect;
+begin
+ Bmp := TBitmap.Create;
+ try
+ if Spps.TryGetImage(FLog.Ghost, Surface, Bmp) then
+ begin
+ PaintBox.Canvas.Draw(0, VertPos, Bmp);
+ ARect := Rect(Bmp.Width + 10, VertPos, PaintBox.Width-5, VertPos+10000);
+ H := DrawTextEx(PaintBox.Canvas.Handle, PChar(Talk), -1, ARect,
+ DT_WORDBREAK, nil);
+ if H > Bmp.Height then
+ Result := H
+ else
+ Result := Bmp.Height;
+ end;
+ finally
+ Bmp.Free;
+ end;
+end;
+
+procedure TfrmTalkShow.ScrollBarChange(Sender: TObject);
+begin
+ PaintBoxPaint(self);
+end;
+
+end.