Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / client / src / interface_v3 / action_handler_misc.cpp
blob91e00807d90b9e9401adffd74113165b2f8b4558
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
22 #include "action_handler_misc.h"
23 #include "interface_manager.h"
24 #include "nel/gui/ctrl_button.h"
25 #include "nel/gui/group_container.h"
26 #include "nel/gui/group_editbox.h"
27 #include "people_interraction.h"
28 #include "nel/misc/algo.h"
29 #include "nel/gui/interface_expr.h"
30 #include "nel/gui/interface_link.h"
31 #include "../client_chat_manager.h"
32 #include "../motion/user_controls.h"
33 #include "../entity_cl.h"
34 #include "../client_cfg.h"
35 #include "../fog_map.h"
36 #include "../sky_render.h"
37 #include "../continent_manager.h"
38 #include "../main_loop.h"
39 #include "../misc.h"
41 using namespace std;
42 using namespace NLMISC;
43 using namespace NL3D;
45 ////////////
46 // EXTERN //
47 ////////////
49 extern CClientChatManager ChatMngr;
50 extern UScene *SceneRoot;
51 extern UScene *SkyScene;
52 extern UScene *Scene;
53 extern CFogState MainFogState;
54 extern CFogState RootFogState;
55 extern CLightCycleManager LightCycleManager;
56 extern UCamera MainCam;
57 extern CContinentManager ContinentMngr;
58 extern NLMISC::CLog g_log;
60 ////////////
61 // static //
62 ////////////
63 //static CCDBNodeLeaf *MenuColorWidgetValue = NULL; // db entry for the color menu widget (Red)
66 static const string ScreenshotsDirectory("screenshots/"); // don't forget the final /
68 void preRenderNewSky ();
70 // ***************************************************************************
71 class CAHCommand : public IActionHandler
73 public:
75 virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
77 ICommand::execute(Params, g_log);
80 REGISTER_ACTION_HANDLER (CAHCommand, "command");
82 // ***************************************************************************
83 // ***************************************************************************
84 // class CActionHandlerShowOne
85 // ***************************************************************************
86 // ***************************************************************************
89 // ***************************************************************************
90 REGISTER_ACTION_HANDLER (CActionHandlerShowOne, "show_one");
92 // ***************************************************************************
93 void CActionHandlerShowOne::execute (CCtrlBase * /* pCaller */, const std::string &params)
95 CInterfaceManager *mngr= CInterfaceManager::getInstance();
96 string wndListValue= getParam(params, "list");
97 string wndShow= getParam(params, "show");
99 // get the list
100 vector<string> wndList;
101 splitString(wndListValue, ",", wndList);
103 // hide all window from the list.
104 for(uint i=0;i<wndList.size();i++)
106 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(wndList[i]);
107 if(wnd)
108 wnd->setActive(false);
111 // show the one needed
112 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(wndShow);
113 if(wnd)
114 wnd->setActive(true);
118 // ***************************************************************************
119 REGISTER_ACTION_HANDLER (CActionHandlerActive, "set_active");
120 // ***************************************************************************
121 void CActionHandlerActive::execute (CCtrlBase * /* pCaller */, const std::string &params)
123 std::string active = getParam(params, "active");
124 std::string target = getParam(params, "target");
125 CInterfaceExprValue activeValue;
126 if (CInterfaceExpr::eval(active, activeValue, NULL))
128 if (!activeValue.toBool())
130 nlwarning("<CActionHandlerActive::execute> The 'active' param must be convertible to a boolean");
131 return;
133 CInterfaceManager *mngr = CInterfaceManager::getInstance();
134 CInterfaceElement *wnd = CWidgetManager::getInstance()->getElementFromId(target);
135 if(!wnd)
137 nlwarning("<CActionHandlerActive::execute> Can't get window %s", target.c_str());
138 return;
140 wnd->setActive(activeValue.getBool());
142 else
144 nlwarning("<CActionHandlerActive::execute> can't parse the 'active' param");
145 return;
149 // ***************************************************************************
150 REGISTER_ACTION_HANDLER (CActionHandlerSetOpen, "set_open");
151 // ***************************************************************************
152 void CActionHandlerSetOpen::execute (CCtrlBase * /* pCaller */, const std::string &params)
154 std::string open = getParam(params, "open");
155 std::string target = getParam(params, "target");
156 CInterfaceExprValue activeValue;
157 if (CInterfaceExpr::eval(open, activeValue, NULL))
159 if (!activeValue.toBool())
161 nlwarning("<CActionHandlerActive::execute> The 'active' param must be co,vertible to a boolean");
162 return;
164 CInterfaceManager *mngr = CInterfaceManager::getInstance();
165 CGroupContainer *wnd = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId(target));
166 if(!wnd)
168 nlwarning("<CActionHandlerActive::execute> Can't get window %s", target.c_str());
169 return;
171 wnd->setOpen(activeValue.getBool());
173 else
175 nlwarning("<CActionHandlerActive::execute> can't parse the 'active' param");
176 return;
180 // ***************************************************************************
181 // ***************************************************************************
182 // CActionHandlerHideClose
183 // ***************************************************************************
184 // ***************************************************************************
186 // ***************************************************************************
187 REGISTER_ACTION_HANDLER (CActionHandlerHideClose, "hide_close");
189 // ***************************************************************************
190 void CActionHandlerHideClose::execute (CCtrlBase * /* pCaller */, const std::string &params)
192 CInterfaceManager *mngr= CInterfaceManager::getInstance();
193 string hideValue= getParam(params, "hide");
194 string closeValue= getParam(params, "close");
196 // get the list
197 vector<string> hideList;
198 splitString(hideValue, ",", hideList);
199 vector<string> closeList;
200 splitString(closeValue, ",", closeList);
202 // hide all window from the hide list.
203 uint i;
204 for(i=0;i<hideList.size();i++)
206 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(hideList[i]);
207 if(wnd)
208 wnd->setActive(false);
211 // close all containers from the hide list.
212 for(i=0;i<closeList.size();i++)
214 // get a container if possible
215 CInterfaceElement *wnd= CWidgetManager::getInstance()->getElementFromId(closeList[i]);
216 CGroupContainer *pIC = dynamic_cast<CGroupContainer*>(wnd);
217 if(pIC)
218 pIC->close();
224 // ***************************************************************************
225 // ***************************************************************************
226 // Misc
227 // ***************************************************************************
228 // ***************************************************************************
231 // ***************************************************************************
232 REGISTER_ACTION_HANDLER (CActionHandlerEnterModal, "enter_modal");
233 REGISTER_ACTION_HANDLER (CActionHandlerPushModal, "push_modal");
234 REGISTER_ACTION_HANDLER (CActionHandlerLeaveModal, "leave_modal");
236 // ***************************************************************************
237 void CActionHandlerEnterModal::execute(CCtrlBase *pCaller, const std::string &params)
239 CInterfaceManager *pIM= CInterfaceManager::getInstance();
241 // get the group from param
242 string groupName= getParam(params, "group");
243 CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(groupName) );
244 if(group)
246 UserControls.stopFreeLook();
248 // enable the modal
249 CWidgetManager::getInstance()->enableModalWindow(pCaller, group);
251 else
253 nlwarning("<CActionHandlerEnterModal::execute> Couldn't find group %s", groupName.c_str());
257 // ***************************************************************************
258 void CActionHandlerPushModal::execute(CCtrlBase *pCaller, const std::string &params)
260 CInterfaceManager *mngr= CInterfaceManager::getInstance();
262 // get the group from param
263 string groupName= getParam(params, "group");
264 CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(groupName) );
265 if(group)
267 // enable the modal
268 CWidgetManager::getInstance()->pushModalWindow(pCaller, group);
270 else
272 nlwarning("<CActionHandlerPushModal::execute> Couldn't find group %s", groupName.c_str());
277 // ***************************************************************************
278 void CActionHandlerLeaveModal::execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
280 CInterfaceManager *mngr= CInterfaceManager::getInstance();
282 // quit the modal
283 CWidgetManager::getInstance()->popModalWindow();
287 // ***************************************************************************
288 // proc
289 // ***************************************************************************
290 class CActionHandlerProc : public IActionHandler
292 public:
293 virtual void execute (CCtrlBase *pCaller, const std::string &params)
295 // split the parameters
296 vector<string> paramList;
297 splitString(params, "|", paramList);
298 if(paramList.empty())
299 return;
301 // execute the procedure
302 CWidgetManager::getInstance()->runProcedure(paramList[0], pCaller, paramList);
305 REGISTER_ACTION_HANDLER (CActionHandlerProc, "proc");
308 /** Confirm that a group container can be deactivated
310 class CActionHandlerConfirmCanDeactivate : public IActionHandler
312 public:
313 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* params */)
315 CGroupContainer::validateCanDeactivate(true);
318 REGISTER_ACTION_HANDLER (CActionHandlerConfirmCanDeactivate, "confirm_can_deactivate");
320 /** Cancel a group container deactivation
322 class CActionHandlerCancelCanDeactivate : public IActionHandler
324 public:
325 virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* params */)
327 CGroupContainer::validateCanDeactivate(false);
330 REGISTER_ACTION_HANDLER (CActionHandlerCancelCanDeactivate, "cancel_can_deactivate");
336 // ***************************************************************************
337 // ***************************************************************************
338 // EditBox
339 // ***************************************************************************
340 // ***************************************************************************
343 // ***************************************************************************
344 class CActionHandlerEditBoxNumber : public IActionHandler
346 public:
347 virtual void execute (CCtrlBase *pCaller, const std::string &params)
349 CGroupEditBox *pEditBox= dynamic_cast<CGroupEditBox*>(pCaller);
350 if(!pEditBox)
351 return;
355 // get the dblink dest
356 string dblink= getParam(params, "value");
357 if(dblink.empty())
358 return;
360 // get the value
361 sint64 val= pEditBox->getInputStringAsInt64();
363 string valueStr;
364 // see if a max value has been set
365 valueStr = getParam(params, "max_value");
366 if (!valueStr.empty())
368 CInterfaceExprValue maxValue;
369 if (!CInterfaceExpr::eval(valueStr, maxValue) || !maxValue.toInteger())
371 nlwarning("<CActionHandlerEditBoxNumber::execute> Can't eval maxValue, or can't convert to integer : %s", valueStr.c_str());
372 return;
374 val = std::min(maxValue.getInteger(), val);
376 // see if a min value has been set
377 valueStr = getParam(params, "min_value");
378 if (!valueStr.empty())
380 CInterfaceExprValue minValue;
381 if (!CInterfaceExpr::eval(valueStr, minValue) || !minValue.toInteger())
383 nlwarning("<CActionHandlerEditBoxNumber::execute> Can't eval minValue, or can't convert to integer : %s", valueStr.c_str());
384 return;
386 val = std::max(minValue.getInteger(), val);
388 // set in the database
389 CInterfaceProperty prop;
390 prop.link(dblink.c_str());
391 prop.setSInt64(val);
392 string updateText = getParam(params, "update_text");
393 bool mustUpdate = updateText.empty() ? true : CInterfaceElement::convertBool(updateText.c_str());
395 if (mustUpdate)
397 // replace the editbox string
398 pEditBox->setInputStringAsInt64(val);
399 pEditBox->setSelectionAll();
403 REGISTER_ACTION_HANDLER (CActionHandlerEditBoxNumber, "editbox_number");
405 // ***************************************************************************
406 // Dynamic creation of interface links
407 // ***************************************************************************
408 /** Add a link to an interface element
410 class CActionHandlerAddLink : public IActionHandler
412 virtual void execute (CCtrlBase *pCaller, const std::string &params)
414 std::string expr = getParam(params, "expr");
415 std::string targets = getParam(params, "target");
416 std::string id = getParam(params, "id");
417 std::string ah = getParam(params, "action");
418 std::string ahparam = getParam(params, "params");
419 std::string ahcond = getParam(params, "cond");
420 if (id.empty())
422 nlwarning("<CActionHandlerAddLink> Must specify a link's id");
423 return;
425 CInterfaceGroup *parentGroup = dynamic_cast<CInterfaceGroup *>(pCaller);
426 if (!parentGroup)
428 if (pCaller) parentGroup = pCaller->getParent();
431 std::vector<CInterfaceLink::CTargetInfo> targetsVect;
432 std::vector<CInterfaceLink::CCDBTargetInfo> cdbTargetsVect;
433 bool result = CInterfaceLink::splitLinkTargetsExt(targets, parentGroup, targetsVect, cdbTargetsVect);
434 if (!result)
436 nlwarning("<CActionHandlerAddLink> Couldn't parse all links");
438 // add the link
439 CInterfaceLink *il = new CInterfaceLink;
440 il->init(targetsVect, cdbTargetsVect, expr, ah, ahparam, ahcond, parentGroup);
441 CInterfaceManager *im = CInterfaceManager::getInstance();
442 CWidgetManager::getInstance()->getParser()->addLink(il, id);
443 il->update();
446 REGISTER_ACTION_HANDLER (CActionHandlerAddLink, "add_link");
448 /** Remove a link from an interface element
450 class CActionHandlerRemoveLink : public IActionHandler
452 virtual void execute (CCtrlBase * /* pCaller */, const std::string &params)
454 std::string id = getParam(params, "id");
455 if (id.empty())
457 nlwarning("<CActionHandlerRemoveLink> Must specify a link's id");
458 return;
460 CInterfaceManager *im = CInterfaceManager::getInstance();
461 CWidgetManager::getInstance()->getParser()->removeLink(id);
464 REGISTER_ACTION_HANDLER (CActionHandlerRemoveLink, "remove_link");
466 // ***************************************************************************
467 REGISTER_ACTION_HANDLER (CActionHandlerEvalExpr, "eval_expr");
468 // ***************************************************************************
469 void CActionHandlerEvalExpr::execute(CCtrlBase * /* pCaller */, const std::string &params)
471 std::string expr = getParam(params, "expr");
472 if (expr.empty())
474 nlwarning("<CActionHandlerEvalExpr::execute> 'expr' parameter not found or empty.");
475 return;
477 CInterfaceExprValue dummyResult; // result not used
478 if (!CInterfaceExpr::eval(expr, dummyResult))
480 nlwarning("<CActionHandlerEvalExpr::execute> Couldn't eval expression");
482 return;
485 // ***************************************************************************
486 CInterfaceGroup *createMenuColorWidget(const string &colDbEntry,
487 const string &toolTipTextID,
488 const string &ccdTitle)
490 CInterfaceManager *im = CInterfaceManager::getInstance();
491 pair<string, string> params[3] =
493 make_pair(string("col_db_entry"), colDbEntry),
494 make_pair(string("tooltip"), toolTipTextID),
495 make_pair(string("ccd_title"), ccdTitle),
497 return CWidgetManager::getInstance()->getParser()->createGroupInstance("menu_color_widget", "", params, 3);
500 // ***************************************************************************
501 struct CCameraBackup
503 CViewport Viewport;
504 CFrustum Frustum;
508 // *********************************************************
509 CCameraBackup setupCameraForScreenshot(UScene &scene, uint left, uint right, uint top, uint bottom, uint screenShotWidth, uint screenShotHeight)
511 CCameraBackup cb;
512 cb.Frustum = scene.getCam().getFrustum();
513 cb.Viewport = scene.getViewport();
514 // Build a frustum
515 CFrustum frustumPart;
516 frustumPart.Left = cb.Frustum.Left+(cb.Frustum.Right-cb.Frustum.Left)*((float)left/(float)screenShotWidth);
517 frustumPart.Right = cb.Frustum.Left+(cb.Frustum.Right-cb.Frustum.Left)*((float)right/(float)screenShotWidth);
518 frustumPart.Top = cb.Frustum.Top+(cb.Frustum.Bottom-cb.Frustum.Top)*((float)top/(float)screenShotHeight);
519 frustumPart.Bottom = cb.Frustum.Top+(cb.Frustum.Bottom-cb.Frustum.Top)*((float)bottom/(float)screenShotHeight);
520 frustumPart.Near = cb.Frustum.Near;
521 frustumPart.Far = cb.Frustum.Far;
522 frustumPart.Perspective = cb.Frustum.Perspective;
524 // Build a viewport
525 CViewport viewport;
526 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
527 viewport.init (0, 0, (float)(right-left)/Driver->getWindowWidth(), (float)(bottom-top)/Driver->getWindowHeight());
529 // Activate all this
530 scene.getCam().setFrustum (frustumPart);
531 scene.setViewport (viewport);
533 return cb;
537 // *********************************************************
538 static void restoreCamera(UScene &scene, const CCameraBackup &backup)
540 scene.getCam().setFrustum (backup.Frustum);
541 scene.setViewport(backup.Viewport);
544 // ***************************************************************************
545 void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint screenShotWidth, uint screenShotHeight)
547 CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight);
548 CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight);
549 commitCamera();
550 // sky setup are copied from main scene before rendering so no setup done here
551 renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom);
552 restoreCamera(*Scene, cbScene);
553 restoreCamera(*SceneRoot, cbCanopy);
554 commitCamera();
557 // ***************************************************************************
559 void getBuffer (CBitmap &btm)
561 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
563 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
565 // Destination image
566 CBitmap temp;
567 btm.resize (ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight, CBitmap::RGBA);
569 uint top;
570 uint bottom = std::min (Driver->getWindowHeight (), ClientCfg.ScreenShotHeight);
571 for (top=0; top<ClientCfg.ScreenShotHeight; top+=Driver->getWindowHeight ())
573 uint left;
574 uint right = std::min (Driver->getWindowWidth (), ClientCfg.ScreenShotWidth);
575 for (left=0; left<ClientCfg.ScreenShotWidth; left+=Driver->getWindowWidth ())
577 Driver->clearBuffers (CRGBA::Black);
578 renderSceneScreenShot (left, right, top, bottom, ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
579 // Get the bitmap
580 Driver->getBuffer (temp);
581 Driver->swapBuffers ();
582 btm.blit (temp, 0, Driver->getWindowHeight ()-(bottom-top), right-left, bottom-top, left, top);
584 // Next
585 right = std::min (right+Driver->getWindowWidth (), ClientCfg.ScreenShotWidth);
588 // Next
589 bottom = std::min (bottom+Driver->getWindowHeight (), ClientCfg.ScreenShotHeight);
592 else
594 Driver->getBuffer(btm);
598 void displayScreenShotSavedInfo(const string &filename)
600 CInterfaceManager *pIM = CInterfaceManager::getInstance();
601 string msg = "'" + filename + "' " + CI18N::get("uiScreenshotSaved");
602 pIM->displaySystemInfo(msg);
605 void initScreenshot()
607 if (!CFile::isExists(ScreenshotsDirectory)) CFile::createDirectory(ScreenshotsDirectory);
610 bool screenshotZBuffer(const std::string &filename)
612 std::string::size_type pos = filename.find(".");
614 if (pos == std::string::npos)
615 return false;
617 std::string filename_z = filename.substr(0, pos) + "_z" + filename.substr(pos);
618 std::string ext = filename.substr(pos+1);
620 std::vector<float> z;
621 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
623 Driver->getZBuffer(z);
625 float min = std::numeric_limits<float>::max();
626 float max = std::numeric_limits<float>::min();
628 // get min and max values
629 for(uint i = 0; i < z.size(); ++i)
631 float value = z[i];
632 if (value > max)
634 max = value;
636 else if (value < min)
638 min = value;
642 max = max - min;
644 CBitmap zi;
645 zi.resize(Driver->getWindowWidth(), Driver->getWindowHeight());
646 CRGBA *dest = (CRGBA *) &zi.getPixels()[0];
648 for(uint k = 0; k < z.size(); ++k)
650 // normalize values
651 uint8 i = (uint8) ((z[k] - min) * 255.f / max);
652 dest->set(i, i, i, i);
653 ++ dest;
658 COFile f;
659 f.open(filename_z);
660 if (ext == "png")
661 zi.writePNG(f, 32);
662 else
663 zi.writeTGA(f, 32);
665 catch(...)
667 return false;
670 return true;
673 static std::string findNewScreenShotFileName(std::string filename)
675 static char cstime[25];
676 time_t dtime;
677 time(&dtime);
678 struct tm *tms = localtime(&dtime);
679 if (tms)
681 strftime(cstime, 25, "%Y-%m-%d", tms);
683 std::string::size_type pos = filename.find_last_of('.');
685 // fallback if no extension is given
686 if (pos == std::string::npos)
687 filename = filename + "_" + cstime + "_";
688 else
689 filename = filename.substr(0, pos) + "_" + cstime + "_" + filename.substr(pos);
692 // screenshot_YYYY-MM-DD_000.jpg
693 return CFile::findNewFile(filename);
696 void screenShotTGA()
698 CBitmap btm;
699 getBuffer (btm);
701 string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.tga");
702 COFile fs(filename);
704 if (!btm.writeTGA(fs, 24, false))
706 fs.close();
707 CFile::deleteFile(filename);
708 return;
711 if (ClientCfg.ScreenShotZBuffer)
712 screenshotZBuffer(filename);
714 nlinfo("Screenshot '%s' saved in tga format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
715 displayScreenShotSavedInfo(filename);
718 void screenShotPNG()
720 CBitmap btm;
721 getBuffer (btm);
723 string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.png");
724 COFile fs(filename);
726 if (!btm.writePNG(fs, 24))
728 fs.close();
729 CFile::deleteFile(filename);
730 return;
733 if (ClientCfg.ScreenShotZBuffer)
734 screenshotZBuffer(filename);
736 nlinfo("Screenshot '%s' saved in png format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
737 displayScreenShotSavedInfo(filename);
740 void screenShotJPG()
742 CBitmap btm;
743 getBuffer (btm);
745 string filename = findNewScreenShotFileName(ScreenshotsDirectory+"screenshot.jpg");
746 COFile fs(filename);
748 if (!btm.writeJPG(fs))
750 fs.close();
751 CFile::deleteFile(filename);
752 return;
755 if (ClientCfg.ScreenShotZBuffer)
756 screenshotZBuffer(filename);
758 nlinfo("Screenshot '%s' saved in jpg format (%ux%u)", filename.c_str(), ClientCfg.ScreenShotWidth, ClientCfg.ScreenShotHeight);
759 displayScreenShotSavedInfo(filename);
762 // ***************************************************************************
764 class CAHScreenShot : public IActionHandler
766 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
768 // if custom screenshot size is asked, then do it right now
769 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
771 // Custom screen shot ?
772 screenShotTGA();
774 else
776 // post screenshot request
777 ScreenshotRequest = ScreenshotRequestTGA;
782 // ***************************************************************************
783 REGISTER_ACTION_HANDLER (CAHScreenShot, "screen_shot");
785 // ***************************************************************************
786 class CAHScreenShotJPG : public IActionHandler
788 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
790 // if custom screenshot size is asked, then do it right now
791 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
793 screenShotJPG();
795 else
797 // post screenshot request
798 ScreenshotRequest = ScreenshotRequestJPG;
802 // ***************************************************************************
803 REGISTER_ACTION_HANDLER (CAHScreenShotJPG, "screen_shot_jpg");
805 // ***************************************************************************
806 class CAHScreenShotPNG : public IActionHandler
808 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
810 // if custom screenshot size is asked, then do it right now
811 if (ClientCfg.ScreenShotWidth && ClientCfg.ScreenShotHeight)
813 screenShotPNG();
815 else
817 // post screenshot request
818 ScreenshotRequest = ScreenshotRequestPNG;
822 // ***************************************************************************
823 REGISTER_ACTION_HANDLER (CAHScreenShotPNG, "screen_shot_png");
826 // ***************************************************************************
827 // Reply to the last people who talked in the chat -> this change the target of the main chat to the name of the last teller
828 class CAHReplyTeller : public IActionHandler
830 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
832 if (!PeopleInterraction.LastSenderName.empty())
834 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
835 if (w)
837 w->setKeyboardFocus();
838 w->enableBlink(1);
839 PeopleInterraction.ChatGroup.Filter.setTargetPlayer(CEntityCL::removeTitleAndShardFromName(PeopleInterraction.LastSenderName));
840 CGroupEditBox *eb = w->getEditBox();
841 if (eb != NULL)
843 eb->bypassNextKey();
850 REGISTER_ACTION_HANDLER (CAHReplyTeller, "reply_teller")
852 // ***************************************************************************
853 // Reply to the last people who talked in the chat only once (display '/tell name' in the last activated chat window)
854 class CAHReplyTellerOnce : public IActionHandler
856 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
858 // display a /tell command in the main chat
859 if (!PeopleInterraction.LastSenderName.empty())
861 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
862 if (w)
864 w->setKeyboardFocus();
865 w->enableBlink(1);
866 w->setCommand("tell " + CEntityCL::removeTitleAndShardFromName(PeopleInterraction.LastSenderName) + " ", false);
867 CGroupEditBox *eb = w->getEditBox();
868 if (eb != NULL)
870 eb->bypassNextKey();
876 REGISTER_ACTION_HANDLER (CAHReplyTellerOnce, "reply_teller_once")
878 // ***************************************************************************
879 /** Cycle through the last people on which a 'tell' has been done.
880 * Focus must be in a window with a target (main chat or user chat), otherwise the main chat is used
882 class CAHCycleTell : public IActionHandler
884 void execute(CCtrlBase * /* pCaller */, const std::string &/* params */)
886 CInterfaceManager *im = CInterfaceManager::getInstance();
887 if (!im->isInGame()) return;
888 const string *lastTellPeople = ChatMngr.cycleLastTell();
889 if (!lastTellPeople) return;
890 // just popup the main chat
891 //CChatWindow *w = PeopleInterraction.MainChat.Window;
892 CChatWindow *w = PeopleInterraction.ChatGroup.Window;
893 if (w)
895 w->setKeyboardFocus();
896 w->enableBlink(1);
897 //PeopleInterraction.MainChat.Filter.setTargetPlayer(*lastTellPeople);
898 PeopleInterraction.ChatGroup.Filter.setTargetPlayer(*lastTellPeople);
902 REGISTER_ACTION_HANDLER (CAHCycleTell, "cycle_tell")
907 // temp for test : set last sender name
908 NLMISC_COMMAND(slsn, "Temp : set the name of the last sender.", "<name>")
910 if (args.size() != 1) return false;
911 PeopleInterraction.LastSenderName = args[0];
912 return true;
915 // ***************************************************************************
916 bool CStringPostProcessRemoveName::cbIDStringReceived(string &inOut)
918 // extract the replacement id
919 string strNewTitle = CEntityCL::getTitleFromName(inOut);
921 // retrieve the translated string
922 if (!strNewTitle.empty())
924 inOut = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(strNewTitle, Woman);
926 // Sometimes translation contains another title
927 string::size_type pos = inOut.find('$');
928 if (pos != string::npos)
930 inOut = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(inOut), Woman);
934 else
935 inOut.clear();
937 return true;
940 // ***************************************************************************
941 bool CStringPostProcessRemoveTitle::cbIDStringReceived(string &inOut)
943 inOut = CEntityCL::removeTitleAndShardFromName(inOut);
944 return true;
947 // ***************************************************************************
948 bool CStringPostProcessNPCRemoveTitle::cbIDStringReceived(string &inOut)
950 string sOut = CEntityCL::removeTitleAndShardFromName(inOut);
951 if (sOut.empty())
953 CStringPostProcessRemoveName SPPRM;
954 SPPRM.cbIDStringReceived(inOut);
956 else
958 inOut = sOut;
960 return true;
965 // ***************************************************************************
966 class CAHAnimStart : public IActionHandler
968 public:
969 virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params)
971 string sAnim = getParam(Params, "anim");
972 CWidgetManager::getInstance()->startAnim(sAnim);
975 REGISTER_ACTION_HANDLER (CAHAnimStart, "anim_start");
977 // ***************************************************************************
978 class CAHAnimStop : public IActionHandler
980 public:
981 virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params)
983 string sAnim = getParam(Params, "anim");
984 CWidgetManager::getInstance()->stopAnim(sAnim);
987 REGISTER_ACTION_HANDLER (CAHAnimStop, "anim_stop");