OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4ConsoleCocoa.mm
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #include <GL/glew.h>
17 
18 #include "C4Include.h"
19 #include "editor/C4Console.h"
20 #include "game/C4Application.h"
21 
22 #include "control/C4GameSave.h"
23 #include "game/C4Game.h"
24 #include "gui/C4MessageInput.h"
25 #include "C4Version.h"
26 #include "c4group/C4Language.h"
27 #include "player/C4Player.h"
28 #include "landscape/C4Landscape.h"
29 #include "landscape/C4Sky.h"
30 #include "game/C4GraphicsSystem.h"
31 #include "player/C4PlayerList.h"
32 #include "control/C4GameControl.h"
33 #include "landscape/C4Texture.h"
34 
35 #include "platform/StdFile.h"
36 #include "platform/StdRegistry.h"
37 
38 #import <Cocoa/Cocoa.h>
41 #import "graphics/C4DrawGLMac.h"
42 
43 // implementation of C4Console GUI for Mac OS X
44 
45 static inline C4EditorWindowController* ctrler(C4ConsoleGUI* gui) {return gui->objectiveCObject<C4EditorWindowController>();}
46 
48 {
49 public:
50  State(C4ConsoleGUI *console): Super(console) {}
51 };
52 
54 {
55 public:
56  State(C4ToolsDlg *toolsDlg): Super(toolsDlg) {}
57  ~State()
58  {
59  [ctrler(&Console).toolsPanel orderOut:nil];
60  }
61  CGImageRef CreatePreviewImage();
62  void Default() {}
63  void Clear() {}
64 };
65 
67 {
68  C4WindowController* controller = [C4EditorWindowController new];
69  setObjectiveCObject(controller);
70  [NSBundle loadNibNamed:@"Editor" owner:controller];
71  [controller setStdWindow:this];
72  this->Active = true;
73  return true;
74 }
75 
77 {
78 }
79 
80 void C4ConsoleGUI::Out(const char* message)
81 {
82  C4EditorWindowController* controller = ctrler(this);
83  if (controller)
84  {
85  NSTextStorage* textStorage = controller.outputTextView.textStorage;
86  [textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%s\n", message]]];
87  [controller.outputTextView scrollRangeToVisible:NSMakeRange([textStorage length]-1, 1)];
88  }
89 }
90 
92 {
93  [ctrler(this).outputTextView.textStorage
94  replaceCharactersInRange:NSMakeRange(0, ctrler(this).outputTextView.textStorage.length)
95  withAttributedString:[[NSAttributedString alloc] initWithString:@""]];
96  return true;
97 }
98 
100 {
101  NSTextField* label;
102  switch (type)
103  {
105  label = ctrler(this).frameLabel;
106  break;
107  case CONSOLE_TimeFPS:
108  label = ctrler(this).timeLabel;
109  break;
110  case CONSOLE_Cursor:
111  return;
112  default:
113  return;
114  }
115  [label setStringValue:[NSString stringWithUTF8String:text.getData()]];
116 }
117 
118 void C4ConsoleGUI::SetCaptionToFileName(const char* file_name)
119 {
120  [ctrler(this).window setRepresentedFilename:[NSString stringWithUTF8String:file_name]];
121 }
122 
123 bool C4ConsoleGUI::FileSelect(StdStrBuf *sFilename, const char * szFilter, DWORD dwFlags, bool fSave)
124 {
125  NSSavePanel* savePanel = fSave ? [NSSavePanel savePanel] : [NSOpenPanel openPanel];
126  if (!fSave)
127  {
128  [(NSOpenPanel*)savePanel setCanChooseFiles:YES];
129  [(NSOpenPanel*)savePanel setCanChooseDirectories:YES];
130  }
131  if ([savePanel runModal] == NSFileHandlingPanelOKButton && [[savePanel URL] isFileURL])
132  {
133  sFilename->Copy([[savePanel URL].path cStringUsingEncoding:NSUTF8StringEncoding]);
134  return true;
135  }
136  else
137  return false;
138 }
139 
141 {
142  NSMenuItem* item = [
143  [C4AppDelegate instance].addViewportForPlayerMenuItem.submenu
144  addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(newViewportForPlayer:) keyEquivalent:@""
145  ];
146  [item setTag:player->Number];
147  [item setTarget: C4AppDelegate.instance];
148 }
149 
151 {
152  [[C4AppDelegate instance].addViewportForPlayerMenuItem.submenu removeAllItems];
153 }
154 
155 bool C4ConsoleGUI::Message(const char *message, bool query)
156 {
157  NSAlert* alert = [NSAlert
158  alertWithMessageText:[NSString stringWithUTF8String:C4ENGINECAPTION]
159  defaultButton:query ? @"Yes" : nil
160  alternateButton:query ? @"No" : nil
161  otherButton:nil
162  informativeTextWithFormat:[NSString stringWithUTF8String:message]
163  ];
164  [alert runModal];
165  return true;
166 }
167 
169 {
170  [ctrler(this).objectsPanel orderFront:nil];
171  return true;
172 }
173 
175 {
176  [ctrler(this).objectsPanel orderOut:nil];
177 }
178 
179 void C4ConsoleGUI::PropertyDlgUpdate(C4EditCursorSelection &rSelection, bool force_function_update)
180 {
181  if (![ctrler(this).objectsPanel isVisible])
182  return;
183  StdStrBuf text = rSelection.GetDataString();
184  [ctrler(this).objectPropertiesText.textStorage setAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:text.getData()]]];
185 }
186 
188 {
189  [ctrler(this).toolsPanel orderOut:nil];
190 }
191 
193 {
194  [ctrler(this).toolsPanel orderFront:nil];
195  return true;
196 }
197 
199 {
200  NSPopUpButton* materialsPopup = ctrler(this).materialsPopup;
201  [materialsPopup removeAllItems];
202  [materialsPopup addItemWithTitle:[NSString stringWithUTF8String:C4TLS_MatSky]];
203  NSMutableArray* ary = [[NSMutableArray alloc] initWithCapacity:MaterialMap.Num+1];
204  [ary addObject:[NSString stringWithUTF8String:C4TLS_MatSky]];
205  for (int32_t cnt = 0; cnt < ::MaterialMap.Num; cnt++)
206  {
207  [ary addObject:[NSString stringWithUTF8String: ::MaterialMap.Map[cnt].Name]];
208  }
209  [ary sortUsingComparator:^(id a, id b) {return [a compare:b];}];
210  for (NSString* s in ary)
211  {
212  [materialsPopup addItemWithTitle:s];
213  }
214  [materialsPopup selectItemWithTitle:[NSString stringWithUTF8String:dlg->Material]];
215 }
216 
218 {
219  [ctrler(&Console).toolSelector setSelectedSegment:Tool];
220 }
221 
223 {
224  // Refill dlg
225  NSPopUpButton* texturesPopup = ctrler(&Console).texturesPopup;
226  [texturesPopup removeAllItems];
227  // bottom-most: any invalid textures
228  bool fAnyEntry = false; int32_t cnt; const char *szTexture;
230  for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
231  {
232  if (!::TextureMap.GetIndex(Material, szTexture, false))
233  {
234  fAnyEntry = true;
235  [texturesPopup insertItemWithTitle:[NSString stringWithUTF8String:szTexture] atIndex:0];
236  }
237  }
238  // separator
239  if (fAnyEntry)
240  {
241  [texturesPopup insertItemWithTitle:@"-------" atIndex:0];
242  }
243 
244  // atop: valid textures
245  for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
246  {
247  // Current material-texture valid? Always valid for exact mode
248  if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.GetMode()==LandscapeMode::Exact)
249  {
250  [texturesPopup insertItemWithTitle:[NSString stringWithUTF8String:szTexture] atIndex:0];
251  }
252  }
253  // reselect current
254  [texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:Texture]];
255 }
256 
258 {
259  CGImageRef image = state->CreatePreviewImage();
260  [ctrler(&Console).previewView setImage:image imageProperties:[NSDictionary dictionary]];
261  CGImageRelease(image);
262 }
263 
264 namespace
265 {
266  // copy-pasta from http://stackoverflow.com/questions/2395650/fastest-way-to-draw-a-screen-buffer-on-the-iphone
267  const void* GetBytePointer(void* info)
268  {
269  // this is currently only called once
270  return info; // info is a pointer to the buffer
271  }
272 
273  void ReleaseBytePointer(void*info, const void* pointer)
274  {
275  // don't care, just using the one static buffer at the moment
276  }
277 
278 
279  size_t GetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
280  {
281  // I don't think this ever gets called
282  memcpy(buffer, ((char*)info) + position, count);
283  return count;
284  }
285 }
286 
287 CGImageRef C4ToolsDlg::State::CreatePreviewImage()
288 {
289  C4Surface * sfcPreview;
290  int32_t iPrvWdt,iPrvHgt;
291 
292  iPrvWdt = [ctrler(&Console).previewView frame].size.width;
293  iPrvHgt = [ctrler(&Console).previewView frame].size.height;
294 
295  if (!(sfcPreview=new C4Surface(iPrvWdt,iPrvHgt,0))) return NULL;
296 
297  // fill bg
298  BYTE bCol = 0;
299  C4Pattern Pattern;
300  // Sky material: sky as pattern only
302  {
303  Pattern.Set(::Landscape.GetSky().Surface, 0);
304  }
305  // Material-Texture
306  else
307  {
309  // Get/Create TexMap entry
311  if (iTex)
312  {
313  // Define texture pattern
314  const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex);
315  // Security
316  if (pTex)
317  {
318  // Set drawing pattern
319  Pattern = pTex->GetPattern();
320  }
321  }
322  }
323 
325  sfcPreview,
326  iPrvWdt/2,iPrvHgt/2,
327  GetOwner()->Grade,
328  bCol, Pattern, *::Landscape.GetPal()
329  );
330  //Application.DDraw->AttachPrimaryPalette(sfcPreview);
331 
332  DWORD *pixels = new DWORD[iPrvWdt*iPrvHgt];
333  for (int x = 0; x < iPrvWdt; x++) for (int y = 0; y < iPrvHgt; y++)
334  {
335  pixels[x+y*iPrvWdt] = sfcPreview->GetPixDw(x, y, true);
336  }
337  CGDataProviderDirectCallbacks callbacks = {0, ::GetBytePointer, ::ReleaseBytePointer, ::GetBytesAtPosition, 0};
338  CGDataProviderRef pixelData = CGDataProviderCreateDirect(pixels, iPrvWdt*iPrvHgt*sizeof(DWORD), &callbacks);
339  CGImageRef image = CGImageCreate(iPrvWdt, iPrvHgt, 8, 4*8, iPrvWdt*4, [[NSColorSpace deviceRGBColorSpace] CGColorSpace], kCGBitmapByteOrder32Little, pixelData, NULL, true, kCGRenderingIntentDefault);
340  CGDataProviderRelease(pixelData);
341  delete sfcPreview;
342  return image;
343 }
344 
346 {
347 }
348 
350 {
351  return true;
352 }
353 
355 {
356  StdStrBuf strMessage; strMessage.Format("%s %s\n\n%s", C4ENGINECAPTION, C4VERSION, copyright.getData());
357  Message(strMessage.getData(), false);
358 }
359 
360 void C4ConsoleGUI::ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture)
361 {
362  [ctrler(this).texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:texture]];
363 }
364 
365 void C4ConsoleGUI::ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material)
366 {
367  [ctrler(this).materialsPopup selectItemWithTitle:[NSString stringWithUTF8String:material]];
368 }
369 
370 void C4ConsoleGUI::ToolsDlgSelectBackTexture(C4ToolsDlg *dlg, const char *texture)
371 {
372  // TODO
373 }
374 
375 void C4ConsoleGUI::ToolsDlgSelectBackMaterial(C4ToolsDlg *dlg, const char *material)
376 {
377  // TODO
378 }
379 
381 {
382 }
383 
385 {
386 }
387 
389 {
390  [C4AppDelegate.instance.recordMenuItem setEnabled:NO];
391 }
392 
394 {
395  [C4AppDelegate.instance.netMenu setHidden:NO];
396 }
397 
399 {
400  [C4AppDelegate.instance.netMenu setHidden:YES];
401 }
402 
403 void C4ConsoleGUI::DoEnableControls(bool fEnable)
404 {
405  [ctrler(this).modeSelector setEnabled:fEnable];
406 }
407 
408 bool C4ConsoleGUI::DoUpdateHaltCtrls(bool fHalt)
409 {
410  return true;
411 }
412 
414 {
416 }
417 
419 {
420 }
421 
423 {
424  NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:text.getData() encoding:NSUTF8StringEncoding] action:@selector(kickPlayer:) keyEquivalent:[NSString string]];
425  [item setTarget:ctrler(this)];
426  [C4AppDelegate.instance.netMenu.submenu addItem:item];
427 }
428 
429 void C4ConsoleGUI::SetInputFunctions(std::list<const char*> &functions)
430 {
431  [ctrler(this).consoleCombo setStringValue:[NSString string]];
432  [ctrler(this) setInputFunctions:functions];
433 }
434 
435 void C4ConsoleGUI::AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled)
436 {
437  NSMenuItem* item = [
438  [C4AppDelegate instance].kickPlayerMenuItem.submenu
439  addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(kickPlayer:) keyEquivalent:@""
440  ];
441  [item setEnabled:enabled];
442  [item setTag:player->Number];
443  [item setTarget: ctrler(this)];
444 }
445 
447 {
448  return true;
449 }
450 
452 {
453 }
454 
455 bool C4ConsoleGUI::UpdateModeCtrls(int iMode)
456 {
457  return true;
458 }
459 
460 #define CONSOLEGUICOMMONINCLUDE
const char * getData() const
Definition: StdBuf.h:450
State(C4ToolsDlg *dlg)
Definition: C4Console.cpp:663
C4Console Console
Definition: C4Globals.cpp:45
class C4Surface * Surface
Definition: C4Sky.h:53
void SetCaptionToFileName(const char *file_name)
Definition: C4Console.cpp:694
bool PopMaterial()
Definition: C4Console.cpp:708
void DeleteConsoleWindow()
Definition: C4Console.cpp:683
void ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material)
Definition: C4Console.cpp:700
void ToolsDlgSelectBackTexture(C4ToolsDlg *dlg, const char *texture)
Definition: C4Console.cpp:703
void ToolsDlgInitMaterialCtrls(class C4ToolsDlg *dlg)
Definition: C4Console.cpp:698
uint8_t BYTE
bool DoUpdateHaltCtrls(bool fHalt)
Definition: C4Console.cpp:686
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
C4TextureMap TextureMap
Definition: C4Texture.cpp:580
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85
Definition: C4Texture.h:48
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:97
void PropertyDlgUpdate(class C4EditCursorSelection &rSelection, bool force_function_update)
Definition: C4Console.cpp:692
bool PropertyDlgOpen()
Definition: C4Console.cpp:690
int32_t GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:423
int32_t Grade
Definition: C4ToolsDlg.h:54
const C4Pattern & GetPattern() const
Definition: C4Texture.h:64
char Texture[C4M_MaxName+1]
Definition: C4ToolsDlg.h:57
void ClearNetMenu()
Definition: C4Console.cpp:673
void ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture)
Definition: C4Console.cpp:701
void ShowAboutWithCopyright(StdStrBuf &copyright)
Definition: C4Console.cpp:697
C4Landscape Landscape
char Material[C4M_MaxName+1]
Definition: C4ToolsDlg.h:56
class C4Sky & GetSky()
void Out(const char *message)
Definition: C4Console.cpp:689
C4Draw * pDraw
Definition: C4Draw.cpp:45
int32_t Num
Definition: C4Material.h:170
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
Definition: C4Surface.cpp:501
void ToolsDlgSelectBackMaterial(C4ToolsDlg *dlg, const char *material)
Definition: C4Console.cpp:702
State(C4ConsoleGUI *console)
Definition: C4Console.cpp:659
LandscapeMode GetMode() const
void InitGradeCtrl()
Definition: C4Console.cpp:706
bool Message(const char *message, bool query)
Definition: C4Console.cpp:688
void AddNetMenuItemForPlayer(int32_t client_id, const char *text, C4ConsoleGUI::ClientOperation co)
Definition: C4Console.cpp:669
void UpdateIFTControls()
Definition: C4Console.cpp:710
void AddKickPlayerMenuItem(C4Player *player, StdStrBuf &player_text, bool enabled)
Definition: C4Console.cpp:667
bool ToolsDlgOpen(class C4ToolsDlg *dlg)
Definition: C4Console.cpp:699
void ClearViewportMenu()
Definition: C4Console.cpp:675
int32_t Get(const char *szMaterial)
Definition: C4Material.cpp:362
void NeedPreviewUpdate()
Definition: C4Console.cpp:707
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:503
bool UpdateModeCtrls(int iMode)
Definition: C4Console.cpp:704
void UpdateToolCtrls()
Definition: C4Console.cpp:713
void UpdateLandscapeModeCtrls()
Definition: C4Console.cpp:711
void RecordingEnabled()
Definition: C4Console.cpp:693
bool CreateConsoleWindow(C4AbstractApp *application)
Definition: C4Console.cpp:676
bool PopTextures()
Definition: C4Console.cpp:709
C4MaterialMap MaterialMap
Definition: C4Material.cpp:970
CStdPalette * GetPal() const
bool Active
Definition: C4Window.h:278
BYTE Mat2PixColDefault(int32_t mat)
Definition: C4Material.h:237
void SetInputFunctions(std::list< const char * > &functions)
Definition: C4Console.cpp:696
bool FileSelect(StdStrBuf *sFilename, const char *szFilter, DWORD dwFlags, bool fSave)
Definition: C4Console.cpp:687
bool ClearLog()
Definition: C4Console.cpp:672
bool Set(class C4Surface *sfcSource, int iZoom=0)
Definition: C4Draw.cpp:117
void AddMenuItemForPlayer(C4Player *player, StdStrBuf &player_text)
Definition: C4Console.cpp:668
void ToolsDlgClose()
Definition: C4Console.cpp:671
void DoEnableControls(bool fEnable)
Definition: C4Console.cpp:685
#define C4TLS_MatSky
Definition: C4ToolsDlg.h:39
void DrawPatternedCircle(C4Surface *sfcDest, int x, int y, int r, BYTE col, C4Pattern &Pattern, CStdPalette &rPal)
Definition: C4Draw.cpp:678
void AddNetMenu()
Definition: C4Console.cpp:670
void DisplayInfoText(InfoTextType type, StdStrBuf &text)
Definition: C4Console.cpp:684
C4AppDelegate * instance()
void ClearPlayerMenu()
Definition: C4Console.cpp:674
uint32_t DWORD
void Copy()
Definition: StdBuf.h:475
#define s
void SetCursor(Cursor cursor)
Definition: C4Console.cpp:695
StdStrBuf GetDataString() const
void UpdateTextures()
Definition: C4Console.cpp:712
void EnableControls()
Definition: C4Console.cpp:705
void PropertyDlgClose()
Definition: C4Console.cpp:691
class InternalState< class C4ConsoleGUI > Super
Definition: C4ConsoleGUI.h:43